diff --git a/go.mod b/go.mod index 2b605830a3..06ca2d2361 100644 --- a/go.mod +++ b/go.mod @@ -108,6 +108,7 @@ require ( golang.org/x/sync v0.8.0 golang.org/x/sys v0.26.0 golang.org/x/term v0.25.0 + golang.org/x/text v0.19.0 google.golang.org/api v0.189.0 google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d google.golang.org/grpc v1.65.0 @@ -279,7 +280,6 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.30.0 // indirect - golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect diff --git a/pkg/asset/installconfig/aws/permissions.go b/pkg/asset/installconfig/aws/permissions.go index 0274a7010c..f3e47e7f11 100644 --- a/pkg/asset/installconfig/aws/permissions.go +++ b/pkg/asset/installconfig/aws/permissions.go @@ -493,9 +493,9 @@ func RequiredPermissionGroups(ic *types.InstallConfig) []PermissionGroup { func PermissionsList(required []PermissionGroup) ([]string, error) { requiredPermissions := sets.New[string]() for _, group := range required { - groupPerms, ok := permissions[group] - if !ok { - return nil, fmt.Errorf("unable to access permissions group %s", group) + groupPerms, err := Permissions(group) + if err != nil { + return nil, err } requiredPermissions.Insert(groupPerms...) } @@ -503,6 +503,15 @@ func PermissionsList(required []PermissionGroup) ([]string, error) { return sets.List(requiredPermissions), nil } +// Permissions returns the list of permissions associated with `group`. +func Permissions(group PermissionGroup) ([]string, error) { + groupPerms, ok := permissions[group] + if !ok { + return nil, fmt.Errorf("unable to access permissions group %s", group) + } + return groupPerms, nil +} + // includesExistingInstanceRole checks if at least one BYO instance role is included in the install-config. func includesExistingInstanceRole(installConfig *types.InstallConfig) bool { mpool := aws.MachinePool{} diff --git a/pkg/asset/permissions/permissions.go b/pkg/asset/permissions/permissions.go index f34f5b7bf9..4ed3983a2a 100644 --- a/pkg/asset/permissions/permissions.go +++ b/pkg/asset/permissions/permissions.go @@ -4,7 +4,10 @@ import ( "context" "encoding/json" "fmt" + "strings" + "golang.org/x/text/cases" + "golang.org/x/text/language" iamv1 "sigs.k8s.io/cluster-api-provider-aws/v2/iam/api/v1beta1" "github.com/openshift/installer/pkg/asset" @@ -66,21 +69,27 @@ func (o *Permissions) Generate(ctx context.Context, dependencies asset.Parents) } func (o *Permissions) writePolicy(groups []awsconfig.PermissionGroup, filename string) error { - perms, err := awsconfig.PermissionsList(groups) - if err != nil { - return fmt.Errorf("failed to generate permissions list: %w", err) + policy := iamv1.PolicyDocument{ + Version: "2012-10-17", + Statement: []iamv1.StatementEntry{}, } - policy := iamv1.PolicyDocument{ - Version: "2012-10-17", - Statement: []iamv1.StatementEntry{ - { - Effect: "Allow", - Action: perms, - Resource: iamv1.Resources{"*"}, - }, - }, + caser := cases.Title(language.English) + for _, group := range groups { + groupPerms, err := awsconfig.Permissions(group) + if err != nil { + return err + } + // Sid must be alphanumeric + sid := strings.ReplaceAll(caser.String(string(group)), "-", "") + policy.Statement = append(policy.Statement, iamv1.StatementEntry{ + Effect: "Allow", + Action: groupPerms, + Resource: iamv1.Resources{"*"}, + Sid: sid, + }) } + policyBytes, err := json.Marshal(policy) if err != nil { return fmt.Errorf("failed to marshal permissions policy: %w", err)