Merge pull request #9964 from rifelpet/sa-partition

Add AWS partition support to iam service account roles
This commit is contained in:
Kubernetes Prow Robot 2020-09-18 06:48:46 -07:00 committed by GitHub
commit 255cd59b67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 28 additions and 16 deletions

View File

@ -108,7 +108,7 @@ func addServiceAccountRoleForAWS(context *IAMModelContext, podSpec *corev1.PodSp
return err
}
awsRoleARN := "arn:aws:iam::" + context.AWSAccountID + ":role/" + roleName
awsRoleARN := "arn:" + context.AWSPartition + ":iam::" + context.AWSAccountID + ":role/" + roleName
tokenDir := "/var/run/secrets/amazonaws.com/"
tokenName := "token"

View File

@ -35,6 +35,8 @@ func ParseStatements(policy string) ([]*Statement, error) {
type IAMModelContext struct {
// AWSAccountID holds the 12 digit AWS account ID, when running on AWS
AWSAccountID string
// AWSPartition defines the partition of the AWS account, typically "aws", "aws-cn", or "aws-us-gov"
AWSPartition string
Cluster *kops.Cluster
}

View File

@ -408,11 +408,12 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
awsCloud := cloud.(awsup.AWSCloud)
region = awsCloud.Region()
accountID, err := awsCloud.AccountID()
accountID, partition, err := awsCloud.AccountInfo()
if err != nil {
return err
}
modelContext.AWSAccountID = accountID
modelContext.AWSPartition = partition
if len(sshPublicKeys) == 0 && c.Cluster.Spec.SSHKeyName == nil {
return fmt.Errorf("SSH public key must be specified when running with AWS (create with `kops create secret --name %s sshpublickey admin -i ~/.ssh/id_rsa.pub`)", cluster.ObjectMeta.Name)

View File

@ -29,6 +29,7 @@ go_library(
"//protokube/pkg/etcd:go_default_library",
"//upup/pkg/fi:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/arn:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/client:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/endpoints:go_default_library",

View File

@ -24,6 +24,7 @@ import (
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
@ -163,8 +164,8 @@ type AWSCloud interface {
// FindClusterStatus gets the status of the cluster as it exists in AWS, inferred from volumes
FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error)
// AccountID returns the AWS account ID (typically a 12 digit number) we are deploying into
AccountID() (string, error)
// AccountInfo returns the AWS account ID and AWS partition that we are deploying into
AccountInfo() (string, string, error)
}
type awsCloudImplementation struct {
@ -1660,19 +1661,25 @@ func describeInstanceType(c AWSCloud, instanceType string) (*ec2.InstanceTypeInf
return resp.InstanceTypes[0], nil
}
// AccountID returns the AWS account ID (typically a 12 digit number) we are deploying into
func (c *awsCloudImplementation) AccountID() (string, error) {
// AccountInfo returns the AWS account ID and AWS partition that we are deploying into
func (c *awsCloudImplementation) AccountInfo() (string, string, error) {
request := &sts.GetCallerIdentityInput{}
response, err := c.sts.GetCallerIdentity(request)
if err != nil {
return "", fmt.Errorf("error geting AWS account ID: %v", err)
return "", "", fmt.Errorf("error geting AWS account ID: %v", err)
}
account := aws.StringValue(response.Account)
if account == "" {
return "", fmt.Errorf("AWS account id was empty")
arn, err := arn.Parse(aws.StringValue(response.Arn))
if err != nil {
return "", "", fmt.Errorf("Failed to parse GetCallerIdentity ARN")
}
return account, nil
if arn.AccountID == "" {
return "", "", fmt.Errorf("AWS account id was empty")
}
if arn.Partition == "" {
return "", "", fmt.Errorf("AWS partition was empty")
}
return arn.AccountID, arn.Partition, nil
}

View File

@ -301,7 +301,7 @@ func (c *MockAWSCloud) DescribeInstanceType(instanceType string) (*ec2.InstanceT
return info, nil
}
// AccountID returns the AWS account ID (typically a 12 digit number) we are deploying into
func (c *MockAWSCloud) AccountID() (string, error) {
return "123456789012", nil
// AccountInfo returns the AWS account ID and AWS partition that we are deploying into
func (c *MockAWSCloud) AccountInfo() (string, string, error) {
return "123456789012", "aws-test", nil
}

View File

@ -111,6 +111,7 @@ func runChannelBuilderTest(t *testing.T, key string, addonManifests []string) {
IAMModelContext: iam.IAMModelContext{
Cluster: cluster,
AWSAccountID: "123456789012",
AWSPartition: "aws-test",
},
Region: "us-east-1",
InstanceGroups: []*kopsapi.InstanceGroup{

View File

@ -35,7 +35,7 @@ spec:
- name: KUBERNETES_SERVICE_HOST
value: 127.0.0.1
- name: AWS_ROLE_ARN
value: arn:aws:iam::123456789012:role/dns-controller.kube-system.sa.minimal.example.com
value: arn:aws-test:iam::123456789012:role/dns-controller.kube-system.sa.minimal.example.com
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/amazonaws.com/token
image: k8s.gcr.io/kops/dns-controller:1.19.0-alpha.4

View File

@ -73,7 +73,7 @@ spec:
- id: k8s-1.12
kubernetesVersion: '>=1.12.0'
manifest: dns-controller.addons.k8s.io/k8s-1.12.yaml
manifestHash: ec9465805a830d1029d3fb7a181202a1f9266b8e
manifestHash: 749f5c0750966f8d6ef79090796c1d9c7688edb4
name: dns-controller.addons.k8s.io
selector:
k8s-addon: dns-controller.addons.k8s.io