feat(google-cloud): command to create Workload Identity Federation

This commit is contained in:
Imre Farkas 2024-01-23 11:14:58 +01:00
parent 45ad6d8a4d
commit 82da7c3031
7 changed files with 261 additions and 0 deletions

View File

@ -0,0 +1,19 @@
package google_cloud
import (
"github.com/spf13/cobra"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
googleCloudCreateWLIFCmd "gitlab.com/gitlab-org/cli/commands/google_cloud/wlif"
)
func NewCmdGoogleCloud(f *cmdutils.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "google-cloud <command> [flags]",
Short: "EXPERIMENTAL: Manage Google Cloud integration of a GitLab project",
}
cmd.AddCommand(googleCloudCreateWLIFCmd.NewCmdCreateWLIF(f))
return cmd
}

View File

@ -0,0 +1,84 @@
package wlif
import (
"bytes"
"fmt"
"net/http"
"net/url"
"os/exec"
"github.com/MakeNowJust/heredoc"
"github.com/spf13/cobra"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
)
const (
flagGoogleCloudProjectID = "google-cloud-project-id"
)
type WLIFCreateOptions struct {
GoogleCloudProjectID string `url:"google_cloud_project_id,omitempty"`
GoogleCloudWorkloadIdentityPoolID string `url:"google_cloud_workload_identity_pool_id,omitempty"`
GoogleCloudWorkloadIdentityPoolDisplayName string `url:"google_cloud_workload_identity_pool_display_name,omitempty"`
GoogleCloudWorkloadIdentityPoolProviderID string `url:"google_cloud_workload_identity_pool_provider_id,omitempty"`
GoogleCloudWorkloadIdentityPoolProviderDisplayName string `url:"google_cloud_workload_identity_pool_provider_display_name,omitempty"`
}
func NewCmdCreateWLIF(f *cmdutils.Factory) *cobra.Command {
opts := &WLIFCreateOptions{}
cmd := &cobra.Command{
Use: "create-wlif [project] [flags]",
Short: "EXPERIMENTAL: Create a new Workload Identity Federation on Google Cloud",
Example: heredoc.Doc(`
$ glab google-cloud create-wlif project-id \
--google-cloud-project-id=google-cloud-project-id \
--google-cloud-workload-identity-pool-id=pool-id \
--google-cloud-workload-identity-pool-display-name=pool-display-name \
--google-cloud-workload-identity-pool-provider-id=provider-id \
--google-cloud-workload-identity-pool-provider-display-name=provider-display-name
`),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
client, err := f.HttpClient()
if err != nil {
return err
}
projectID := args[0]
u := fmt.Sprintf("projects/%s/scripts/google_cloud/create_wlif", url.PathEscape(projectID))
request, err := client.NewRequest(http.MethodGet, u, opts, nil)
if err != nil {
return err
}
var buf bytes.Buffer
res, err := client.Do(request, &buf)
if err != nil {
return err
}
if res.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", res.StatusCode)
}
script := exec.Command("bash", "-c", buf.String())
output, err := script.CombinedOutput()
fmt.Println(string(output))
if err != nil {
return err
}
return nil
},
}
cmd.Flags().StringVar(&opts.GoogleCloudProjectID, flagGoogleCloudProjectID, "", "Google Cloud Project ID for the Workload Identity Federation")
cmd.Flags().StringVar(&opts.GoogleCloudWorkloadIdentityPoolID, "google-cloud-workload-identity-pool-id", "", "ID of the Google Cloud Workload Identity Pool to be created")
cmd.Flags().StringVar(&opts.GoogleCloudWorkloadIdentityPoolDisplayName, "google-cloud-workload-identity-pool-display-name", "", "display name of the Google Cloud Workload Identity Pool to be created")
cmd.Flags().StringVar(&opts.GoogleCloudWorkloadIdentityPoolProviderID, "google-cloud-workload-identity-pool-provider-id", "", "ID of the Google Cloud Workload Identity Pool Provider to be created")
cmd.Flags().StringVar(&opts.GoogleCloudWorkloadIdentityPoolProviderDisplayName, "google-cloud-workload-identity-pool-provider-display-name", "", "display name of the Google Cloud Workload Identity Pool Provider to be created")
cobra.CheckErr(cmd.MarkFlagRequired(flagGoogleCloudProjectID))
return cmd
}

View File

