Skip to content

Commit

Permalink
GCP wif commands
Browse files Browse the repository at this point in the history
  • Loading branch information
JakobGray committed May 28, 2024
1 parent 119e9d2 commit 5be0937
Show file tree
Hide file tree
Showing 26 changed files with 1,960 additions and 40 deletions.
515 changes: 515 additions & 0 deletions cmd/ocm/gcp/create-wif-config.go

Large diffs are not rendered by default.

115 changes: 115 additions & 0 deletions cmd/ocm/gcp/delete-wif-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package gcp

import (
"context"
"fmt"

"log"

"github.com/openshift-online/ocm-cli/cmd/ocm/gcp/mock"
"github.com/openshift-online/ocm-cli/cmd/ocm/gcp/models"
"github.com/openshift-online/ocm-cli/pkg/gcp"
"github.com/pkg/errors"

"github.com/spf13/cobra"
)

var (
// DeleteWorkloadIdentityConfigurationOpts captures the options that affect creation of the workload identity pool
DeleteWorkloadIdentityConfigurationOpts = options{
Name: "",
Project: "",
TargetDir: "",
}
)

// NewCreateWorkloadIdentityConfiguration provides the "create-wif-config" subcommand
func NewDeleteWorkloadIdentityConfiguration() *cobra.Command {
deleteWorkloadIdentityPoolCmd := &cobra.Command{
Use: "delete-wif-config [ID]",
Short: "Delete workload identity configuration",
Run: deleteWorkloadIdentityConfigurationCmd,
PersistentPreRun: validationForDeleteWorkloadIdentityConfigurationCmd,
}

return deleteWorkloadIdentityPoolCmd
}

func validationForDeleteWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
if len(argv) != 1 {
log.Fatal(
"Expected exactly one command line parameters containing the id " +
"of the WIF config.",
)
}
}

func deleteWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
ctx := context.Background()
fmt.Println("Deleting wif-config...")

wifConfigId := argv[0]
if wifConfigId == "" {
log.Fatal("WIF config ID is required")
}

wifConfig := getWifConfig(wifConfigId)

gcpClient, err := gcp.NewGcpClient(context.Background())
if err != nil {
log.Fatal(err)
}

if err := deleteServiceAccounts(ctx, gcpClient, wifConfig); err != nil {
log.Fatal(err)
}

if err := deleteWorkloadIdentityPool(ctx, gcpClient, wifConfig); err != nil {
log.Fatal(err)
}

err = deleteWifConfig(wifConfig)
if err != nil {
log.Fatal(err)
}
}

func deleteWifConfig(wifConfig *models.WifConfigOutput) error {
fmt.Println("Deleting WIF config", wifConfig.Spec.DisplayName)
return nil
}

func getWifConfig(wifConfigId string) *models.WifConfigOutput {
return mock.MockWifConfig("test01", wifConfigId)
}

func deleteServiceAccounts(ctx context.Context, gcpClient gcp.GcpClient, wifConfig *models.WifConfigOutput) error {
log.Println("Deleting service accounts...")
projectId := wifConfig.Spec.ProjectId

for _, serviceAccount := range wifConfig.Status.ServiceAccounts {
serviceAccountID := generateServiceAccountID(serviceAccount)
log.Println("Deleting service account", serviceAccountID)
err := gcpClient.DeleteServiceAccount(serviceAccountID, projectId, true)
if err != nil {
panic(err)
}
}

return nil
}

func deleteWorkloadIdentityPool(ctx context.Context, gcpClient gcp.GcpClient, wifConfig *models.WifConfigOutput) error {
log.Println("Deleting workload identity pool...")
projectId := wifConfig.Spec.ProjectId
poolName := wifConfig.Status.WorkloadIdentityPoolData.PoolId
poolResource := fmt.Sprintf("projects/%s/locations/global/workloadIdentityPools/%s", projectId, poolName)

_, err := gcpClient.DeleteWorkloadIdentityPool(ctx, poolResource)
if err != nil {
return errors.Wrapf(err, "Failed to delete workload identity pool %s", poolName)
}

log.Printf("Workload identity pool %s deleted", poolName)
return nil
}
55 changes: 55 additions & 0 deletions cmd/ocm/gcp/describe-wif-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package gcp

