Skip to content

Commit

Permalink
Update WIF scripting logic
Browse files Browse the repository at this point in the history
  • Loading branch information
JakobGray committed Sep 23, 2024
1 parent a077ebb commit 209d01a
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 109 deletions.
26 changes: 4 additions & 22 deletions cmd/ocm/gcp/create-wif-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"strconv"

"github.com/openshift-online/ocm-cli/pkg/gcp"
Expand Down Expand Up @@ -65,26 +63,10 @@ func validationForCreateWorkloadIdentityConfigurationCmd(cmd *cobra.Command, arg
return fmt.Errorf("Project is required")
}

if CreateWifConfigOpts.TargetDir == "" {
pwd, err := os.Getwd()
if err != nil {
return errors.Wrapf(err, "failed to get current directory")
}

CreateWifConfigOpts.TargetDir = pwd
}

fPath, err := filepath.Abs(CreateWifConfigOpts.TargetDir)
var err error
CreateWifConfigOpts.TargetDir, err = getPathFromFlag(CreateWifConfigOpts.TargetDir)
if err != nil {
return errors.Wrapf(err, "failed to resolve full path")
}

sResult, err := os.Stat(fPath)
if os.IsNotExist(err) {
return fmt.Errorf("directory %s does not exist", fPath)
}
if !sResult.IsDir() {
return fmt.Errorf("file %s exists and is not a directory", fPath)
return err
}
return nil
}
Expand Down Expand Up @@ -116,7 +98,7 @@ func createWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) e
if err != nil {
return errors.Wrapf(err, "failed to get project number from id")
}
err = createScript(CreateWifConfigOpts.TargetDir, wifConfig, projectNum)
err = createCreateScript(CreateWifConfigOpts.TargetDir, wifConfig, projectNum)
if err != nil {
return errors.Wrapf(err, "Failed to create script files")
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/ocm/gcp/delete-wif-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ func NewDeleteWorkloadIdentityConfiguration() *cobra.Command {
}

func validationForDeleteWorkloadIdentityConfigurationCmd(cmd *cobra.Command, argv []string) error {
var err error
DeleteWifConfigOpts.TargetDir, err = getPathFromFlag(DeleteWifConfigOpts.TargetDir)
if err != nil {
return err
}
return nil
}

Expand Down
1 change: 0 additions & 1 deletion cmd/ocm/gcp/gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ func NewGcpCmd() *cobra.Command {
gcpCmd.AddCommand(NewGetCmd())
gcpCmd.AddCommand(NewListCmd())
gcpCmd.AddCommand(NewDescribeCmd())
gcpCmd.AddCommand(NewGenerateCommand())

return gcpCmd
}
Expand Down
72 changes: 0 additions & 72 deletions cmd/ocm/gcp/generate-wif-script.go

This file was deleted.

30 changes: 30 additions & 0 deletions cmd/ocm/gcp/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package gcp

import (
"fmt"
"os"
"path/filepath"

cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
"github.com/pkg/errors"
)

// Checks for WIF config name or id in input
Expand Down Expand Up @@ -45,3 +48,30 @@ func findWifConfig(client *cmv1.Client, key string) (*cmv1.WifConfig, error) {
}
return response.Items().Slice()[0], nil
}

// getPathFromFlag validates the filepath
func getPathFromFlag(targetDir string) (string, error) {
if targetDir == "" {
pwd, err := os.Getwd()
if err != nil {
return "", errors.Wrapf(err, "failed to get current directory")
}

return pwd, nil
}

fPath, err := filepath.Abs(targetDir)
if err != nil {
return "", errors.Wrapf(err, "failed to resolve full path")
}

sResult, err := os.Stat(fPath)
if os.IsNotExist(err) {
return "", fmt.Errorf("directory %s does not exist", fPath)
}
if !sResult.IsDir() {
return "", fmt.Errorf("file %s exists and is not a directory", fPath)
}

return targetDir, nil
}
128 changes: 119 additions & 9 deletions cmd/ocm/gcp/scripting.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,26 @@ import (
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
)

