Skip to content

Commit ee00e24

Browse files
feat(Go): add clusterName variable
1 parent 9e4423b commit ee00e24

4 files changed

Lines changed: 191 additions & 19 deletions

File tree

pkg/commands/environment.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,11 @@ func addEnvironmentCmd(topLevel *cobra.Command) {
7272
environmentApplyCmd.PersistentFlags().BoolVar(&optFlags.RedactedEnv, "redact", true, "Redact the terraform output before printing")
7373
environmentApplyCmd.Flags().StringVar(&optFlags.BuildUrl, "build-url", "", "The concourse apply build url")
7474
environmentApplyCmd.Flags().BoolVar(&optFlags.IsApplyPipeline, "is-apply-pipeline", false, "is this running in the apply pipelines")
75+
7576
environmentApplyCmd.Flags().StringVar(&optFlags.AppID, "github-appid", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_app_id"), "App ID ")
7677
environmentApplyCmd.Flags().StringVar(&optFlags.InstallID, "github-installation-id", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_installation_id"), "Installation ID ")
7778
environmentApplyCmd.Flags().StringVar(&optFlags.PemFile, "github-pem-file", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_pem_file"), "PEM file ")
79+
environmentApplyCmd.Flags().StringVarP(&clusterName, "cluster-name", "c", "live", "[optional] Cluster name")
7880

7981
environmentBumpModuleCmd.Flags().StringVarP(&module, "module", "m", "", "Module to upgrade the version")
8082
environmentBumpModuleCmd.Flags().StringVarP(&moduleVersion, "module-version", "v", "", "Semantic version to bump a module to")
@@ -93,9 +95,11 @@ func addEnvironmentCmd(topLevel *cobra.Command) {
9395
environmentDestroyCmd.Flags().StringVar(&optFlags.ClusterDir, "clusterdir", "", "folder name under namespaces/ inside cloud-platform-environments repo referring to full cluster name")
9496
environmentDestroyCmd.PersistentFlags().BoolVar(&optFlags.RedactedEnv, "redact", true, "Redact the terraform output before printing")
9597
environmentDestroyCmd.Flags().BoolVar(&optFlags.SkipProdDestroy, "skip-prod-destroy", true, "skip prod namespaces from destroy namespace")
98+
9699
environmentDestroyCmd.Flags().StringVar(&optFlags.AppID, "github-appid", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_app_id"), "App ID ")
97100
environmentDestroyCmd.Flags().StringVar(&optFlags.InstallID, "github-installation-id", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_installation_id"), "Installation ID ")
98101
environmentDestroyCmd.Flags().StringVar(&optFlags.PemFile, "github-pem-file", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_pem_file"), "PEM file ")
102+
environmentDestroyCmd.Flags().StringVarP(&clusterName, "cluster-name", "c", "live", "[optional] Cluster name")
99103

100104
environmentDivergenceCmd.Flags().StringVarP(&clusterName, "cluster-name", "c", "live", "[optional] Cluster name")
101105
environmentDivergenceCmd.Flags().StringVarP(&githubToken, "github-token", "g", "", "[required] Github token")
@@ -113,9 +117,11 @@ func addEnvironmentCmd(topLevel *cobra.Command) {
113117
environmentPlanCmd.Flags().StringVar(&optFlags.ClusterCtx, "cluster", "", "cluster context from kubeconfig file")
114118
environmentPlanCmd.Flags().StringVar(&optFlags.ClusterDir, "clusterdir", "", "folder name under namespaces/ inside cloud-platform-environments repo referring to full cluster name")
115119
environmentPlanCmd.PersistentFlags().BoolVar(&optFlags.RedactedEnv, "redact", true, "Redact the terraform output before printing")
120+
116121
environmentPlanCmd.Flags().StringVar(&optFlags.AppID, "github-appid", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_app_id"), "App ID ")
117122
environmentPlanCmd.Flags().StringVar(&optFlags.InstallID, "github-installation-id", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_installation_id"), "Installation ID ")
118123
environmentPlanCmd.Flags().StringVar(&optFlags.PemFile, "github-pem-file", os.Getenv("TF_VAR_github_cloud_platform_concourse_bot_pem_file"), "PEM file ")
124+
environmentPlanCmd.Flags().StringVarP(&clusterName, "cluster-name", "c", "live", "[optional] Cluster name")
119125

120126
}
121127

@@ -182,7 +188,7 @@ var environmentPlanCmd = &cobra.Command{
182188
Owner: "ministryofjustice",
183189
}
184190

185-
authType, err := github.NewGithubAppClient(ghConfig, optFlags.PemFile, optFlags.AppID, optFlags.InstallID).FlagCheckAuthType(context.Background(), optFlags.PRNumber, optFlags.Namespace)
191+
authType, err := github.NewGithubAppClient(ghConfig, optFlags.PemFile, optFlags.AppID, optFlags.InstallID).FlagCheckAuthType(context.Background(), optFlags.PRNumber, optFlags.Namespace, clusterName)
186192
if err != nil {
187193
contextLogger.Printf("Failed to get auth_type from PR: %v, defaulting to token auth", err)
188194
authType = "token"
@@ -242,7 +248,7 @@ var environmentApplyCmd = &cobra.Command{
242248
Owner: "ministryofjustice",
243249
}
244250

245-
authType, err := github.NewGithubAppClient(ghConfig, optFlags.PemFile, optFlags.AppID, optFlags.InstallID).FlagCheckAuthType(context.Background(), optFlags.PRNumber, optFlags.Namespace)
251+
authType, err := github.NewGithubAppClient(ghConfig, optFlags.PemFile, optFlags.AppID, optFlags.InstallID).FlagCheckAuthType(context.Background(), optFlags.PRNumber, optFlags.Namespace, clusterName)
246252
if err != nil {
247253
contextLogger.Printf("Failed to get auth_type from PR: %v, defaulting to token auth", err)
248254
authType = "token"
@@ -322,7 +328,7 @@ var environmentDestroyCmd = &cobra.Command{
322328
Owner: "ministryofjustice",
323329
}
324330

325-
authType, err := github.NewGithubAppClient(ghConfig, optFlags.PemFile, optFlags.AppID, optFlags.InstallID).FlagCheckAuthType(context.Background(), optFlags.PRNumber, optFlags.Namespace)
331+
authType, err := github.NewGithubAppClient(ghConfig, optFlags.PemFile, optFlags.AppID, optFlags.InstallID).FlagCheckAuthType(context.Background(), optFlags.PRNumber, optFlags.Namespace, clusterName)
326332
if err != nil {
327333
contextLogger.Printf("Failed to get auth_type from PR: %v, defaulting to token auth", err)
328334
authType = "token"

pkg/github/auth_type.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import (
99
"github.com/google/go-github/v74/github"
1010
)
1111

12-
func (c *GithubClient) FlagCheckAuthType(ctx context.Context, prNumber int, namespace string) (string, error) {
12+
func (c *GithubClient) FlagCheckAuthType(ctx context.Context, prNumber int, namespace, clusterName string) (string, error) {
1313
var branch string
1414
if prNumber == 0 && namespace == "" {
1515
return "", fmt.Errorf("either -pr-number or -namespace flag is required")
1616
} else if prNumber > 0 {
1717
// get namespace from PR
18-
prDetails, err := c.PRDetails(context.Background(), prNumber)
18+
prDetails, err := c.PRDetails(context.Background(), prNumber, clusterName)
1919
if err != nil {
2020
return "", fmt.Errorf("failed to get pr details: %v", err)
2121
}
@@ -29,7 +29,7 @@ func (c *GithubClient) FlagCheckAuthType(ctx context.Context, prNumber int, name
2929
}
3030

3131
// get authtype this is only needed for migration purposes once users are all using github app this can be removed
32-
authType, err := c.SearchAuthTypeInRepo(context.Background(), namespace, branch)
32+
authType, err := c.SearchAuthTypeInRepo(context.Background(), namespace, branch, clusterName)
3333
if err != nil {
3434
fmt.Fprintf(os.Stderr, "Failed to get auth_type from PR: %v, defaulting to token auth\n", err) // DEBUG
3535
authType = "token"
@@ -38,37 +38,34 @@ func (c *GithubClient) FlagCheckAuthType(ctx context.Context, prNumber int, name
3838
return authType, nil
3939
}
4040

41-
func (c *GithubClient) PRDetails(ctx context.Context, prNumber int) ([]string, error) {
41+
func (c *GithubClient) PRDetails(ctx context.Context, prNumber int, clusterName string) ([]string, error) {
4242
var namespace string
43-
pr, _, err := c.V3.PullRequests.Get(ctx, c.Owner, c.Repository, prNumber)
43+
pr, _, err := c.PullRequests.Get(ctx, c.Owner, c.Repository, prNumber)
4444
if err != nil {
4545
return nil, fmt.Errorf("error getting PR %d: %v", prNumber, err)
4646
}
4747
branch := pr.GetHead().GetRef()
48-
fmt.Println(branch)
49-
files, _, err := c.V3.PullRequests.ListFiles(ctx, c.Owner, c.Repository, prNumber, nil)
48+
files, _, err := c.PullRequests.ListFiles(ctx, c.Owner, c.Repository, prNumber, nil)
5049
if err != nil {
5150
return nil, fmt.Errorf("error listing files for PR %d: %v", prNumber, err)
5251
}
5352
for _, file := range files {
54-
fmt.Println(file.Filename)
5553
// split file path by "/"
5654
pathParts := strings.Split(file.GetFilename(), "/")
5755
// check if path matches expected pattern
58-
if len(pathParts) >= 5 && pathParts[0] == "namespaces" && pathParts[1] == "live.cloud-platform.service.justice.gov.uk" {
56+
if len(pathParts) >= 5 && pathParts[0] == "namespaces" && pathParts[1] == clusterName+".cloud-platform.service.justice.gov.uk" {
5957
namespace = pathParts[2]
6058
break
6159
}
62-
fmt.Println(namespace)
6360
}
6461

6562
prDetails := []string{branch, namespace}
6663
return prDetails, nil
6764
}
6865

6966
// search repo for auth_type variable default in a PR depending on namespace directory name
70-
func (c *GithubClient) SearchAuthTypeInRepo(ctx context.Context, namespace, branch string) (string, error) {
71-
path := fmt.Sprintf("namespaces/live.cloud-platform.service.justice.gov.uk/%s/resources/variables.tf", namespace)
67+
func (c *GithubClient) SearchAuthTypeInRepo(ctx context.Context, namespace, branch, clusterName string) (string, error) {
68+
path := fmt.Sprintf("namespaces/%s.cloud-platform.service.justice.gov.uk/%s/resources/variables.tf", clusterName, namespace)
7269
opt := &github.RepositoryContentGetOptions{
7370
Ref: branch,
7471
}
@@ -168,7 +165,7 @@ func containsVarAuthType(line string) bool {
168165
if len(rest) >= 12 && rest[:11] == "\"auth_type\"" {
169166
rest2 := rest[11:]
170167
rest2 = trimSpace(rest2)
171-
if rest2 == "{" || rest2 == "{" {
168+
if rest2 == "{" {
172169
return true
173170
}
174171
}

pkg/github/client.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
var _ GithubPullRequestsService = (*github.PullRequestsService)(nil)
1717

1818
type GithubPullRequestsService interface {
19+
Get(ctx context.Context, owner, repo string, number int) (*github.PullRequest, *github.Response, error)
1920
ListFiles(ctx context.Context, owner string, repo string, number int, opt *github.ListOptions) ([]*github.CommitFile, *github.Response, error)
2021
IsMerged(ctx context.Context, owner string, repo string, number int) (bool, *github.Response, error)
2122
Create(ctx context.Context, owner string, repo string, pr *github.NewPullRequest) (*github.PullRequest, *github.Response, error)
@@ -69,19 +70,22 @@ func NewGithubAppClient(config *GithubClientConfig, key, appid, installid string
6970

7071
appIDInt, err := strconv.ParseInt(appid, 10, 64)
7172
if err != nil {
72-
fmt.Printf("[NewGihubAppClient] Failed to parse appid '%s': %v\n", appid, err)
73+
fmt.Printf("[NewGithubAppClient] Failed to parse appid, value returned:'%s'\nerror message: %v\n", appid, err)
74+
fmt.Println("[NewGithubAppClient] Check if the appid has been set correctly")
7375
return nil
7476
}
7577

7678
installIDInt, err := strconv.ParseInt(installid, 10, 64)
7779
if err != nil {
78-
fmt.Printf("[NewGihubAppClient] Failed to parse installid '%s': %v\n", installid, err)
80+
fmt.Printf("[NewGithubAppClient] Failed to parse installid, value returned:'%s'\nerror message: %v\n", installid, err)
81+
fmt.Println("[NewGithubAppClient] Check if the installid has been set correctly")
7982
return nil
8083
}
8184

8285
appTokenSource, err := githubauth.NewApplicationTokenSource(appIDInt, privateKey)
8386
if err != nil {
84-
fmt.Printf("[NewGihubAppClient] Failed to create ApplicationTokenSource: %v\n", err)
87+
fmt.Printf("[NewGithubAppClient] Failed to create ApplicationTokenSource: %v\n", err)
88+
fmt.Println("[NewGithubAppClient] Check if the private key has been set correctly")
8589
return nil
8690
}
8791

pkg/github/client_test.go

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ type mockGithub struct {
1414
merged bool
1515
}
1616

17+
func (m *mockGithub) Get(ctx context.Context, owner, repo string, number int) (*github.PullRequest, *github.Response, error) {
18+
return nil, nil, nil
19+
}
20+
1721
func (m *mockGithub) ListFiles(ctx context.Context, owner string, repo string, number int, opt *github.ListOptions) ([]*github.CommitFile, *github.Response, error) {
1822
return m.resp, nil, nil
1923
}
@@ -110,3 +114,164 @@ func TestGithubClient_IsMerged(t *testing.T) {
110114
t.Errorf("GithubClient.IsMerged() = %v, want %v", got, true)
111115
}
112116
}
117+
118+
type mockPullRequestService struct {
119+
pr *github.PullRequest
120+
files []*github.CommitFile
121+
}
122+
123+
func (m *mockPullRequestService) Get(ctx context.Context, owner, repo string, number int) (*github.PullRequest, *github.Response, error) {
124+
return m.pr, nil, nil
125+
}
126+
127+
func (m *mockPullRequestService) ListFiles(ctx context.Context, owner, repo string, number int, opts *github.ListOptions) ([]*github.CommitFile, *github.Response, error) {
128+
return m.files, nil, nil
129+
}
130+
131+
func (m *mockPullRequestService) IsMerged(ctx context.Context, owner, repo string, number int) (bool, *github.Response, error) {
132+
return true, nil, nil
133+
}
134+
135+
func (m *mockPullRequestService) Create(ctx context.Context, owner, repo string, pr *github.NewPullRequest) (*github.PullRequest, *github.Response, error) {
136+
return nil, nil, nil
137+
}
138+
139+
func (m *mockPullRequestService) List(ctx context.Context, owner, repo string, opts *github.PullRequestListOptions) ([]*github.PullRequest, *github.Response, error) {
140+
return nil, nil, nil
141+
}
142+
143+
func TestGithubClient_PRDetails(t *testing.T) {
144+
tests := []struct {
145+
name string
146+
prNumber int
147+
clusterName string
148+
pr *github.PullRequest
149+
files []*github.CommitFile
150+
want []string
151+
wantErr bool
152+
errContains string
153+
}{
154+
{
155+
name: "successful extraction with valid namespace path",
156+
prNumber: 123,
157+
clusterName: "live",
158+
pr: &github.PullRequest{
159+
Head: &github.PullRequestBranch{
160+
Ref: github.Ptr("feature-branch"),
161+
},
162+
},
163+
files: []*github.CommitFile{
164+
{
165+
Filename: github.Ptr("namespaces/live.cloud-platform.service.justice.gov.uk/test-namespace/resources/variables.tf"),
166+
},
167+
{
168+
Filename: github.Ptr("other/file.txt"),
169+
},
170+
},
171+
want: []string{"feature-branch", "test-namespace"},
172+
wantErr: false,
173+
},
174+
{
175+
name: "no matching namespace path",
176+
prNumber: 124,
177+
clusterName: "live",
178+
pr: &github.PullRequest{
179+
Head: &github.PullRequestBranch{
180+
Ref: github.Ptr("another-branch"),
181+
},
182+
},
183+
files: []*github.CommitFile{
184+
{
185+
Filename: github.Ptr("other/path/file.txt"),
186+
},
187+
{
188+
Filename: github.Ptr("random/file.yaml"),
189+
},
190+
},
191+
want: []string{"another-branch", ""},
192+
wantErr: false,
193+
},
194+
{
195+
name: "multiple files with first matching",
196+
prNumber: 125,
197+
clusterName: "live",
198+
pr: &github.PullRequest{
199+
Head: &github.PullRequestBranch{
200+
Ref: github.Ptr("dev-branch"),
201+
},
202+
},
203+
files: []*github.CommitFile{
204+
{
205+
Filename: github.Ptr("namespaces/live.cloud-platform.service.justice.gov.uk/first-namespace/resources/00-namespace.yaml"),
206+
},
207+
{
208+
Filename: github.Ptr("namespaces/live.cloud-platform.service.justice.gov.uk/second-namespace/resources/main.tf"),
209+
},
210+
},
211+
want: []string{"dev-branch", "first-namespace"},
212+
wantErr: false,
213+
},
214+
{
215+
name: "path with insufficient parts",
216+
prNumber: 126,
217+
clusterName: "live",
218+
pr: &github.PullRequest{
219+
Head: &github.PullRequestBranch{
220+
Ref: github.Ptr("short-path-branch"),
221+
},
222+
},
223+
files: []*github.CommitFile{
224+
{
225+
Filename: github.Ptr("namespaces/live.cloud-platform.service.justice.gov.uk"),
226+
},
227+
},
228+
want: []string{"short-path-branch", ""},
229+
wantErr: false,
230+
},
231+
{
232+
name: "path with different cluster name",
233+
prNumber: 126,
234+
clusterName: "staging",
235+
pr: &github.PullRequest{
236+
Head: &github.PullRequestBranch{
237+
Ref: github.Ptr("short-path-branch"),
238+
},
239+
},
240+
files: []*github.CommitFile{
241+
{
242+
Filename: github.Ptr("namespaces/staging.cloud-platform.service.justice.gov.uk/test-namespace/resources/variables.tf"),
243+
},
244+
},
245+
want: []string{"short-path-branch", "test-namespace"},
246+
wantErr: false,
247+
},
248+
}
249+
250+
for _, tt := range tests {
251+
t.Run(tt.name, func(t *testing.T) {
252+
mockPRService := &mockPullRequestService{
253+
pr: tt.pr,
254+
files: tt.files,
255+
}
256+
257+
c := &GithubClient{
258+
Owner: "test-owner",
259+
Repository: "test-repo",
260+
PullRequests: mockPRService,
261+
}
262+
263+
got, err := c.PRDetails(context.Background(), tt.prNumber, tt.clusterName)
264+
265+
if tt.wantErr {
266+
assert.Error(t, err)
267+
if tt.errContains != "" {
268+
assert.Contains(t, err.Error(), tt.errContains)
269+
}
270+
return
271+
}
272+
273+
assert.NoError(t, err)
274+
assert.Equal(t, tt.want, got)
275+
})
276+
}
277+
}

0 commit comments

Comments
 (0)