import (
"fmt"
"log"
"os"
"text/tabwriter"

"github.com/openshift-online/ocm-cli/cmd/ocm/gcp/mock"

"github.com/openshift-online/ocm-cli/pkg/urls"
"github.com/spf13/cobra"
)

// NewDescribeWorkloadIdentityConfiguration provides the "describe-wif-config" subcommand
func NewDescribeWorkloadIdentityConfiguration() *cobra.Command {
describeWorkloadIdentityPoolCmd := &cobra.Command{
Use: "describe-wif-config [ID]",
Short: "Show details of a wif-config.",
Run: describeWorkloadIdentityConfigurationCmd,
PersistentPreRun: validationForDescribeWorkloadIdentityConfigurationCmd,
}

return describeWorkloadIdentityPoolCmd
}

func describeWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
id, err := urls.Expand(argv)
if err != nil {
log.Fatalf("could not create URI: %v", err)
}

if id != "test01" {
log.Fatalf("failed to find WIF Config with id: %s", id)
}
wifconfig := mock.MockWifConfig("test01", id)

// Print output
w := tabwriter.NewWriter(os.Stdout, 8, 0, 2, ' ', 0)

fmt.Fprintf(w, "ID:\t%s\n", wifconfig.Metadata.Id)
fmt.Fprintf(w, "Display Name:\t%s\n", wifconfig.Metadata.DisplayName)
fmt.Fprintf(w, "Project:\t%s\n", wifconfig.Spec.ProjectId)
fmt.Fprintf(w, "State:\t%s\n", wifconfig.Status.State)
fmt.Fprintf(w, "Summary:\t%s\n", wifconfig.Status.Summary)
fmt.Fprintf(w, "Issuer URL:\t%s\n", wifconfig.Status.WorkloadIdentityPoolData.IssuerUrl)

w.Flush()
}

func validationForDescribeWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
if len(argv) != 1 {
log.Fatalf("Expected exactly one command line parameters containing the id of the WIF config.")
}
}
34 changes: 34 additions & 0 deletions cmd/ocm/gcp/gcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package gcp

import (
"github.com/spf13/cobra"
)

type options struct {
TargetDir string
Region string
Name string
Project string
WorkloadIdentityPool string
WorkloadIdentityProvider string
DryRun bool
}

// NewGCPCmd implements the "gcp" subcommand for the credentials provisioning
func NewGCPCmd() *cobra.Command {
gcpCmd := &cobra.Command{
Use: "gcp COMMAND",
Short: "Perform actions related to GCP WIF",
Long: "Manage GCP Workload Identity Federation (WIF) resources.",
Args: cobra.MinimumNArgs(1),
}

gcpCmd.AddCommand(NewCreateWorkloadIdentityConfiguration())
gcpCmd.AddCommand(NewUpdateWorkloadIdentityConfiguration())
gcpCmd.AddCommand(NewDeleteWorkloadIdentityConfiguration())
gcpCmd.AddCommand(NewGetWorkloadIdentityConfiguration())
gcpCmd.AddCommand(NewListWorkloadIdentityConfiguration())
gcpCmd.AddCommand(NewDescribeWorkloadIdentityConfiguration())

return gcpCmd
}
70 changes: 70 additions & 0 deletions cmd/ocm/gcp/get-wif-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package gcp

import (
"encoding/json"
"log"
"os"

"github.com/openshift-online/ocm-cli/cmd/ocm/gcp/mock"

"github.com/openshift-online/ocm-cli/pkg/arguments"
"github.com/openshift-online/ocm-cli/pkg/dump"
"github.com/openshift-online/ocm-cli/pkg/urls"
"github.com/spf13/cobra"
)

var GetWorkloadIdentityConfigurationOpts struct {
parameter []string
header []string
single bool
}

// NewCreateWorkloadIdentityConfiguration provides the "create-wif-config" subcommand
func NewGetWorkloadIdentityConfiguration() *cobra.Command {
getWorkloadIdentityPoolCmd := &cobra.Command{
Use: "get-wif-config [ID]",
Short: "Send a GET request for wif-config.",
Run: getWorkloadIdentityConfigurationCmd,
PersistentPreRun: validationForGetWorkloadIdentityConfigurationCmd,
}

fs := getWorkloadIdentityPoolCmd.Flags()
arguments.AddParameterFlag(fs, &GetWorkloadIdentityConfigurationOpts.parameter)
arguments.AddHeaderFlag(fs, &GetWorkloadIdentityConfigurationOpts.header)
fs.BoolVar(
&GetWorkloadIdentityConfigurationOpts.single,
"single",
false,
"Return the output as a single line.",
)

return getWorkloadIdentityPoolCmd
}

func getWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
path, err := urls.Expand(argv)
if err != nil {
log.Fatalf("could not create URI: %v", err)
}

wifconfig := mock.MockWifConfig("test01", path)
body, err := json.Marshal(wifconfig)
if err != nil {
log.Fatalf("failed to marshal wifconfig: %v", err)
}

if GetWorkloadIdentityConfigurationOpts.single {
err = dump.Single(os.Stdout, body)
} else {
err = dump.Pretty(os.Stdout, body)
}
if err != nil {
log.Fatalf("can't print body: %v", err)
}
}

func validationForGetWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
if len(argv) != 1 {
log.Fatalf("Expected exactly one command line parameters containing the id of the WIF config.")
}
}
115 changes: 115 additions & 0 deletions cmd/ocm/gcp/list-wif-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package gcp

import (
"context"
"log"
"os"

"github.com/openshift-online/ocm-cli/cmd/ocm/gcp/mock"
"github.com/openshift-online/ocm-cli/cmd/ocm/gcp/models"
"github.com/openshift-online/ocm-cli/pkg/config"
"github.com/openshift-online/ocm-cli/pkg/ocm"
"github.com/openshift-online/ocm-cli/pkg/output"
"github.com/spf13/cobra"
)

var ListWorkloadIdentityConfigurationOpts struct {
columns string
noHeaders bool
}

// NewCreateWorkloadIdentityConfiguration provides the "create-wif-config" subcommand
func NewListWorkloadIdentityConfiguration() *cobra.Command {
listWorkloadIdentityPoolCmd := &cobra.Command{
Use: "list-wif-config [ID]",
Short: "List wif-configs.",
Run: listWorkloadIdentityConfigurationCmd,
PersistentPreRun: validationForListWorkloadIdentityConfigurationCmd,
}

fs := listWorkloadIdentityPoolCmd.Flags()
fs.StringVar(
&ListWorkloadIdentityConfigurationOpts.columns,
"columns",
"metadata.id, metadata.displayName, status.state",
"Specify which columns to display separated by commas, path is based on wif-config struct",
)
fs.BoolVar(
&ListWorkloadIdentityConfigurationOpts.noHeaders,
"no-headers",
false,
"Don't print header row",
)

return listWorkloadIdentityPoolCmd
}

func validationForListWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
// No validation needed
}

func listWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
// Create a context:
ctx := context.Background()

// Load the configuration:
cfg, err := config.Load()
if err != nil {
log.Fatal(err)
}

// Create the client for the OCM API:
connection, err := ocm.NewConnection().Build()
if err != nil {
log.Fatal(err)
}
defer connection.Close()

// Create the output printer:
printer, err := output.NewPrinter().
Writer(os.Stdout).
Pager(cfg.Pager).
Build(ctx)
if err != nil {
log.Fatal(err)
}
defer printer.Close()

wifconfigs, err := getMockWifConfigs()
if err != nil {
log.Fatalf("failed to get wif-configs: %v", err)
}

// Create the output table:
table, err := printer.NewTable().
Name("wifconfigs").
Columns(ListWorkloadIdentityConfigurationOpts.columns).
Build(ctx)
if err != nil {
log.Fatal(err)
}
defer table.Close()

// Unless noHeaders set, print header row:
if !ListWorkloadIdentityConfigurationOpts.noHeaders {
table.WriteHeaders()
}

// Write the rows:
for _, wc := range wifconfigs {
err = table.WriteObject(wc)
if err != nil {
break
}
}
if err != nil {
log.Fatal(err)
}
}

func getMockWifConfigs() ([]models.WifConfigOutput, error) {
return []models.WifConfigOutput{
*mock.MockWifConfig("test01", "0001"),
*mock.MockWifConfig("test02", "0002"),
}, nil
}
Loading

0 comments on commit 5be0937

Please sign in to comment.