Skip to content

Commit

Permalink
Merge pull request #854 from staebler/aws_cn
Browse files Browse the repository at this point in the history
support aws china for managed dns
  • Loading branch information
openshift-merge-robot authored Feb 27, 2020
2 parents fa12980 + 8cad7e4 commit 9de5c48
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 15 deletions.
4 changes: 4 additions & 0 deletions config/crds/hive_v1_dnszone.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ spec:
description: CredentialsSecretRef contains a reference to a secret
that contains AWS credentials for CRUD operations
type: object
region:
description: Region is the AWS region to use for route53 operations.
This defaults to us-east-1. For AWS China, use cn-northwest-1.
type: string
type: object
gcp:
description: GCP specifies GCP-specific cloud configuration
Expand Down
4 changes: 4 additions & 0 deletions config/crds/hive_v1_hiveconfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ spec:
parent ManageDNSConfig object. Secret should have AWS keys
named 'aws_access_key_id' and 'aws_secret_access_key'.
type: object
region:
description: Region is the AWS region to use for route53 operations.
This defaults to us-east-1. For AWS China, use cn-northwest-1.
type: string
type: object
domains:
description: Domains is the list of domains that hive will be
Expand Down
6 changes: 6 additions & 0 deletions pkg/apis/hive/v1/dnszone_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ type AWSDNSZoneSpec struct {
// to these tags,the DNS Zone controller will set a hive.openhsift.io/hostedzone tag
// identifying the HostedZone record that it belongs to.
AdditionalTags []AWSResourceTag `json:"additionalTags,omitempty"`

// Region is the AWS region to use for route53 operations.
// This defaults to us-east-1.
// For AWS China, use cn-northwest-1.
// +optional
Region string `json:"region,omitempty"`
}

// AWSResourceTag represents a tag that is applied to an AWS cloud resource
Expand Down
6 changes: 6 additions & 0 deletions pkg/apis/hive/v1/hiveconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ type ManageDNSAWSConfig struct {
// Secret should have AWS keys named 'aws_access_key_id' and 'aws_secret_access_key'.
// +optional
CredentialsSecretRef corev1.LocalObjectReference `json:"credentialsSecretRef,omitempty"`

// Region is the AWS region to use for route53 operations.
// This defaults to us-east-1.
// For AWS China, use cn-northwest-1.
// +optional
Region string `json:"region,omitempty"`
}

// ManageDNSGCPConfig contains GCP-specific info to manage a given domain.
Expand Down
31 changes: 24 additions & 7 deletions pkg/awsclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
Expand All @@ -27,6 +28,8 @@ import (
"github.com/aws/aws-sdk-go/service/route53/route53iface"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3iface"

"github.com/openshift/hive/pkg/constants"
)