func createScript(targetDir string, wifConfig *cmv1.WifConfig, projectNum int64) error {
func createCreateScript(targetDir string, wifConfig *cmv1.WifConfig, projectNum int64) error {
// Write the script content to the path
scriptContent := generateScriptContent(wifConfig, projectNum)
err := os.WriteFile(filepath.Join(targetDir, "script.sh"), []byte(scriptContent), 0600)
scriptContent := generateCreateScriptContent(wifConfig, projectNum)
err := os.WriteFile(filepath.Join(targetDir, "create.sh"), []byte(scriptContent), 0600)
if err != nil {
return err
}
// Write jwk json file to the path
jwkPath := filepath.Join(targetDir, "jwk.json")
err = os.WriteFile(jwkPath, []byte(wifConfig.Gcp().WorkloadIdentityPool().IdentityProvider().Jwks()), 0600)
if err != nil {
return err
}
return nil
}

func createUpdateScript(targetDir string, wifConfig *cmv1.WifConfig, projectNum int64) error {
// Write the script content to the path
scriptContent := generateUpdateScriptContent(wifConfig, projectNum)
err := os.WriteFile(filepath.Join(targetDir, "apply.sh"), []byte(scriptContent), 0600)
if err != nil {
return err
}
Expand Down Expand Up @@ -67,7 +83,7 @@ gcloud iam workload-identity-pools delete %s --project=%s --location=global
`, pool.PoolId(), wifConfig.Gcp().ProjectId())
}

func generateScriptContent(wifConfig *cmv1.WifConfig, projectNum int64) string {
func generateCreateScriptContent(wifConfig *cmv1.WifConfig, projectNum int64) string {
scriptContent := "#!/bin/bash\n"

// Create a script to create the workload identity pool
Expand All @@ -84,6 +100,23 @@ func generateScriptContent(wifConfig *cmv1.WifConfig, projectNum int64) string {
return scriptContent
}

func generateUpdateScriptContent(wifConfig *cmv1.WifConfig, projectNum int64) string {
scriptContent := "#!/bin/bash\n"

// Create a script to create the workload identity pool
scriptContent += createIdentityPoolScriptContent(wifConfig)

// Append the script to create the identity provider
scriptContent += createIdentityProviderScriptContent(wifConfig)

// Append the script to create/update the service accounts
scriptContent += updateServiceAccountScriptContent(wifConfig, projectNum)

scriptContent += grantSupportAccessScriptContent(wifConfig)

return scriptContent
}

func createIdentityPoolScriptContent(wifConfig *cmv1.WifConfig) string {
name := wifConfig.Gcp().WorkloadIdentityPool().PoolId()
project := wifConfig.Gcp().ProjectId()
Expand Down Expand Up @@ -125,6 +158,44 @@ func createServiceAccountScriptContent(wifConfig *cmv1.WifConfig, projectNum int
var sb strings.Builder

sb.WriteString("\n# Create service accounts:\n")
sb.WriteString(createServiceAccountScript(wifConfig))

sb.WriteString("\n# Create custom roles for service accounts:\n")
sb.WriteString(createCustomRoleScript(wifConfig))

sb.WriteString("\n# Bind roles to service accounts:\n")
sb.WriteString(addRoleBindingsScript(wifConfig))

sb.WriteString("\n# Grant access to service accounts:\n")
sb.WriteString(grantServiceAccountAccessScript(wifConfig, projectNum))

return sb.String()
}

func updateServiceAccountScriptContent(wifConfig *cmv1.WifConfig, projectNum int64) string {
// For each service account, create a service account and bind it to the workload identity pool
var sb strings.Builder

sb.WriteString("\n# Create service accounts:\n")
sb.WriteString(createServiceAccountScript(wifConfig))

sb.WriteString("\n# Create custom roles for service accounts:\n")
sb.WriteString(createCustomRoleScript(wifConfig))

sb.WriteString("\n# Update custom roles for service accounts:\n")
sb.WriteString(updateCustomRolesScript(wifConfig))

sb.WriteString("\n# Bind roles to service accounts:\n")
sb.WriteString(addRoleBindingsScript(wifConfig))

sb.WriteString("\n# Grant access to service accounts:\n")
sb.WriteString(grantServiceAccountAccessScript(wifConfig, projectNum))

return sb.String()
}

func createServiceAccountScript(wifConfig *cmv1.WifConfig) string {
var sb strings.Builder
for _, sa := range wifConfig.Gcp().ServiceAccounts() {
project := wifConfig.Gcp().ProjectId()
serviceAccountID := sa.ServiceAccountId()
Expand All @@ -134,11 +205,15 @@ func createServiceAccountScriptContent(wifConfig *cmv1.WifConfig, projectNum int
sb.WriteString(fmt.Sprintf("gcloud iam service-accounts create %s --display-name=%s --description=\"%s\" --project=%s\n",
serviceAccountID, serviceAccountName, serviceAccountDesc, project))
}
sb.WriteString("\n# Create custom roles for service accounts:\n")
return sb.String()
}

func createCustomRoleScript(wifConfig *cmv1.WifConfig) string {
var sb strings.Builder
for _, sa := range wifConfig.Gcp().ServiceAccounts() {
for _, role := range sa.Roles() {
if !role.Predefined() {
roleId := strings.ReplaceAll(role.RoleId(), "-", "_")
roleId := role.RoleId()
project := wifConfig.Gcp().ProjectId()
permissions := strings.Join(role.Permissions(), ",")
roleName := roleId
Expand All @@ -149,7 +224,33 @@ func createServiceAccountScriptContent(wifConfig *cmv1.WifConfig, projectNum int
}
}
}
sb.WriteString("\n# Bind roles to service accounts:\n")
return sb.String()
}

func updateCustomRolesScript(wifConfig *cmv1.WifConfig) string {
var sb strings.Builder
for _, sa := range wifConfig.Gcp().ServiceAccounts() {
for _, role := range sa.Roles() {
if !role.Predefined() {
project := wifConfig.Gcp().ProjectId()
var roleResource string
if role.Predefined() {
roleResource = fmt.Sprintf("roles/%s", role.RoleId())
} else {
roleResource = fmt.Sprintf("projects/%s/roles/%s", project, role.RoleId())
}
permissions := strings.Join(role.Permissions(), ",")
//nolint:lll
sb.WriteString(fmt.Sprintf("gcloud iam roles update %s --project=%s--permissions=%s\n",
roleResource, project, permissions))
}
}
}
return sb.String()
}

func addRoleBindingsScript(wifConfig *cmv1.WifConfig) string {
var sb strings.Builder
for _, sa := range wifConfig.Gcp().ServiceAccounts() {
for _, role := range sa.Roles() {
project := wifConfig.Gcp().ProjectId()
Expand All @@ -164,7 +265,11 @@ func createServiceAccountScriptContent(wifConfig *cmv1.WifConfig, projectNum int
project, member, roleResource))
}
}
sb.WriteString("\n# Grant access to service accounts:\n")
return sb.String()
}

func grantServiceAccountAccessScript(wifConfig *cmv1.WifConfig, projectNum int64) string {
var sb strings.Builder
for _, sa := range wifConfig.Gcp().ServiceAccounts() {
if sa.AccessMethod() == "wif" {
project := wifConfig.Gcp().ProjectId()
Expand Down Expand Up @@ -198,13 +303,18 @@ func grantSupportAccessScriptContent(wifConfig *cmv1.WifConfig) string {
sb.WriteString("\n# Create custom roles for support:\n")
for _, role := range roles {
if !role.Predefined() {
roleId := strings.ReplaceAll(role.RoleId(), "-", "_")
roleId := role.RoleId()
permissions := strings.Join(role.Permissions(), ",")
roleName := roleId
roleDesc := roleDescription + " for WIF config " + wifConfig.DisplayName()
//nolint:lll
sb.WriteString(fmt.Sprintf("gcloud iam roles create %s --project=%s --title=%s --description=\"%s\" --stage=GA --permissions=%s\n",
roleId, project, roleName, roleDesc, permissions))

roleResource := fmt.Sprintf("projects/%s/roles/%s", project, roleId)
//nolint:lll
sb.WriteString(fmt.Sprintf("gcloud iam roles update %s --project=%s--permissions=%s\n",
roleResource, project, permissions))
}
}

Expand Down
Loading

0 comments on commit 209d01a

Please sign in to comment.