Skip to content

Commit

Permalink
OCM-8979 | test: Prepare shared VPC resources
Browse files Browse the repository at this point in the history
  • Loading branch information
jameszwang committed Jul 1, 2024
1 parent 35b747c commit 752d581
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 27 deletions.
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ go 1.21

require (
github.com/apparentlymart/go-cidr v1.1.0
github.com/aws/aws-sdk-go-v2 v1.26.1
github.com/aws/aws-sdk-go-v2 v1.30.0
github.com/aws/aws-sdk-go-v2/config v1.27.9
github.com/aws/aws-sdk-go-v2/credentials v1.17.9
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.48.0
github.com/aws/aws-sdk-go-v2/service/ec2 v1.152.0
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.24.3
github.com/aws/aws-sdk-go-v2/service/iam v1.27.1
github.com/aws/aws-sdk-go-v2/service/kms v1.30.0
github.com/aws/aws-sdk-go-v2/service/ram v1.26.1
github.com/aws/aws-sdk-go-v2/service/route53 v1.40.3
github.com/aws/aws-sdk-go-v2/service/sts v1.28.5
github.com/go-jose/go-jose/v4 v4.0.2
Expand All @@ -34,8 +35,8 @@ require (

require (
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.12 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.12 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.35.1
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect
Expand Down
14 changes: 8 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA=
github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
github.com/aws/aws-sdk-go-v2 v1.30.0 h1:6qAwtzlfcTtcL8NHtbDQAqgM5s6NDipQTkPxyH/6kAA=
github.com/aws/aws-sdk-go-v2 v1.30.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2/go.mod h1:lPprDr1e6cJdyYeGXnRaJoP4Md+cDBvi2eOj00BlGmg=
github.com/aws/aws-sdk-go-v2/config v1.27.9 h1:gRx/NwpNEFSk+yQlgmk1bmxxvQ5TyJ76CWXs9XScTqg=
Expand All @@ -10,10 +10,10 @@ github.com/aws/aws-sdk-go-v2/credentials v1.17.9 h1:N8s0/7yW+h8qR8WaRlPQeJ6czVMN
github.com/aws/aws-sdk-go-v2/credentials v1.17.9/go.mod h1:446YhIdmSV0Jf/SLafGZalQo+xr2iw7/fzXGDPTU1yQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0 h1:af5YzcLf80tv4Em4jWVD75lpnOHSBkPUZxZfGkrI3HI=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0/go.mod h1:nQ3how7DMnFMWiU1SpECohgC82fpn4cKZ875NDMmwtA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.12 h1:SJ04WXGTwnHlWIODtC5kJzKbeuHt+OUNOgKg7nfnUGw=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.12/go.mod h1:FkpvXhA92gb3GE9LD6Og0pHHycTxW7xGpnEh5E7Opwo=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.12 h1:hb5KgeYfObi5MHkSSZMEudnIvX30iB+E21evI4r6BnQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.12/go.mod h1:CroKe/eWJdyfy9Vx4rljP5wTUjNJfb+fPz1uMYUhEGM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.48.0 h1:uMlYsoHdd2Gr9sDGq2ieUR5jVu7F5AqPYz6UBJmdRhY=
Expand All @@ -32,6 +32,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 h1:b+E7zIUHM
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6/go.mod h1:S2fNV0rxrP78NhPbCZeQgY8H9jdDMeGtwcfZIRxzBqU=
github.com/aws/aws-sdk-go-v2/service/kms v1.30.0 h1:yS0JkEdV6h9JOo8sy2JSpjX+i7vsKifU8SIeHrqiDhU=
github.com/aws/aws-sdk-go-v2/service/kms v1.30.0/go.mod h1:+I8VUUSVD4p5ISQtzpgSva4I8cJ4SQ4b1dcBcof7O+g=
github.com/aws/aws-sdk-go-v2/service/ram v1.26.1 h1:1UcUsMsHB7ZnpcUYNwBTX90hFjIZrhf8Xu00R9Vo+Kg=
github.com/aws/aws-sdk-go-v2/service/ram v1.26.1/go.mod h1:e/3wE+afnOAeolpqyg8fKAQK/kKya+ycDW62/X4vjK8=
github.com/aws/aws-sdk-go-v2/service/route53 v1.40.3 h1:wr5gulbwbb8PSRMWjCROoP0TIMccpF8x5A7hEk2SjpA=
github.com/aws/aws-sdk-go-v2/service/route53 v1.40.3/go.mod h1:/Gyl9xjGcjIVe80ar75YlmA8m6oFh0A4XfLciBmdS8s=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 h1:mnbuWHOcM70/OFUlZZ5rcdfA8PflGXXiefU/O+1S3+8=
Expand Down
91 changes: 78 additions & 13 deletions pkg/aws/aws_client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/kms"
"github.com/aws/aws-sdk-go-v2/service/ram"
"github.com/aws/aws-sdk-go-v2/service/sts"

"github.com/openshift-online/ocm-common/pkg/log"
Expand All @@ -35,44 +36,71 @@ type AWSClient struct {
KmsClient *kms.Client
CloudWatchLogsClient *cloudwatchlogs.Client
AWSConfig *aws.Config
RamClient *ram.Client
}

type AccessKeyMod struct {
AccessKeyId string `ini:"aws_access_key_id,omitempty"`
SecretAccessKey string `ini:"aws_secret_access_key,omitempty"`
}

func CreateAWSClient(profileName string, region string) (*AWSClient, error) {
func CreateAWSClient(profileName string, region string, awsSharedCredentialFile ...string) (*AWSClient, error) {
var cfg aws.Config
var err error

if envCredential() {
log.LogInfo("Got AWS_ACCESS_KEY_ID env settings, going to build the config with the env")
if len(awsSharedCredentialFile) > 0 {
file := awsSharedCredentialFile[0]
log.LogInfo("Got aws shared credential file path: %s ", file)
cfg, err = config.LoadDefaultConfig(context.TODO(),
config.WithRegion(region),
config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(
os.Getenv("AWS_ACCESS_KEY_ID"),
os.Getenv("AWS_SECRET_ACCESS_KEY"),
"")),
config.WithSharedCredentialsFiles([]string{file}),
)
} else {
if envAwsProfile() {
file := os.Getenv("AWS_SHARED_CREDENTIALS_FILE")
log.LogInfo("Got file path: %s from env variable AWS_SHARED_CREDENTIALS_FILE\n", file)
if envCredential() {
log.LogInfo("Got AWS_ACCESS_KEY_ID env settings, going to build the config with the env")
cfg, err = config.LoadDefaultConfig(context.TODO(),
config.WithRegion(region),
config.WithSharedCredentialsFiles([]string{file}),
config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(
os.Getenv("AWS_ACCESS_KEY_ID"),
os.Getenv("AWS_SECRET_ACCESS_KEY"),
"")),
)
} else {
cfg, err = config.LoadDefaultConfig(context.TODO(),
config.WithRegion(region),
config.WithSharedConfigProfile(profileName),
)
}

}

//if envCredential() {
// log.LogInfo("Got AWS_ACCESS_KEY_ID env settings, going to build the config with the env")
// cfg, err = config.LoadDefaultConfig(context.TODO(),
// config.WithRegion(region),
// config.WithCredentialsProvider(
// credentials.NewStaticCredentialsProvider(
// os.Getenv("AWS_ACCESS_KEY_ID"),
// os.Getenv("AWS_SECRET_ACCESS_KEY"),
// "")),
// )
//} else {
// if envAwsProfile() {
// file := os.Getenv("AWS_SHARED_CREDENTIALS_FILE")
// log.LogInfo("Got file path: %s from env variable AWS_SHARED_CREDENTIALS_FILE\n", file)
// cfg, err = config.LoadDefaultConfig(context.TODO(),
// config.WithRegion(region),
// config.WithSharedCredentialsFiles([]string{file}),
// )
// } else {
// cfg, err = config.LoadDefaultConfig(context.TODO(),
// config.WithRegion(region),
// config.WithSharedConfigProfile(profileName),
// )
// }
//
//}

if err != nil {
return nil, err
}
Expand All @@ -88,6 +116,7 @@ func CreateAWSClient(profileName string, region string) (*AWSClient, error) {
ClientContext: context.TODO(),
KmsClient: kms.NewFromConfig(cfg),
AWSConfig: &cfg,
RamClient: ram.NewFromConfig(cfg),
}
awsClient.AccountID = awsClient.GetAWSAccountID()
return awsClient, nil
Expand Down Expand Up @@ -144,3 +173,39 @@ func GrantValidAccessKeys(userName string) (*AccessKeyMod, error) {
}
return keysMod, err
}

//func CreateSharedVPCAWSClient(region string) (*AWSClient, error) {
// var cfg aws.Config
// var err error
//
// if os.Getenv("SHARED_VPC_AWS_SHARED_CREDENTIALS_FILE") == "" {
// panic(fmt.Errorf("SHARED_VPC_AWS_SHARED_CREDENTIALS_FILE env is not set or empty, it's requried by Shared-VPC cluster"))
// }
//
// file := os.Getenv("SHARED_VPC_AWS_SHARED_CREDENTIALS_FILE")
// log.LogInfo("Got file path: %s from env variable SHARED_VPC_AWS_SHARED_CREDENTIALS_FILE\n", file)
// cfg, err = config.LoadDefaultConfig(context.TODO(),
// config.WithRegion(region),
// config.WithSharedCredentialsFiles([]string{file}),
// )
//
// if err != nil {
// return nil, err
// }
//
// awsClient := &AWSClient{
// Ec2Client: ec2.NewFromConfig(cfg),
// Route53Client: route53.NewFromConfig(cfg),
// StackFormationClient: cloudformation.NewFromConfig(cfg),
// ElbClient: elb.NewFromConfig(cfg),
// Region: region,
// StsClient: sts.NewFromConfig(cfg),
// IamClient: iam.NewFromConfig(cfg),
// ClientContext: context.TODO(),
// KmsClient: kms.NewFromConfig(cfg),
// AWSConfig: &cfg,
// RamClient: ram.NewFromConfig(cfg),
// }
// awsClient.AccountID = awsClient.GetAWSAccountID()
// return awsClient, nil
//}
32 changes: 32 additions & 0 deletions pkg/aws/aws_client/ram.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package aws_client

import (
"context"
"github.com/aws/aws-sdk-go-v2/service/ram"
"github.com/openshift-online/ocm-common/pkg/log"
)

func (awsClient AWSClient) CreateResourceShare(resourceShareName string, resourceArns []string, principles []string) (*ram.CreateResourceShareOutput, error) {
input := &ram.CreateResourceShareInput{
Name: &resourceShareName,
ResourceArns: resourceArns,
Principals: principles,
}

resp, err := awsClient.RamClient.CreateResourceShare(context.TODO(), input)
if err != nil {
log.LogError("Create resource share failed with name %s: %s", resourceShareName, err.Error())
} else {
log.LogInfo("Create resource share succeed with name %s", resourceShareName)
}
return resp, err
}

func (awsClient AWSClient) DeleteResourceShare(resourceShareArn string) error {
input := &ram.DeleteResourceShareInput{
ResourceShareArn: &resourceShareArn,
}

_, err := awsClient.RamClient.DeleteResourceShare(context.TODO(), input)
return err
}
44 changes: 43 additions & 1 deletion pkg/aws/aws_client/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,46 @@ func (client *AWSClient) UntagRole(roleName string, tagKeys []string) error {
}
_, err := client.IamClient.UntagRole(context.TODO(), input)
return err
}
}

func (client *AWSClient) CreateRoleForSharedVPC(roleName, installerRoleArn string, ingressOperatorRoleArn string) (types.Role, error) {
statement := map[string]interface{}{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": map[string]interface{}{
"AWS": []string{installerRoleArn, ingressOperatorRoleArn},
},
"Action": "sts:AssumeRole",
}

assumeRolePolicyDocument, err := completeRolePolicyDocument(statement)
if err != nil {
fmt.Println("Failed to convert Role Policy Document into JSON: ", err)
return types.Role{}, err
}

return client.CreateRole(roleName, string(assumeRolePolicyDocument), "", make(map[string]string), "/")
}

func (client *AWSClient) CreatePolicyForSharedVPC(policyName string) (string, error) {
statement := map[string]interface{}{
"Sid": "Statement1",
"Effect": "Allow",
"Action": []string{
"route53:GetChange",
"route53:GetHostedZone",
"route53:ChangeResourceRecordSets",
"route53:ListHostedZones",
"route53:ListHostedZonesByName",
"route53:ListResourceRecordSets",
"route53:ChangeTagsForResource",
"route53:GetAccountLimit",
"route53:ListTagsForResource",
"route53:UpdateHostedZoneComment",
"tag:GetResources",
"tag:UntagResources",
},
"Resource": "*",
}
return client.CreatePolicy(policyName, statement)
}
22 changes: 18 additions & 4 deletions pkg/aws/aws_client/route53.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,29 @@ import (
"github.com/openshift-online/ocm-common/pkg/log"
)

func (awsClient AWSClient) CreateHostedZone(hostedZoneName string, vpcID string, private bool) (*route53.CreateHostedZoneOutput, error) {
func (awsClient AWSClient) CreateHostedZone(hostedZoneName string, callerReference string, vpcID string, region string, private bool) (*route53.CreateHostedZoneOutput, error) {
// callReference is a required field of CreateHostedZoneInput struct, which used to identifies the request as a unique string.
// Usually random string or date/time stamp can be used as callReference.
input := &route53.CreateHostedZoneInput{
Name: &hostedZoneName,
Name: &hostedZoneName,
CallerReference: &callerReference,
HostedZoneConfig: &types.HostedZoneConfig{
PrivateZone: private,
},
}
if vpcID != "" {
vpc := &types.VPC{
VPCId: &vpcID,
VPCId: &vpcID,
VPCRegion: types.VPCRegion(region),
}
input.VPC = vpc
}

resp, err := awsClient.Route53Client.CreateHostedZone(context.TODO(), input)
if err != nil {
log.LogError("Create hosted zone failed for vpc %s with name %s: %s", vpcID, hostedZoneName, err.Error())
} else {
log.LogError("Create hosted zone succeed for vpc %s with name %s", vpcID, hostedZoneName)
log.LogInfo("Create hosted zone succeed for vpc %s with name %s", vpcID, hostedZoneName)
}
return resp, err
}
Expand All @@ -47,3 +52,12 @@ func (awsClient AWSClient) ListHostedZoneByDNSName(hostedZoneName string) (*rout

return awsClient.Route53Client.ListHostedZonesByName(context.TODO(), input)
}

func (awsClient AWSClient) DeleteHostedZone(hostedZoneID string) error {
input := &route53.DeleteHostedZoneInput{
Id: &hostedZoneID,
}

_, err := awsClient.Route53Client.DeleteHostedZone(context.TODO(), input)
return err
}
Loading

0 comments on commit 752d581

Please sign in to comment.