@ -0,0 +1,62 @@
package wlif
import (
"bytes"
"io"
"net/http"
"os"
"testing"
"github.com/stretchr/testify/assert"
"gitlab.com/gitlab-org/cli/commands/cmdtest"
"gitlab.com/gitlab-org/cli/pkg/httpmock"
"gitlab.com/gitlab-org/cli/test"
)
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, "")
factory := cmdtest.InitFactory(ios, rt)
_, _ = factory.HttpClient()
cmd := NewCmdCreateWLIF(factory)
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
}
func TestNewCmdCreateWLIF(t *testing.T) {
old := os.Stdout // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stdout = w
fakeHTTP := &httpmock.Mocker{
MatchURL: httpmock.PathAndQuerystring,
}
defer fakeHTTP.Verify(t)
fakeHTTP.RegisterResponder(http.MethodGet, "/api/v4/projects/OWNER/REPO/scripts/google_cloud/create_wlif?google_cloud_project_id=my_gcp_project",
httpmock.NewStringResponse(http.StatusOK, `#!/bin/bash
echo "success from script"`))
cli := `"OWNER/REPO" --google-cloud-project-id "my_gcp_project"`
_, err := runCommand(fakeHTTP, false, cli)
if err != nil {
return
}
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
_, _ = io.Copy(&buf, r)
outC <- buf.String()
}()
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
assert.Contains(t, out, "success from script")
}

View File

@ -16,6 +16,7 @@ import (
"gitlab.com/gitlab-org/cli/commands/cmdutils"
completionCmd "gitlab.com/gitlab-org/cli/commands/completion"
configCmd "gitlab.com/gitlab-org/cli/commands/config"
googleCloudCmd "gitlab.com/gitlab-org/cli/commands/google_cloud"
"gitlab.com/gitlab-org/cli/commands/help"
incidentCmd "gitlab.com/gitlab-org/cli/commands/incident"
issueCmd "gitlab.com/gitlab-org/cli/commands/issue"
@ -112,6 +113,7 @@ func NewCmdRoot(f *cmdutils.Factory, version, buildDate string) *cobra.Command {
rootCmd.AddCommand(changelogCmd.NewCmdChangelog(f))
rootCmd.AddCommand(clusterCmd.NewCmdCluster(f))
rootCmd.AddCommand(googleCloudCmd.NewCmdGoogleCloud(f))
rootCmd.AddCommand(issueCmd.NewCmdIssue(f))
rootCmd.AddCommand(incidentCmd.NewCmdIncident(f))
rootCmd.AddCommand(labelCmd.NewCmdLabel(f))

View File

@ -0,0 +1,46 @@
---
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
<!--
This documentation is auto generated by a script.
Please do not edit this file directly. Run `make gen-docs` instead.
-->
# `glab google-cloud create-wlif`
EXPERIMENTAL: Create a new Workload Identity Federation on Google Cloud
```plaintext
glab google-cloud create-wlif [project] [flags]
```
## Examples
```plaintext
$ glab google-cloud create-wlif project-id \
--google-cloud-project-id=google-cloud-project-id \
--google-cloud-workload-identity-pool-id=pool-id \
--google-cloud-workload-identity-pool-display-name=pool-display-name \
--google-cloud-workload-identity-pool-provider-id=provider-id \
--google-cloud-workload-identity-pool-provider-display-name=provider-display-name
```
## Options
```plaintext
--google-cloud-project-id string Google Cloud Project ID for the Workload Identity Federation
--google-cloud-workload-identity-pool-display-name string display name of the Google Cloud Workload Identity Pool to be created
--google-cloud-workload-identity-pool-id string ID of the Google Cloud Workload Identity Pool to be created
--google-cloud-workload-identity-pool-provider-display-name string display name of the Google Cloud Workload Identity Pool Provider to be created
--google-cloud-workload-identity-pool-provider-id string ID of the Google Cloud Workload Identity Pool Provider to be created
```
## Options inherited from parent commands
```plaintext
--help Show help for command
```

View File

@ -0,0 +1,24 @@
---
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
<!--
This documentation is auto generated by a script.
Please do not edit this file directly. Run `make gen-docs` instead.
-->
# `glab google-cloud help`
Help about any command
```plaintext
glab google-cloud help [command] [flags]
```
## Options inherited from parent commands
```plaintext
--help Show help for command
```

View File

@ -0,0 +1,24 @@
---
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
<!--
This documentation is auto generated by a script.
Please do not edit this file directly. Run `make gen-docs` instead.
-->
# `glab google-cloud`
EXPERIMENTAL: Manage Google Cloud integration of a GitLab project
## Options inherited from parent commands
```plaintext
--help Show help for command
```
## Subcommands
- [`create-wlif`](create-wlif.md)