Skip to content

Commit

Permalink
Implement stackit ske cluster list
Browse files Browse the repository at this point in the history
  • Loading branch information
Henrique Santos committed Nov 20, 2023
1 parent c6a5d86 commit 7009f17
Show file tree
Hide file tree
Showing 4 changed files with 281 additions and 0 deletions.
18 changes: 18 additions & 0 deletions internal/cmd/ske/cluster/cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cluster

import (
"github.com/stackitcloud/stackit-cli/internal/cmd/ske/cluster/list"

"github.com/spf13/cobra"
)

var Cmd = &cobra.Command{
Use: "zone",
Short: "Provides functionality for SKE cluster",
Long: "Provides functionality for SKE cluster",
Example: list.Cmd.Example,
}

func init() {
Cmd.AddCommand(list.Cmd)
}
80 changes: 80 additions & 0 deletions internal/cmd/ske/cluster/list/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package list

import (
"context"
"fmt"

"github.com/stackitcloud/stackit-cli/internal/pkg/config"
"github.com/stackitcloud/stackit-cli/internal/pkg/services/ske/client"
"github.com/stackitcloud/stackit-cli/internal/pkg/tables"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stackitcloud/stackit-sdk-go/services/ske"
)

const (
projectIdFlag = "project-id"
)

type flagModel struct {
ProjectId string
}

var Cmd = &cobra.Command{
Use: "list",
Short: "List all SKE clusters",
Long: "List all SKE clusters",
Example: `$ stackit ske cluster list --project-id xxx`,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
model, err := parseFlags(cmd)
if err != nil {
return err
}

// Configure API client
apiClient, err := client.ConfigureClient(cmd)
if err != nil {
return fmt.Errorf("authentication failed, please run \"stackit auth login\" or \"stackit auth activate-service-account\"")
}

// Call API
req := buildRequest(ctx, model, apiClient)
resp, err := req.Execute()
if err != nil {
return fmt.Errorf("get SKE clusters: %w", err)
}
clusters := *resp.Items
if len(clusters) == 0 {
fmt.Printf("No clusters found for project with ID %s\n", model.ProjectId)
return nil
}

// Show output as table
table := tables.NewTable()
table.SetHeader("NAME", "STATE")
for _, cluster := range clusters {
table.AddRow(*cluster.Name, *cluster.Status.Aggregated)
}
table.Render()

return nil
},
}

func parseFlags(cmd *cobra.Command) (*flagModel, error) {

Check failure on line 66 in internal/cmd/ske/cluster/list/list.go

View workflow job for this annotation

GitHub Actions / CI

unused-parameter: parameter 'cmd' seems to be unused, consider removing or renaming it as _ (revive)
projectId := viper.GetString(config.ProjectIdKey)
if projectId == "" {
return nil, fmt.Errorf("project ID not set")
}

return &flagModel{
ProjectId: projectId,
}, nil
}

func buildRequest(ctx context.Context, model *flagModel, apiClient *ske.APIClient) ske.ApiGetClustersRequest {
req := apiClient.GetClusters(ctx, model.ProjectId)
return req
}
165 changes: 165 additions & 0 deletions internal/cmd/ske/cluster/list/list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package list

import (
"context"
"testing"

"github.com/stackitcloud/stackit-cli/internal/pkg/config"
"github.com/stackitcloud/stackit-cli/internal/pkg/testutils"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/google/uuid"
"github.com/spf13/cobra"
"github.com/stackitcloud/stackit-sdk-go/services/ske"
)

type testCtxKey struct{}

var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo")
var testClient = &ske.APIClient{}
var testProjectId = uuid.NewString()

func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string {
flagValues := map[string]string{
projectIdFlag: testProjectId,
}
for _, mod := range mods {
mod(flagValues)
}
return flagValues
}

func fixtureFlagModel(mods ...func(model *flagModel)) *flagModel {
model := &flagModel{
ProjectId: testProjectId,
}
for _, mod := range mods {
mod(model)
}
return model
}

func fixtureRequest(mods ...func(request *ske.ApiGetClustersRequest)) ske.ApiGetClustersRequest {
request := testClient.GetClusters(testCtx, testProjectId)
for _, mod := range mods {
mod(&request)
}
return request
}

func TestParseFlags(t *testing.T) {
tests := []struct {
description string
flagValues map[string]string
isValid bool
expectedModel *flagModel
}{
{
description: "base",
flagValues: fixtureFlagValues(),
isValid: true,
expectedModel: fixtureFlagModel(),
},
{
description: "no values",
flagValues: map[string]string{},
isValid: false,
},
{
description: "project id missing",
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
delete(flagValues, projectIdFlag)
}),
isValid: false,
},
{
description: "project id invalid 1",
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
flagValues[projectIdFlag] = ""
}),
isValid: false,
},
{
description: "project id invalid 2",
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
flagValues[projectIdFlag] = "invalid-uuid"
}),
isValid: false,
},
}

for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
cmd := &cobra.Command{}

// Flag defined in root command
err := testutils.ConfigureBindUUIDFlag(cmd, projectIdFlag, config.ProjectIdKey)
if err != nil {
t.Fatalf("configure global flag --%s: %v", projectIdFlag, err)
}

for flag, value := range tt.flagValues {
err := cmd.Flags().Set(flag, value)
if err != nil {
if !tt.isValid {
return
}
t.Fatalf("setting flag --%s=%s: %v", flag, value, err)
}
}

err = cmd.ValidateRequiredFlags()
if err != nil {
if !tt.isValid {
return
}
t.Fatalf("error validating flags: %v", err)
}

model, err := parseFlags(cmd)
if err != nil {
if !tt.isValid {
return
}
t.Fatalf("error parsing flags: %v", err)
}

if !tt.isValid {
t.Fatalf("did not fail on invalid input")
}
diff := cmp.Diff(model, tt.expectedModel)
if diff != "" {
t.Fatalf("Data does not match: %s", diff)
}
})
}
}

func TestBuildRequest(t *testing.T) {
tests := []struct {
description string
model *flagModel
expectedRequest ske.ApiGetClustersRequest
}{
{
description: "base",
model: fixtureFlagModel(),
expectedRequest: fixtureRequest(),
},
}

for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
request := buildRequest(testCtx, tt.model, testClient)

diff := cmp.Diff(request, tt.expectedRequest,
cmp.AllowUnexported(tt.expectedRequest),
cmpopts.EquateComparable(testCtx),
)
if diff != "" {
t.Fatalf("Data does not match: %s", diff)
}
})
}
}
18 changes: 18 additions & 0 deletions internal/cmd/ske/ske.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ske

import (
"github.com/stackitcloud/stackit-cli/internal/cmd/ske/cluster"

"github.com/spf13/cobra"
)

var Cmd = &cobra.Command{
Use: "dns",
Short: "Provides functionality for SKE",
Long: "Provides functionality for STACKIT Kubernetes engine (SKE)",
Example: cluster.Cmd.Example,
}

func init() {
Cmd.AddCommand(cluster.Cmd)
}

0 comments on commit 7009f17

Please sign in to comment.