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

OCM-8979 | test: Prepare shared VPC resources #62

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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
49 changes: 30 additions & 19 deletions pkg/aws/aws_client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package aws_client

import (
"context"
"os"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
Expand All @@ -12,7 +10,9 @@ 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"
"os"

"github.com/openshift-online/ocm-common/pkg/log"

Expand All @@ -35,42 +35,52 @@ 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")
jameszwang marked this conversation as resolved.
Show resolved Hide resolved
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 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 {
Expand All @@ -88,6 +98,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
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
}
43 changes: 43 additions & 0 deletions pkg/aws/aws_client/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/openshift-online/ocm-common/pkg/log"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
Expand Down Expand Up @@ -395,3 +396,45 @@ 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 {
log.LogError("Failed to convert Role Policy Document into JSON: %s", err.Error())
return types.Role{}, err
}

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

func (client *AWSClient) CreatePolicyForSharedVPC(policyName string) (string, error) {
jameszwang marked this conversation as resolved.
Show resolved Hide resolved
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)
}
23 changes: 19 additions & 4 deletions pkg/aws/aws_client/route53.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,30 @@ 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) {
jameszwang marked this conversation as resolved.
Show resolved Hide resolved
jameszwang marked this conversation as resolved.
Show resolved Hide resolved
// CreateHostedZone is a function used for hosted zone creation on AWS
// 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 +53,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
}
17 changes: 13 additions & 4 deletions pkg/test/vpc_client/vpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ func (vpc *VPC) DeleteVPCChain(totalClean ...bool) error {
// Just be careful once you use checkExisting, the vpc may have subnets not existing in your zones. And maybe multi subnets in the zones
// Try vpc.PreparePairSubnets by zone for further implementation to get a pair of
// Zones will be customized if you want. Otherwise, it will use the default zone "a"
func PrepareVPC(vpcName string, region string, vpcCIDR string, checkExisting bool, zones ...string) (*VPC, error) {
func PrepareVPC(vpcName string, region string, vpcCIDR string, checkExisting bool, awsSharedCredentialFile string, zones ...string) (*VPC, error) {
var awsclient *aws_client.AWSClient
var err error

if vpcCIDR == "" {
vpcCIDR = CON.DefaultVPCCIDR
}
Expand All @@ -160,7 +163,12 @@ func PrepareVPC(vpcName string, region string, vpcCIDR string, checkExisting boo
vpcName, region, vpcCIDR)
}
log.LogInfo(logMessage)
awsclient, err := aws_client.CreateAWSClient("", region)
if awsSharedCredentialFile == "" {
awsclient, err = aws_client.CreateAWSClient("", region)
} else {
awsclient, err = aws_client.CreateAWSClient("", region, awsSharedCredentialFile)
}

if err != nil {
log.LogError("Create AWS Client due to error: %s", err.Error())
return nil, err
Expand Down Expand Up @@ -217,8 +225,9 @@ func PrepareVPC(vpcName string, region string, vpcCIDR string, checkExisting boo

// GenerateVPCByID will return a VPC with CIDRpool and subnets
// If you know the vpc ID on AWS, then try to generate it
func GenerateVPCByID(vpcID string, region string) (*VPC, error) {
awsClient, err := aws_client.CreateAWSClient("", region)
func GenerateVPCByID(vpcID string, region string, awsSharedCredentialFile ...string) (*VPC, error) {
awsClient, err := aws_client.CreateAWSClient("", region, awsSharedCredentialFile...)

jameszwang marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
Expand Down
Loading