Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace wif models and client with sdk #643

Merged
merged 6 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
220 changes: 124 additions & 96 deletions cmd/ocm/gcp/create-wif-config.go

Large diffs are not rendered by default.

58 changes: 30 additions & 28 deletions cmd/ocm/gcp/delete-wif-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ package gcp
import (
"context"
"fmt"
"strings"

"log"

"github.com/googleapis/gax-go/v2/apierror"
"google.golang.org/grpc/codes"

alphaocm "github.com/openshift-online/ocm-cli/pkg/alpha_ocm"
"github.com/openshift-online/ocm-cli/pkg/gcp"
"github.com/openshift-online/ocm-cli/pkg/models"
"github.com/openshift-online/ocm-cli/pkg/ocm"
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
"github.com/pkg/errors"
"google.golang.org/api/googleapi"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -59,21 +58,23 @@ func deleteWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
log.Fatal("WIF config ID is required")
}

// Create clients
ocmClient, err := alphaocm.NewOcmClient()
// Create the client for the OCM API:
connection, err := ocm.NewConnection().Build()
if err != nil {
log.Fatalf("failed to create backend client: %v", err)
log.Fatal(err)
Copy link
Collaborator

@ckandag ckandag Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does the end user see when this happens ? error stack ?

Copy link
Collaborator

@ckandag ckandag Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we previously discussed bubbling up the errors to the caller and allow the top level "Run" function decide how to handle/display the error.

I dont see these kind of Fatal log msgs anywhere in the else in the ocm or rosa cli code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example error:

➜  go run ./cmd/ocm gcp delete wif-config 2crdacmjbo3jmdgfn4dq791a7nig04qg
2024/07/30 14:25:07 Not logged in, credentials aren't set, run the 'login' command
exit status 1

This is the top level Run function.

}
defer connection.Close()

wifConfig, err := ocmClient.GetWifConfig(wifConfigId)
response, err := connection.ClustersMgmt().V1().GCP().WifConfigs().WifConfig(wifConfigId).Get().Send()
if err != nil {
log.Fatal(err)
log.Fatalf("failed to get wif-config: %v", err)
}
wifConfig := response.Body()

if DeleteWifConfigOpts.DryRun {
log.Printf("Writing script files to %s", DeleteWifConfigOpts.TargetDir)

err := createDeleteScript(DeleteWifConfigOpts.TargetDir, &wifConfig)
err := createDeleteScript(DeleteWifConfigOpts.TargetDir, wifConfig)
if err != nil {
log.Fatalf("Failed to create script files: %s", err)
}
Expand All @@ -85,27 +86,30 @@ func deleteWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
log.Fatal(err)
}

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

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

err = ocmClient.DeleteWifConfig(wifConfigId)
_, err = connection.ClustersMgmt().V1().GCP().WifConfigs().
WifConfig(wifConfigId).
Delete().
Send()
if err != nil {
log.Fatal(err)
log.Fatalf("failed to delete wif config %q: %v", wifConfigId, err)
}
}

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

for _, serviceAccount := range wifConfig.Status.ServiceAccounts {
serviceAccountID := serviceAccount.Id
for _, serviceAccount := range wifConfig.Gcp().ServiceAccounts() {
serviceAccountID := serviceAccount.ServiceAccountId()
log.Println("Deleting service account", serviceAccountID)
err := gcpClient.DeleteServiceAccount(serviceAccountID, projectId, allowMissing)
if err != nil {
Expand All @@ -117,20 +121,18 @@ func deleteServiceAccounts(ctx context.Context, gcpClient gcp.GcpClient,
}

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

_, err := gcpClient.DeleteWorkloadIdentityPool(ctx, poolResource)
if err != nil {
pApiError, ok := err.(*apierror.APIError)
if ok {
if pApiError.GRPCStatus().Code() == codes.NotFound && allowMissing {
log.Printf("Workload identity pool %s not found", poolName)
return nil
}
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 &&
strings.Contains(gerr.Message, "Requested entity was not found") && allowMissing {
log.Printf("Workload identity pool %s not found", poolName)
return nil
}
return errors.Wrapf(err, "Failed to delete workload identity pool %s", poolName)
}
Expand Down
20 changes: 10 additions & 10 deletions cmd/ocm/gcp/describe-wif-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"os"
"text/tabwriter"

alphaocm "github.com/openshift-online/ocm-cli/pkg/alpha_ocm"
"github.com/openshift-online/ocm-cli/pkg/ocm"
"github.com/openshift-online/ocm-cli/pkg/urls"
"github.com/spf13/cobra"
)
Expand All @@ -30,25 +30,25 @@ func describeWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string)
}

// Create the client for the OCM API:
ocmClient, err := alphaocm.NewOcmClient()
connection, err := ocm.NewConnection().Build()
if err != nil {
log.Fatalf("failed to create backend client: %v", err)
log.Fatal(err)
}
defer connection.Close()

wifconfig, err := ocmClient.GetWifConfig(id)
response, err := connection.ClustersMgmt().V1().GCP().WifConfigs().WifConfig(id).Get().Send()
if err != nil {
log.Fatalf("failed to get wif-config: %v", err)
}
wifConfig := response.Body()

// 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)
fmt.Fprintf(w, "ID:\t%s\n", wifConfig.ID())
fmt.Fprintf(w, "Display Name:\t%s\n", wifConfig.DisplayName())
fmt.Fprintf(w, "Project:\t%s\n", wifConfig.Gcp().ProjectId())
fmt.Fprintf(w, "Issuer URL:\t%s\n", wifConfig.Gcp().WorkloadIdentityPool().IdentityProvider().IssuerUrl())

w.Flush()
}
Expand Down
29 changes: 22 additions & 7 deletions cmd/ocm/gcp/generate-wif-script.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package gcp

