diff --git a/commands/cloudapi-v6/completer/ids.go b/commands/cloudapi-v6/completer/ids.go index 5e97781d6..5dd7c8664 100644 --- a/commands/cloudapi-v6/completer/ids.go +++ b/commands/cloudapi-v6/completer/ids.go @@ -83,7 +83,7 @@ func DatacenterIdsFilterLocation(loc string) []string { return dcIds } -func DataCentersIds() []string { +func DataCentersIds(filters ...func(datacenter ionoscloud.Datacenter) bool) []string { datacenterSvc := resources.NewDataCenterService(client.Must(), context.Background()) datacenters, _, err := datacenterSvc.List(resources.ListQueryParams{}) if err != nil { diff --git a/commands/vpn/ipsec/completer/completer.go b/commands/vpn/ipsec/completer/completer.go index 1c636bd74..d5bdfccec 100644 --- a/commands/vpn/ipsec/completer/completer.go +++ b/commands/vpn/ipsec/completer/completer.go @@ -4,11 +4,8 @@ import ( "context" "github.com/ionos-cloud/ionosctl/v6/internal/client" - "github.com/ionos-cloud/ionosctl/v6/internal/config" - "github.com/ionos-cloud/ionosctl/v6/internal/constants" "github.com/ionos-cloud/ionosctl/v6/pkg/functional" vpn "github.com/ionos-cloud/sdk-go-vpn" - "github.com/spf13/viper" ) // -- GATEWAYS @@ -24,10 +21,6 @@ func GatewaysProperty[V any](f func(gateway vpn.IPSecGatewayRead) V, fs ...Gatew // Gateways returns all distributions matching the given filters func Gateways(fs ...GatewayFilter) (vpn.IPSecGatewayReadList, error) { - if url := config.GetServerUrl(); url == constants.DefaultApiURL || url == "" { - viper.Set(constants.ArgServerUrl, constants.DefaultVPNApiURL) - } - req := client.Must().VPNClient.IPSecGatewaysApi.IpsecgatewaysGet(context.Background()) for _, f := range fs { var err error @@ -57,10 +50,6 @@ func TunnelsProperty[V any](gatewayID string, f func(tunnel vpn.IPSecTunnelRead) // Tunnels returns all distributions matching the given filters func Tunnels(gatewayID string, fs ...TunnelFilter) (vpn.IPSecTunnelReadList, error) { - if url := config.GetServerUrl(); url == constants.DefaultApiURL || url == "" { - viper.Set(constants.ArgServerUrl, constants.DefaultVPNApiURL) - } - req := client.Must().VPNClient.IPSecTunnelsApi.IpsecgatewaysTunnelsGet(context.Background(), gatewayID) for _, f := range fs { var err error diff --git a/commands/vpn/wireguard/completer/completer.go b/commands/vpn/wireguard/completer/completer.go index 29e732d0b..09c279dd1 100644 --- a/commands/vpn/wireguard/completer/completer.go +++ b/commands/vpn/wireguard/completer/completer.go @@ -4,11 +4,8 @@ import ( "context" "github.com/ionos-cloud/ionosctl/v6/internal/client" - "github.com/ionos-cloud/ionosctl/v6/internal/config" - "github.com/ionos-cloud/ionosctl/v6/internal/constants" "github.com/ionos-cloud/ionosctl/v6/pkg/functional" vpn "github.com/ionos-cloud/sdk-go-vpn" - "github.com/spf13/viper" ) // -- GATEWAYS @@ -24,10 +21,6 @@ func GatewaysProperty[V any](f func(gateway vpn.WireguardGatewayRead) V, fs ...G // Gateways returns all distributions matching the given filters func Gateways(fs ...GatewayFilter) (vpn.WireguardGatewayReadList, error) { - if url := config.GetServerUrl(); url == constants.DefaultApiURL || url == "" { - viper.Set(constants.ArgServerUrl, constants.DefaultVPNApiURL) - } - req := client.Must().VPNClient.WireguardGatewaysApi.WireguardgatewaysGet(context.Background()) for _, f := range fs { var err error @@ -59,10 +52,6 @@ func PeersProperty[V any](gatewayID string, f func(peer vpn.WireguardPeerRead) V // Peers returns all distributions matching the given filters func Peers(gatewayID string, fs ...PeerFilter) (vpn.WireguardPeerReadList, error) { - if url := config.GetServerUrl(); url == constants.DefaultApiURL || url == "" { - viper.Set(constants.ArgServerUrl, constants.DefaultVPNApiURL) - } - req := client.Must().VPNClient.WireguardPeersApi.WireguardgatewaysPeersGet(context.Background(), gatewayID) for _, f := range fs { var err error diff --git a/go.mod b/go.mod index 85b43aa48..a30d63365 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4 github.com/ionos-cloud/sdk-go-cdn v1.1.0 github.com/ionos-cloud/sdk-go-dbaas-mariadb v1.1.1 + github.com/ionos-cloud/sdk-go-kafka v1.1.0 github.com/ionos-cloud/sdk-go-vpn v1.0.1 ) diff --git a/internal/config/config.go b/internal/config/config.go index 9b0385809..7a25863ba 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -22,18 +22,25 @@ var FieldsWithSensitiveDataInConfigFile = []string{ // GetServerUrl returns the server URL the SDK should use, with support for layered fallbacks. func GetServerUrl() string { viper.AutomaticEnv() - if val := viper.GetString(constants.ArgServerUrl); viper.IsSet(constants.ArgServerUrl) { + if val := viper.GetString(constants.ArgServerUrl); viper.IsSet(constants.ArgServerUrl) && val != "" { // 1. Above all, use global flag val return val } - if val := viper.GetString(constants.EnvServerUrl); viper.IsSet(constants.EnvServerUrl) { + if val := viper.GetString(constants.EnvServerUrl); viper.IsSet(constants.EnvServerUrl) && val != "" { // 2. Fallback to non-empty env vars return val } - if val := viper.GetString(constants.CfgServerUrl); viper.IsSet(constants.CfgServerUrl) { - // 3. Fallback to non-empty cfg field + + cfgFields, err := Read() + if err != nil { + return "" + } + val := cfgFields[constants.CfgServerUrl] + + if val != "" { // 3. Fallback to non-empty cfg field return val } + // 4. Return empty string. SDKs should handle it, per docs return "" } diff --git a/internal/core/command.go b/internal/core/command.go index 224929c0e..7222a944d 100644 --- a/internal/core/command.go +++ b/internal/core/command.go @@ -95,7 +95,6 @@ func WithRegionalFlags(c *Command, baseURL string, allowedLocations []string) *C c.Command.PersistentFlags().StringP( constants.ArgServerUrl, constants.ArgServerUrlShort, defaultUrl, "Override default host URL", ) - viper.BindPFlag(constants.ArgServerUrl, c.Command.PersistentFlags().Lookup(constants.ArgServerUrl)) // Add the location flag c.Command.PersistentFlags().StringP( @@ -132,6 +131,17 @@ func WithRegionalFlags(c *Command, baseURL string, allowedLocations []string) *C } } + // Because Viper has issues with binding to the same flag multiple times, we need to manually set the value + if c.Command.PersistentFlags().Changed(constants.ArgServerUrl) { + customURL, _ := c.Command.PersistentFlags().GetString(constants.ArgServerUrl) + viper.Set(constants.ArgServerUrl, customURL) + } + + // Because Viper has issues with binding to the same env var multiple times, we need to manually set the value + if envURL := os.Getenv(constants.EnvServerUrl); envURL != "" { + viper.Set(constants.EnvServerUrl, envURL) + } + return nil } diff --git a/internal/core/flag-option.go b/internal/core/flag-option.go index 680a6b2cd..df5ff2c55 100644 --- a/internal/core/flag-option.go +++ b/internal/core/flag-option.go @@ -55,7 +55,9 @@ func WithCompletionComplex( func(passedCmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { viper.AutomaticEnv() - if viper.IsSet(constants.ArgServerUrl) || viper.IsSet(constants.EnvServerUrl) { + if viper.IsSet(constants.ArgServerUrl) || + viper.IsSet(constants.EnvServerUrl) || + viper.IsSet(constants.CfgServerUrl) { // If manually set, do nothing and directly call completionFunc return completionFunc(passedCmd, args, toComplete) }