Skip to content

Commit 5f9897b

Browse files
authored
feat: add list-deployments command (#63)
Lists namespaces and display PR information if available.
1 parent 3eeab10 commit 5f9897b

5 files changed

Lines changed: 145 additions & 1 deletion

File tree

pkg/cmd/listdeployments.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
8+
"github.com/SwissDataScienceCenter/renku-dev-utils/pkg/github"
9+
"github.com/SwissDataScienceCenter/renku-dev-utils/pkg/k8s"
10+
"github.com/spf13/cobra"
11+
)
12+
13+
var listDeploymentsCmd = &cobra.Command{
14+
Use: "list-deployments",
15+
Aliases: []string{"lsd"},
16+
Short: "List renku deployments",
17+
Run: listDeployments,
18+
}
19+
20+
func listDeployments(cmd *cobra.Command, args []string) {
21+
ctx := cmd.Context()
22+
if ctx == nil {
23+
ctx = context.Background()
24+
}
25+
26+
cli, err := github.NewGitHubCLI("")
27+
if err != nil {
28+
fmt.Println(err)
29+
os.Exit(1)
30+
}
31+
32+
clients, err := k8s.GetClientset()
33+
if err != nil {
34+
fmt.Println(err)
35+
os.Exit(1)
36+
}
37+
38+
namespaceList, err := k8s.ListNamespaces(ctx, clients)
39+
if err != nil {
40+
fmt.Println(err)
41+
os.Exit(1)
42+
}
43+
44+
for i := range namespaceList.Items {
45+
ns := namespaceList.Items[i]
46+
repo, pr := github.MatchDeploymentNamespace(ns.Name)
47+
if repo != "" {
48+
state, err := cli.GetPullRequestState(ctx, repo, pr)
49+
if err != nil {
50+
state = "UNKNOWN"
51+
fmt.Println(err)
52+
}
53+
fmt.Printf("%s\t%s\t%d\t%s\n", ns.Name, repo, pr, state)
54+
} else {
55+
fmt.Printf("%s\n", ns.Name)
56+
}
57+
}
58+
}

pkg/cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func preRunRoot(cmd *cobra.Command, args []string) error {
2929
func init() {
3030
rootCmd.AddCommand(cleanupDeploymentCmd)
3131
rootCmd.AddCommand(copyKeycloakAdminPasswordCmd)
32+
rootCmd.AddCommand(listDeploymentsCmd)
3233
rootCmd.AddCommand(loginCmd)
3334
rootCmd.AddCommand(logoutCmd)
3435
rootCmd.AddCommand(makeMeAdminCmd)

pkg/github/pullrequest.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package github
33
import (
44
"context"
55
"encoding/json"
6+
"fmt"
67
)
78

89
func (cli *GitHubCLI) GetCurrentPullRequest(ctx context.Context) (int, error) {
@@ -23,3 +24,22 @@ func (cli *GitHubCLI) GetCurrentPullRequest(ctx context.Context) (int, error) {
2324
type gitHubPRViewOutput struct {
2425
Number int `json:"number"`
2526
}
27+
28+
func (cli *GitHubCLI) GetPullRequestState(ctx context.Context, repository string, pr int) (state string, err error) {
29+
out, err := cli.RunCmd(ctx, "pr", "view", "--repo", repository, "--json", "state", fmt.Sprintf("%d", pr))
30+
if err != nil {
31+
return "", err
32+
}
33+
34+
var res gitHubPRViewStateOutput
35+
err = json.Unmarshal(out, &res)
36+
if err != nil {
37+
return "", err
38+
}
39+
40+
return res.State, nil
41+
}
42+
43+
type gitHubPRViewStateOutput struct {
44+
State string `json:"state"`
45+
}

pkg/github/utils.go

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
package github
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strconv"
7+
)
48

59
// Maps repositories to namespace templates
610
var repoToNamespaceTemplateMap map[string]string
711

12+
// Deployment namespace regexes
13+
var namespaceRegexes []namespaceRegex
14+
815
// Contains the list of Renku global images
916
var globalImagesSlice []string
1017

@@ -20,9 +27,28 @@ func GetGlobalImages() []string {
2027
return globalImagesSlice[:]
2128
}
2229

30+
func MatchDeploymentNamespace(namespace string) (repository string, pr int) {
31+
for i := range namespaceRegexes {
32+
res := namespaceRegexes[i].regex.FindStringSubmatch(namespace)
33+
if res != nil {
34+
pr, err := strconv.Atoi(res[1])
35+
if err == nil && pr > 0 {
36+
return namespaceRegexes[i].repository, pr
37+
}
38+
}
39+
}
40+
return "", 0
41+
}
42+
43+
type namespaceRegex struct {
44+
regex *regexp.Regexp
45+
repository string
46+
}
47+
2348
func init() {
2449
initRepoToNamespaceTemplateMap()
2550
initGlobalImagesSlice()
51+
initNamespaceRegexes()
2652
}
2753

2854
func initRepoToNamespaceTemplateMap() {
@@ -31,6 +57,32 @@ func initRepoToNamespaceTemplateMap() {
3157
"SwissDataScienceCenter/renku": "ci-renku-%d",
3258
"SwissDataScienceCenter/renku-data-services": "renku-ci-ds-%d",
3359
"SwissDataScienceCenter/renku-ui": "renku-ci-ui-%d",
60+
"SwissDataScienceCenter/renku-gateway": "renku-ci-gw-%d",
61+
}
62+
}
63+
64+
func initNamespaceRegexes() {
65+
namespaceRegexes = []namespaceRegex{
66+
{
67+
regex: regexp.MustCompile(`^renku-ci-am-(\d+)$`),
68+
repository: "SwissDataScienceCenter/amalthea",
69+
},
70+
{
71+
regex: regexp.MustCompile(`^ci-renku-(\d+)$`),
72+
repository: "SwissDataScienceCenter/renku",
73+
},
74+
{
75+
regex: regexp.MustCompile(`^renku-ci-ds-(\d+)$`),
76+
repository: "SwissDataScienceCenter/renku-data-services",
77+
},
78+
{
79+
regex: regexp.MustCompile(`^renku-ci-ui-(\d+)$`),
80+
repository: "SwissDataScienceCenter/renku-ui",
81+
},
82+
{
83+
regex: regexp.MustCompile(`^renku-ci-gw-(\d+)$`),
84+
repository: "SwissDataScienceCenter/renku-gateway",
85+
},
3486
}
3587
}
3688

pkg/k8s/namespace.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package k8s
2+
3+
import (
4+
"context"
5+
6+
corev1 "k8s.io/api/core/v1"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
"k8s.io/client-go/kubernetes"
9+
)
10+
11+
func ListNamespaces(ctx context.Context, clients *kubernetes.Clientset) (namespaceList *corev1.NamespaceList, err error) {
12+
return clients.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
13+
}

0 commit comments

Comments
 (0)