diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml
index a98b0b7..b3f4c72 100644
--- a/.idea/dictionaries/project.xml
+++ b/.idea/dictionaries/project.xml
@@ -5,6 +5,8 @@
instanceactions
keypairs
loadbalancer
+ microversion
+ microversions
recordsets
securitygroups
snat
diff --git a/internal/openstack/context_serviceclients.go b/internal/openstack/context_serviceclients.go
index 285592d..77bcd0c 100644
--- a/internal/openstack/context_serviceclients.go
+++ b/internal/openstack/context_serviceclients.go
@@ -3,10 +3,12 @@ package openstack
import (
"context"
"fmt"
+ "strings"
"github.com/gophercloud/gophercloud/v2"
"github.com/gophercloud/gophercloud/v2/openstack"
"github.com/gophercloud/gophercloud/v2/openstack/sharedfilesystems/apiversions"
+ "golang.org/x/mod/semver"
)
type clientServiceBuilder func(*gophercloud.ProviderClient, gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error)
@@ -29,6 +31,48 @@ func (c *Context) getClientService(key string, opts gophercloud.EndpointOpts, bu
return actual.(*gophercloud.ServiceClient), nil
}
+func getAPIVersions(ctx context.Context, client *gophercloud.ServiceClient) ([]apiversions.APIVersion, error) {
+ pages, err := apiversions.List(client).AllPages(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("listing API versions for %s failed: %w", client.Endpoint, err)
+ }
+
+ versions, err := apiversions.ExtractAPIVersions(pages)
+ if err != nil {
+ return nil, fmt.Errorf("listing API versions for %s failed: %w", client.Endpoint, err)
+ }
+
+ return versions, nil
+}
+
+func checkMicroversion(ctx context.Context, client *gophercloud.ServiceClient, minimum, required string) error {
+ versions, err := getAPIVersions(ctx, client)
+ if err != nil {
+ return err
+ }
+
+ for _, v := range versions {
+ if semver.Compare(minimum, v.ID) != 0 {
+ continue
+ }
+
+ version := strings.TrimSpace(v.Version)
+ if version != "" && !strings.HasPrefix(version, "v") {
+ version = "v" + version
+ }
+
+ if !semver.IsValid(version) {
+ version = v.ID
+ }
+
+ if semver.Compare(required, version) <= 0 {
+ return nil
+ }
+ }
+
+ return fmt.Errorf("requested microversion %s is unsupported", required)
+}
+
func (c *Context) IdentityV3() (*gophercloud.ServiceClient, error) {
return c.getClientService("identity", gophercloud.EndpointOpts{}, openstack.NewIdentityV3)
}
@@ -79,26 +123,15 @@ func newSharedFileSystemV2(provider *gophercloud.ProviderClient, opts gopherclou
return nil, err
}
- pages, err := apiversions.List(client).AllPages(context.Background())
- if err != nil {
- return nil, fmt.Errorf("listing shared file system API versions: %w", err)
- }
+ minimum := "v2.0"
+ required := "v2.60"
- versions, err := apiversions.ExtractAPIVersions(pages)
+ err = checkMicroversion(context.Background(), client, minimum, required)
if err != nil {
- return nil, fmt.Errorf("extracting shared file system API versions: %w", err)
- }
-
- for _, version := range versions {
- if version.ID != "v2.0" {
- continue
- }
-
- client.Microversion = min(version.Version, "2.60")
- return client, nil
+ return nil, err
}
- return nil, fmt.Errorf("shared file system API v2 not found")
+ return client, nil
}
func (c *Context) ContainerInfraV1() (*gophercloud.ServiceClient, error) {
@@ -115,7 +148,13 @@ func newContainerInfraV1(provider *gophercloud.ProviderClient, opts gophercloud.
return nil, err
}
- client.Microversion = "1.14"
+ minimum := "v1"
+ required := "v1"
+
+ err = checkMicroversion(context.Background(), client, minimum, required)
+ if err != nil {
+ return nil, err
+ }
return client, nil
}
diff --git a/internal/resources/containers/coe/clusters/clusters.go b/internal/resources/containers/coe/clusters/clusters.go
index fe599c6..f5de7ba 100644
--- a/internal/resources/containers/coe/clusters/clusters.go
+++ b/internal/resources/containers/coe/clusters/clusters.go
@@ -86,7 +86,7 @@ func (r *Resource) Commands() []resource.Command {
{Key: "s", Description: "Show", Default: true},
{Key: "shift-t", Description: "Cluster Template"},
{Key: "shift-n", Description: "Node Groups"},
- {Key: "k", Description: "Show Kubeconfig"},
+ {Key: "k", Description: "Kubeconfig"},
{Key: "ctrl+k", Description: "Get Kubeconfig", StatusLabel: "Downloading"},
}
}