const (
Expand All @@ -52,7 +55,7 @@ func init() {

// Client is a wrapper object for actual AWS SDK clients to allow for easier testing.
type Client interface {
//EC2
// EC2
DescribeAvailabilityZones(*ec2.DescribeAvailabilityZonesInput) (*ec2.DescribeAvailabilityZonesOutput, error)
DescribeImages(*ec2.DescribeImagesInput) (*ec2.DescribeImagesOutput, error)
DescribeVpcs(*ec2.DescribeVpcsInput) (*ec2.DescribeVpcsOutput, error)
Expand All @@ -62,10 +65,10 @@ type Client interface {
DescribeInstances(*ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error)
TerminateInstances(*ec2.TerminateInstancesInput) (*ec2.TerminateInstancesOutput, error)

//ELB
// ELB
RegisterInstancesWithLoadBalancer(*elb.RegisterInstancesWithLoadBalancerInput) (*elb.RegisterInstancesWithLoadBalancerOutput, error)

//IAM
// IAM
CreateAccessKey(*iam.CreateAccessKeyInput) (*iam.CreateAccessKeyOutput, error)
CreateUser(*iam.CreateUserInput) (*iam.CreateUserOutput, error)
DeleteAccessKey(*iam.DeleteAccessKeyInput) (*iam.DeleteAccessKeyOutput, error)
Expand All @@ -76,15 +79,15 @@ type Client interface {
ListUserPolicies(*iam.ListUserPoliciesInput) (*iam.ListUserPoliciesOutput, error)
PutUserPolicy(*iam.PutUserPolicyInput) (*iam.PutUserPolicyOutput, error)

//S3
// S3
CreateBucket(*s3.CreateBucketInput) (*s3.CreateBucketOutput, error)
DeleteBucket(*s3.DeleteBucketInput) (*s3.DeleteBucketOutput, error)
ListBuckets(*s3.ListBucketsInput) (*s3.ListBucketsOutput, error)

//Custom
// Custom
GetS3API() s3iface.S3API

//Route53
// Route53
CreateHostedZone(input *route53.CreateHostedZoneInput) (*route53.CreateHostedZoneOutput, error)
GetHostedZone(*route53.GetHostedZoneInput) (*route53.GetHostedZoneOutput, error)
ListTagsForResource(*route53.ListTagsForResourceInput) (*route53.ListTagsForResourceOutput, error)
Expand Down Expand Up @@ -300,7 +303,10 @@ func NewClient(kubeClient client.Client, secretName, namespace, region string) (
//
// Pass a nil secret to load credentials from the standard AWS environment variables.
func NewClientFromSecret(secret *corev1.Secret, region string) (Client, error) {
awsConfig := &aws.Config{Region: aws.String(region)}
awsConfig := &aws.Config{
Region: aws.String(region),
EndpointResolver: endpoints.ResolverFunc(awsChinaEndpointResolver),
}

// Special case to not use a secret to gather credentials.
if secret != nil {
Expand Down Expand Up @@ -339,3 +345,14 @@ func NewClientFromSecret(secret *corev1.Secret, region string) (Client, error) {
tagClient: resourcegroupstaggingapi.New(s),
}, nil
}

func awsChinaEndpointResolver(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
if service != route53.EndpointsID || region != constants.AWSChinaRoute53Region {
return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
}

return endpoints.ResolvedEndpoint{
URL: "https://route53.amazonaws.com.cn",
PartitionID: "aws-cn",
}, nil
}
9 changes: 9 additions & 0 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ const (

// PasswordSecretKey is a key used to store a password inside of a secret containing username / password credentials
PasswordSecretKey = "password"

// AWSRoute53Region is the region to use for route53 operations.
AWSRoute53Region = "us-east-1"

// AWSChinaRoute53Region is the region to use for AWS China route53 operations.
AWSChinaRoute53Region = "cn-northwest-1"

// AWSChinaRegionPrefix is the prefix for regions in AWS China.
AWSChinaRegionPrefix = "cn-"
)

// GetMergedPullSecretName returns name for merged pull secret name per cluster deployment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"reflect"
"sort"
"strings"
"time"

"github.com/pkg/errors"
Expand Down Expand Up @@ -1358,9 +1359,14 @@ func (r *ReconcileClusterDeployment) createManagedDNSZone(cd *hivev1.ClusterDepl
for k, v := range cd.Spec.Platform.AWS.UserTags {
additionalTags = append(additionalTags, hivev1.AWSResourceTag{Key: k, Value: v})
}
region := ""
if strings.HasPrefix(cd.Spec.Platform.AWS.Region, constants.AWSChinaRegionPrefix) {
region = constants.AWSChinaRoute53Region
}
dnsZone.Spec.AWS = &hivev1.AWSDNSZoneSpec{
CredentialsSecretRef: cd.Spec.Platform.AWS.CredentialsSecretRef,
AdditionalTags: additionalTags,
Region: region,
}
case cd.Spec.Platform.GCP != nil:
dnsZone.Spec.GCP = &hivev1.GCPDNSZoneSpec{
Expand Down
7 changes: 6 additions & 1 deletion pkg/controller/dnsendpoint/dnsendpoint_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/source"

hivev1 "github.com/openshift/hive/pkg/apis/hive/v1"
"github.com/openshift/hive/pkg/constants"
"github.com/openshift/hive/pkg/controller/dnsendpoint/nameserver"
hivemetrics "github.com/openshift/hive/pkg/controller/metrics"
controllerutils "github.com/openshift/hive/pkg/controller/utils"
Expand Down Expand Up @@ -277,7 +278,11 @@ func createNameServerQuery(c client.Client, logger log.FieldLogger, managedDomai
if managedDomain.AWS != nil {
secretName := managedDomain.AWS.CredentialsSecretRef.Name
logger.Infof("using aws creds for managed domains stored in %q secret", secretName)
return nameserver.NewAWSQuery(c, secretName)
region := managedDomain.AWS.Region
if region == "" {
region = constants.AWSRoute53Region
}
return nameserver.NewAWSQuery(c, secretName, region)
}
if managedDomain.GCP != nil {
secretName := managedDomain.GCP.CredentialsSecretRef.Name
Expand Down
4 changes: 2 additions & 2 deletions pkg/controller/dnsendpoint/nameserver/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import (
)

// NewAWSQuery creates a new name server query for AWS.
func NewAWSQuery(c client.Client, credsSecretName string) Query {
func NewAWSQuery(c client.Client, credsSecretName string, region string) Query {
return &awsQuery{
getAWSClient: func() (awsclient.Client, error) {
awsClient, err := awsclient.NewClient(c, credsSecretName, constants.HiveNamespace, "us-east-1")
awsClient, err := awsclient.NewClient(c, credsSecretName, constants.HiveNamespace, region)
return awsClient, errors.Wrap(err, "error creating AWS client")
},
}
Expand Down
12 changes: 7 additions & 5 deletions pkg/controller/dnszone/awsactuator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import (

hivev1 "github.com/openshift/hive/pkg/apis/hive/v1"
awsclient "github.com/openshift/hive/pkg/awsclient"
"github.com/openshift/hive/pkg/constants"
)

const (
hiveDNSZoneAWSTag = "hive.openshift.io/dnszone"
defaultRegionEndpoint = "us-east-1"
hiveDNSZoneAWSTag = "hive.openshift.io/dnszone"
)

// Ensure AWSActuator implements the Actuator interface. This will fail at compile time when false.
Expand Down Expand Up @@ -54,9 +54,11 @@ func NewAWSActuator(
dnsZone *hivev1.DNSZone,
awsClientBuilder awsClientBuilderType,
) (*AWSActuator, error) {
// Route53 is a regionless service, we specify a default region just for the purpose of creating
// our client configuration.
awsClient, err := awsClientBuilder(secret, defaultRegionEndpoint)
region := dnsZone.Spec.AWS.Region
if region == "" {
region = constants.AWSRoute53Region
}
awsClient, err := awsClientBuilder(secret, region)
if err != nil {
logger.WithError(err).Error("Error creating AWSClient")
return nil, err
Expand Down
8 changes: 8 additions & 0 deletions pkg/operator/assets/bindata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9de5c48

Please sign in to comment.