mygithub.libinneed.workers.dev/stackitcloud/stackit-cli
Advanced tools
@@ -20,3 +20,3 @@ name: CI | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| uses: actions/checkout@v5 | ||
@@ -51,3 +51,3 @@ - name: Install go | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| uses: actions/checkout@v5 | ||
@@ -54,0 +54,0 @@ - name: Check GoReleaser |
@@ -29,3 +29,3 @@ # STACKIT CLI release workflow. | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| uses: actions/checkout@v5 | ||
| with: | ||
@@ -32,0 +32,0 @@ # Allow goreleaser to access older tag information. |
@@ -14,7 +14,7 @@ name: Renovate | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| uses: actions/checkout@v5 | ||
| - name: Self-hosted Renovate | ||
| uses: renovatebot/github-action@v43.0.5 | ||
| uses: renovatebot/github-action@v43.0.7 | ||
| with: | ||
| configurationFile: .github/renovate.json | ||
| token: ${{ secrets.RENOVATE_TOKEN }} |
+10
-10
@@ -23,4 +23,4 @@ module github.com/stackitcloud/stackit-cli | ||
| github.com/stackitcloud/stackit-sdk-go/services/git v0.7.1 | ||
| github.com/stackitcloud/stackit-sdk-go/services/iaas v0.27.1 | ||
| github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.5.1 | ||
| github.com/stackitcloud/stackit-sdk-go/services/iaas v0.29.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.5.2 | ||
| github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.24.1 | ||
@@ -33,3 +33,3 @@ github.com/stackitcloud/stackit-sdk-go/services/postgresflex v1.2.1 | ||
| github.com/stackitcloud/stackit-sdk-go/services/serverupdate v1.2.1 | ||
| github.com/stackitcloud/stackit-sdk-go/services/serviceaccount v0.9.1 | ||
| github.com/stackitcloud/stackit-sdk-go/services/serviceaccount v0.11.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/serviceenablement v1.2.2 | ||
@@ -39,6 +39,6 @@ github.com/stackitcloud/stackit-sdk-go/services/ske v1.3.0 | ||
| github.com/zalando/go-keyring v0.2.6 | ||
| golang.org/x/mod v0.26.0 | ||
| golang.org/x/mod v0.27.0 | ||
| golang.org/x/oauth2 v0.30.0 | ||
| golang.org/x/term v0.33.0 | ||
| golang.org/x/text v0.27.0 | ||
| golang.org/x/term v0.34.0 | ||
| golang.org/x/text v0.28.0 | ||
| k8s.io/apimachinery v0.32.3 | ||
@@ -49,3 +49,3 @@ k8s.io/client-go v0.32.3 | ||
| require ( | ||
| golang.org/x/net v0.42.0 // indirect | ||
| golang.org/x/net v0.43.0 // indirect | ||
| golang.org/x/time v0.11.0 // indirect | ||
@@ -214,3 +214,3 @@ gopkg.in/inf.v0 v0.9.1 // indirect | ||
| golang.org/x/sync v0.16.0 // indirect | ||
| golang.org/x/tools v0.35.0 // indirect | ||
| golang.org/x/tools v0.36.0 // indirect | ||
| golang.org/x/tools/go/expect v0.1.1-deprecated // indirect | ||
@@ -250,3 +250,3 @@ golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect | ||
| github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.3.1 | ||
| github.com/stackitcloud/stackit-sdk-go/services/observability v0.9.1 | ||
| github.com/stackitcloud/stackit-sdk-go/services/observability v0.10.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.25.1 | ||
@@ -256,3 +256,3 @@ github.com/stackitcloud/stackit-sdk-go/services/redis v0.25.1 | ||
| go.uber.org/multierr v1.11.0 // indirect | ||
| golang.org/x/sys v0.34.0 // indirect | ||
| golang.org/x/sys v0.35.0 // indirect | ||
| gopkg.in/yaml.v3 v3.0.1 // indirect | ||
@@ -259,0 +259,0 @@ k8s.io/api v0.32.3 // indirect |
@@ -47,4 +47,3 @@ package getaccesstoken | ||
| // Try to get a valid access token, refreshing if necessary | ||
| accessToken, err := auth.RefreshAccessToken(params.Printer) | ||
| accessToken, err := auth.GetValidAccessToken(params.Printer) | ||
| if err != nil { | ||
@@ -51,0 +50,0 @@ return err |
@@ -169,3 +169,4 @@ package list | ||
| table.SetHeader("ID", "NAME", "OS", "ARCHITECTURE", "DISTRIBUTION", "VERSION", "LABELS") | ||
| for _, item := range items { | ||
| for i := range items { | ||
| item := items[i] | ||
| var ( | ||
@@ -172,0 +173,0 @@ architecture string = "n/a" |
@@ -10,2 +10,3 @@ package describe | ||
| "github.com/stackitcloud/stackit-cli/internal/pkg/print" | ||
| "github.com/stackitcloud/stackit-cli/internal/pkg/utils" | ||
@@ -238,2 +239,180 @@ "github.com/google/go-cmp/cmp" | ||
| }, | ||
| { | ||
| name: "cluster with single error", | ||
| args: args{ | ||
| outputFormat: "", | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: &[]ske.ClusterError{ | ||
| { | ||
| Code: utils.Ptr("SKE_INFRA_SNA_NETWORK_NOT_FOUND"), | ||
| Message: utils.Ptr("Network configuration not found"), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "cluster with multiple errors", | ||
| args: args{ | ||
| outputFormat: "", | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: &[]ske.ClusterError{ | ||
| { | ||
| Code: utils.Ptr("SKE_INFRA_SNA_NETWORK_NOT_FOUND"), | ||
| Message: utils.Ptr("Network configuration not found"), | ||
| }, | ||
| { | ||
| Code: utils.Ptr("SKE_NODE_MACHINE_TYPE_NOT_FOUND"), | ||
| Message: utils.Ptr("Specified machine type unavailable"), | ||
| }, | ||
| { | ||
| Code: utils.Ptr("SKE_FETCHING_ERRORS_NOT_POSSIBLE"), | ||
| Message: utils.Ptr("Fetching errors not possible"), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "cluster with error but no message", | ||
| args: args{ | ||
| outputFormat: "", | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: &[]ske.ClusterError{ | ||
| { | ||
| Code: utils.Ptr("SKE_FETCHING_ERRORS_NOT_POSSIBLE"), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "cluster with nil errors", | ||
| args: args{ | ||
| outputFormat: "", | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: nil, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "cluster with empty errors array", | ||
| args: args{ | ||
| outputFormat: "", | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: &[]ske.ClusterError{}, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "cluster without status", | ||
| args: args{ | ||
| outputFormat: "", | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "JSON output format with errors", | ||
| args: args{ | ||
| outputFormat: print.JSONOutputFormat, | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: &[]ske.ClusterError{ | ||
| { | ||
| Code: utils.Ptr("SKE_INFRA_SNA_NETWORK_NOT_FOUND"), | ||
| Message: utils.Ptr("Network configuration not found"), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "YAML output format with errors", | ||
| args: args{ | ||
| outputFormat: print.YAMLOutputFormat, | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: &[]ske.ClusterError{ | ||
| { | ||
| Code: utils.Ptr("SKE_INFRA_SNA_NETWORK_NOT_FOUND"), | ||
| Message: utils.Ptr("Network configuration not found"), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "cluster with kubernetes info and errors", | ||
| args: args{ | ||
| outputFormat: "", | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Kubernetes: &ske.Kubernetes{ | ||
| Version: utils.Ptr("1.28.0"), | ||
| }, | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: &[]ske.ClusterError{ | ||
| { | ||
| Code: utils.Ptr("SKE_INFRA_SNA_NETWORK_NOT_FOUND"), | ||
| Message: utils.Ptr("Network configuration not found"), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| { | ||
| name: "cluster with extensions and errors", | ||
| args: args{ | ||
| outputFormat: "", | ||
| cluster: &ske.Cluster{ | ||
| Name: utils.Ptr("test-cluster"), | ||
| Extensions: &ske.Extension{ | ||
| Acl: &ske.ACL{ | ||
| AllowedCidrs: &[]string{"10.0.0.0/8"}, | ||
| Enabled: utils.Ptr(true), | ||
| }, | ||
| }, | ||
| Status: &ske.ClusterStatus{ | ||
| Errors: &[]ske.ClusterError{ | ||
| { | ||
| Code: utils.Ptr("SKE_INFRA_SNA_NETWORK_NOT_FOUND"), | ||
| Message: utils.Ptr("Network configuration not found"), | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| wantErr: false, | ||
| }, | ||
| } | ||
@@ -240,0 +419,0 @@ p := print.NewPrinter() |
@@ -7,2 +7,3 @@ package describe | ||
| "fmt" | ||
| "strings" | ||
@@ -135,2 +136,5 @@ "github.com/goccy/go-yaml" | ||
| table.AddSeparator() | ||
| if clusterErrs := cluster.Status.GetErrors(); len(clusterErrs) != 0 { | ||
| handleClusterErrors(clusterErrs, &table) | ||
| } | ||
| } | ||
@@ -141,2 +145,3 @@ if cluster.Kubernetes != nil { | ||
| } | ||
| table.AddRow("ACL", acl) | ||
@@ -151,1 +156,15 @@ err := table.Display(p) | ||
| } | ||
| func handleClusterErrors(clusterErrs []ske.ClusterError, table *tables.Table) { | ||
| errs := make([]string, 0, len(clusterErrs)) | ||
| for _, e := range clusterErrs { | ||
| b := new(strings.Builder) | ||
| fmt.Fprint(b, e.GetCode()) | ||
| if msg, ok := e.GetMessageOk(); ok { | ||
| fmt.Fprintf(b, ": %s", msg) | ||
| } | ||
| errs = append(errs, b.String()) | ||
| } | ||
| table.AddRow("ERRORS", strings.Join(errs, "\n")) | ||
| table.AddSeparator() | ||
| } |
@@ -170,3 +170,4 @@ package list | ||
| for _, volume := range volumes { | ||
| for i := range volumes { | ||
| volume := volumes[i] | ||
| table.AddRow( | ||
@@ -173,0 +174,0 @@ utils.PtrString(volume.Id), |
@@ -137,5 +137,6 @@ package auth | ||
| // RefreshAccessToken refreshes the access token if it's expired for the user token flow. | ||
| // It returns the new access token or an error if the refresh fails. | ||
| func RefreshAccessToken(p *print.Printer) (string, error) { | ||
| // GetValidAccessToken returns a valid access token for the current authentication flow. | ||
| // For user token flows, it refreshes the token if necessary. | ||
| // For service account flows, it returns the current access token. | ||
| func GetValidAccessToken(p *print.Printer) (string, error) { | ||
| flow, err := GetAuthFlow() | ||
@@ -145,4 +146,10 @@ if err != nil { | ||
| } | ||
| // For service account flows, just return the current token | ||
| if flow == AUTH_FLOW_SERVICE_ACCOUNT_TOKEN || flow == AUTH_FLOW_SERVICE_ACCOUNT_KEY { | ||
| return GetAccessToken() | ||
| } | ||
| if flow != AUTH_FLOW_USER_TOKEN { | ||
| return "", fmt.Errorf("token refresh is only supported for user token flow, current flow: %s", flow) | ||
| return "", fmt.Errorf("unsupported authentication flow: %s", flow) | ||
| } | ||
@@ -149,0 +156,0 @@ |
Sorry, the diff of this file is too big to display