import (
"context"
"log"

alphaocm "github.com/openshift-online/ocm-cli/pkg/alpha_ocm"
"github.com/openshift-online/ocm-cli/pkg/gcp"
"github.com/openshift-online/ocm-cli/pkg/ocm"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -39,27 +41,40 @@ func validationForGenerateCreateScriptCmd(cmd *cobra.Command, argv []string) {
}

func generateCreateScriptCmd(cmd *cobra.Command, argv []string) {
// Create the client for the OCM API:
ocmClient, err := alphaocm.NewOcmClient()
ctx := context.Background()

gcpClient, err := gcp.NewGcpClient(ctx)
if err != nil {
log.Fatalf("failed to initiate GCP client: %v", err)
}

connection, err := ocm.NewConnection().Build()
if err != nil {
log.Fatalf("failed to create backend client: %v", err)
log.Fatal(err)
}
defer connection.Close()

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

wifConfig, err := ocmClient.GetWifConfig(wifConfigId)
response, err := connection.ClustersMgmt().V1().GCP().WifConfigs().WifConfig(wifConfigId).Get().Send()
if err != nil {
log.Fatalf("failed to get wif-config: %v", err)
}
wifConfig := response.Body()

projectNum, err := gcpClient.ProjectNumberFromId(wifConfig.Gcp().ProjectId())
if err != nil {
log.Fatalf("failed to get project number from id: %v", err)
}

log.Printf("Writing script files to %s", GenerateScriptOpts.TargetDir)
if err := createScript(GenerateScriptOpts.TargetDir, &wifConfig); err != nil {
if err := createScript(GenerateScriptOpts.TargetDir, wifConfig, projectNum); err != nil {
log.Fatalf("failed to generate create script: %v", err)
}
if err := createDeleteScript(GenerateScriptOpts.TargetDir, &wifConfig); err != nil {
if err := createDeleteScript(GenerateScriptOpts.TargetDir, wifConfig); err != nil {
log.Fatalf("failed to generate delete script: %v", err)
}
}
26 changes: 14 additions & 12 deletions cmd/ocm/gcp/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ package gcp
import (
"context"
"fmt"
"log"

"cloud.google.com/go/iam/admin/apiv1/adminpb"
"github.com/openshift-online/ocm-cli/pkg/gcp"

cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v1"
)

// EnsurePolicyBindingsForProject ensures that given roles and member, appropriate binding is added to project
// EnsurePolicyBindingsForProject ensures that given roles and member, appropriate binding is added to project.
// Roles should be in the format projects/{project}/roles/{role_id} for custom roles and roles/{role_id}
// for predefined roles.
func EnsurePolicyBindingsForProject(gcpClient gcp.GcpClient, roles []string, member string, projectName string) error {
needPolicyUpdate := false

Expand Down Expand Up @@ -88,44 +89,45 @@ func setProjectIamPolicy(gcpClient gcp.GcpClient, policy *cloudresourcemanager.P

/* Custom Role Creation */

// GetRole fetches the role created to satisfy a credentials request
func GetRole(gcpClient gcp.GcpClient, roleID, projectName string) (*adminpb.Role, error) {
log.Printf("role id %v", roleID)
// GetRole fetches the role created to satisfy a credentials request.
// Custom roles should follow the format projects/{project}/roles/{role_id}.
func GetRole(gcpClient gcp.GcpClient, roleName string) (*adminpb.Role, error) {
role, err := gcpClient.GetRole(context.TODO(), &adminpb.GetRoleRequest{
Name: fmt.Sprintf("projects/%s/roles/%s", projectName, roleID),
Name: roleName,
})
return role, err
}

// CreateRole creates a new role given permissions
func CreateRole(gcpClient gcp.GcpClient, permissions []string, roleName, roleID, roleDescription,
func CreateRole(gcpClient gcp.GcpClient, permissions []string, roleTitle, roleId, roleDescription,
projectName string) (*adminpb.Role, error) {
role, err := gcpClient.CreateRole(context.TODO(), &adminpb.CreateRoleRequest{
Role: &adminpb.Role{
Title: roleName,
Title: roleTitle,
Description: roleDescription,
IncludedPermissions: permissions,
Stage: adminpb.Role_GA,
},
Parent: fmt.Sprintf("projects/%s", projectName),
RoleId: roleID,
RoleId: roleId,
})
if err != nil {
return nil, err
}
return role, nil
}

// UpdateRole updates an existing role given permissions
// UpdateRole updates an existing role given permissions.
// Custom roles should follow the format projects/{project}/roles/{role_id}.
func UpdateRole(gcpClient gcp.GcpClient, role *adminpb.Role, roleName string) (*adminpb.Role, error) {
role, err := gcpClient.UpdateRole(context.TODO(), &adminpb.UpdateRoleRequest{
updated, err := gcpClient.UpdateRole(context.TODO(), &adminpb.UpdateRoleRequest{
Name: roleName,
Role: role,
})
if err != nil {
return nil, err
}
return role, nil
return updated, nil
}

// DeleteRole deletes the role created to satisfy a credentials request
Expand Down
48 changes: 32 additions & 16 deletions cmd/ocm/gcp/list-wif-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import (
"log"
"os"

alphaocm "github.com/openshift-online/ocm-cli/pkg/alpha_ocm"
"github.com/openshift-online/ocm-cli/pkg/config"
"github.com/openshift-online/ocm-cli/pkg/ocm"
"github.com/openshift-online/ocm-cli/pkg/output"
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
"github.com/spf13/cobra"
)

Expand All @@ -30,7 +31,7 @@ func NewListWorkloadIdentityConfiguration() *cobra.Command {
fs.StringVar(
&ListWorkloadIdentityConfigurationOpts.columns,
"columns",
"metadata.id, metadata.displayName, status.state",
"id, display_name",
"Specify which columns to display separated by commas, path is based on wif-config struct",
)
fs.BoolVar(
Expand Down Expand Up @@ -58,10 +59,11 @@ func listWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
}

// Create the client for the OCM API:
ocmClient, err := alphaocm.NewOcmClient()
connection, err := ocm.NewConnection().Build()
if err != nil {
log.Fatalf("failed to create backend client: %v", err)
log.Fatal(err)
}
defer connection.Close()

// Create the output printer:
printer, err := output.NewPrinter().
Expand All @@ -73,12 +75,6 @@ func listWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
}
defer printer.Close()

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

// Create the output table:
table, err := printer.NewTable().
Name("wifconfigs").
Expand All @@ -94,14 +90,34 @@ func listWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) {
table.WriteHeaders()
}

// Write the rows:
for _, wc := range wifconfigs {
err = table.WriteObject(wc)
// Create the request
request := connection.ClustersMgmt().V1().GCP().WifConfigs().List()

size := 100
index := 1
for {
// Fetch the next page:
request.Size(size)
request.Page(index)
response, err := request.Send()
if err != nil {
log.Fatalf("Can't retrieve wif configs: %v", err)
}

// Display the items of the fetched page:
response.Items().Each(func(wc *cmv1.WifConfig) bool {
err = table.WriteObject(wc)
return err == nil
})
if err != nil {
log.Fatal(err)
}

// If the number of fetched items is less than requested, then this was the last
// page, otherwise process the next one:
if response.Size() < size {
break
}
}
if err != nil {
log.Fatal(err)
index++
}
}
Loading
Loading