Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmd/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ var getClustersCmd = &cobra.Command{
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
clusters, err := client.ListClusters(apiToken, baseURL)
response, err := client.ListClusters(apiToken, baseURL, 0, 0)
if err != nil {
fmt.Printf("Error listing clusters: %v\n", err)
return
}
if len(clusters) == 0 {
if len(response.Result) == 0 {
fmt.Println("No clusters found.")
return
}
Expand All @@ -41,7 +41,7 @@ var getClustersCmd = &cobra.Command{
{Number: 6, WidthMin: 10},
{Number: 7, WidthMin: 15},
})
for _, cluster := range clusters {
for _, cluster := range response.Result {
t.AppendRow(table.Row{
cluster.Name,
cluster.KubeVersion,
Expand Down
120 changes: 83 additions & 37 deletions cmd/cluster_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,67 @@ package cmd
import (
"encoding/json"
"fmt"
"github.com/manifoldco/promptui"
"os"
"path/filepath"
"strings"

"ankra/internal/client"

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)

type SelectableItem struct {
IsLoadMore bool
Cluster *client.ClusterListItem
Label string
}

var selectClusterCmd = &cobra.Command{
Use: "cluster",
Aliases: []string{"clusters"},
Short: "Interactively select a cluster and save as active",
Run: func(cmd *cobra.Command, args []string) {
clusters, err := client.ListClusters(apiToken, baseURL)
if err != nil {
fmt.Printf("Error listing clusters: %v\n", err)
return
}
if len(clusters) == 0 {
fmt.Println("No clusters available.")
return
}
templates := &promptui.SelectTemplates{
Label: "{{ . }}:",
Active: "\U0001F336 {{ .Name | cyan }} ({{ .ID | red }})",
Inactive: " {{ .Name | cyan }} ({{ .ID | red }})",
Selected: "\U0001F336 {{ .Name | red }}",
}
searcher := func(input string, index int) bool {
cluster := clusters[index]
return strings.Contains(strings.ToLower(cluster.Name), strings.ToLower(input))
}
prompt := promptui.Select{
Label: "Select Cluster",
Items: clusters,
Templates: templates,
Searcher: searcher,
}
i, _, err := prompt.Run()
if err != nil {
fmt.Printf("Prompt failed: %v\n", err)
return
}
selectedCluster := clusters[i]
if err := saveSelectedCluster(selectedCluster); err != nil {
fmt.Printf("Failed to save selection: %v\n", err)
return
page := 1
fetchedClusters := []client.ClusterListItem{}
startCursorPosition := 0

for {
response, err := client.ListClusters(apiToken, baseURL, page, 25)
if err != nil {
fmt.Printf("Error listing clusters: %v\n", err)
break
}

if len(response.Result) == 0 {
fmt.Println("No clusters available.")
break
}

prompt, selectableItems, updatedFetchedClusters := createListPromptUi(response, fetchedClusters, startCursorPosition)
fetchedClusters = updatedFetchedClusters
i, _, err := prompt.Run()
if err != nil {
fmt.Printf("Prompt failed: %v\n", err)
break
}
selectedItem := selectableItems[i]
if selectedItem.IsLoadMore {
startCursorPosition = i
page++
continue
} else {
selectedCluster := *selectedItem.Cluster
if err := saveSelectedCluster(selectedCluster); err != nil {
fmt.Printf("Failed to save selection: %v\n", err)
return
} else {
fmt.Printf("Selected cluster: %s (ID: %s) is now active.\n", selectedCluster.Name, selectedCluster.ID)
fmt.Println("You can now run 'ankra get operations' or 'ankra get addons'.")
return
}
}
}
fmt.Printf("Selected cluster: %s (ID: %s) is now active.\n", selectedCluster.Name, selectedCluster.ID)
fmt.Println("You can now run 'ankra get operations' or 'ankra get addons'.")
},
}

Expand Down Expand Up @@ -125,3 +134,40 @@ func init() {
selectCmd.AddCommand(selectClusterCmd)
selectCmd.AddCommand(clearSelectionCmd)
}

func createListPromptUi(response *client.ClusterListResponse, previousFetchedClusters []client.ClusterListItem, startCursorPosition int) (promptui.Select, []SelectableItem, []client.ClusterListItem) {
templates := &promptui.SelectTemplates{
Label: "{{ . }}:",
Active: "\U0001F336 {{ .Label | cyan }} {{ if .Cluster }} {{.Cluster.ID | red }} {{ end }}",
Inactive: " {{ .Label | cyan }} {{ if .Cluster }} {{.Cluster.ID | red }} {{ end }}",
Selected: " {{ if .Cluster }} \u2705 {{ .Label | cyan }} {{.Cluster.ID | red }} {{ end }} {{ if .IsLoadMore }} \u23F3 Loading next page... {{ end }}",
}
selectableItems := []SelectableItem{}

fetchedClusters := append(previousFetchedClusters, response.Result...)

for _, cluster := range fetchedClusters {
currentCluster := cluster
selectableItems = append(selectableItems, SelectableItem{IsLoadMore: false, Cluster: &currentCluster, Label: cluster.Name})
}

if response.Pagination.Page < response.Pagination.TotalPages {
selectableItems = append(selectableItems, SelectableItem{IsLoadMore: true, Cluster: nil, Label: "→ Load Next Page"})
}

searcher := func(input string, index int) bool {
cluster := fetchedClusters[index]
return strings.Contains(strings.ToLower(cluster.Name), strings.ToLower(input))
}

prompt := promptui.Select{
Label: "Select Cluster",
Items: selectableItems,
CursorPos: startCursorPosition,
Templates: templates,
Searcher: searcher,
Size: response.Pagination.PageSize + 1,
}

return prompt, selectableItems, fetchedClusters
}
28 changes: 23 additions & 5 deletions internal/client/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,33 @@ type ClusterWithStatusResponse struct {
Result []ClusterWithStatus `json:"result"`
}

func ListClusters(token, baseURL string) ([]ClusterListItem, error) {
url := strings.TrimRight(baseURL, "/") + "/api/v1/clusters"
var resp ClusterListResponse
if err := getJSON(url, token, &resp); err != nil {
func ListClusters(token string, baseURL string, page int, pageSize int) (*ClusterListResponse, error) {
if page == 0 {
page = 1
}
if pageSize == 0 {
pageSize = 25
}

url := fmt.Sprintf("%s/api/v1/clusters?page=%d&page_size=%d", baseURL, page, pageSize)
fmt.Printf("CHECK %s", url)
var response *ClusterListResponse
if err := getJSON(url, token, &response); err != nil {
return nil, err
}
return resp.Result, nil

return response, nil
}

// func ListClusters(token, baseURL string) ([]ClusterListItem, error) {
// url := strings.TrimRight(baseURL, "/") + "/api/v1/clusters"
// var resp ClusterListResponse
// if err := getJSON(url, token, &resp); err != nil {
// return nil, err
// }
// return resp.Result, nil
// }

func GetCluster(token, baseURL, name string) (ClusterWithStatus, error) {
url := fmt.Sprintf("%s/api/v1/clusters?cluster_name=%s",
strings.TrimRight(baseURL, "/"), name)
Expand Down
Loading