Merge pull request #12419 from eddycharly/audiences

feat: add support for custom audience in aws oidc provider
This commit is contained in:
Kubernetes Prow Robot 2021-09-29 13:45:21 -07:00 committed by GitHub
commit dc9bf4f36c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 69 additions and 7 deletions

View File

@ -5240,6 +5240,12 @@ spec:
description: ServiceAccountIssuerDiscovery configures the OIDC Issuer
for ServiceAccounts.
properties:
additionalAudiences:
description: AdditionalAudiences adds user defined audiences to
the provisioned AWS OIDC provider
items:
type: string
type: array
discoveryStore:
description: DiscoveryStore is the VFS path to where OIDC Issuer
Discovery metadata is stored.

View File

@ -224,6 +224,8 @@ type ServiceAccountIssuerDiscoveryConfig struct {
DiscoveryStore string `json:"discoveryStore,omitempty"`
// EnableAWSOIDCProvider will provision an AWS OIDC provider that trusts the ServiceAccount Issuer
EnableAWSOIDCProvider bool `json:"enableAWSOIDCProvider,omitempty"`
// AdditionalAudiences adds user defined audiences to the provisioned AWS OIDC provider
AdditionalAudiences []string `json:"additionalAudiences,omitempty"`
}
// ServiceAccountExternalPermissions grants a ServiceAccount permissions to external resources.

View File

@ -222,6 +222,8 @@ type ServiceAccountIssuerDiscoveryConfig struct {
DiscoveryStore string `json:"discoveryStore,omitempty"`
// EnableAWSOIDCProvider will provision an AWS OIDC provider that trusts the ServiceAccount Issuer
EnableAWSOIDCProvider bool `json:"enableAWSOIDCProvider,omitempty"`
// AdditionalAudiences adds user defined audiences to the provisioned AWS OIDC provider
AdditionalAudiences []string `json:"additionalAudiences,omitempty"`
}
// ServiceAccountExternalPermissions grants a ServiceAccount permissions to external resources.

View File

@ -6690,6 +6690,7 @@ func Convert_kops_ServiceAccountExternalPermission_To_v1alpha2_ServiceAccountExt
func autoConvert_v1alpha2_ServiceAccountIssuerDiscoveryConfig_To_kops_ServiceAccountIssuerDiscoveryConfig(in *ServiceAccountIssuerDiscoveryConfig, out *kops.ServiceAccountIssuerDiscoveryConfig, s conversion.Scope) error {
out.DiscoveryStore = in.DiscoveryStore
out.EnableAWSOIDCProvider = in.EnableAWSOIDCProvider
out.AdditionalAudiences = in.AdditionalAudiences
return nil
}
@ -6701,6 +6702,7 @@ func Convert_v1alpha2_ServiceAccountIssuerDiscoveryConfig_To_kops_ServiceAccount
func autoConvert_kops_ServiceAccountIssuerDiscoveryConfig_To_v1alpha2_ServiceAccountIssuerDiscoveryConfig(in *kops.ServiceAccountIssuerDiscoveryConfig, out *ServiceAccountIssuerDiscoveryConfig, s conversion.Scope) error {
out.DiscoveryStore = in.DiscoveryStore
out.EnableAWSOIDCProvider = in.EnableAWSOIDCProvider
out.AdditionalAudiences = in.AdditionalAudiences
return nil
}

View File

@ -1185,7 +1185,7 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
if in.ServiceAccountIssuerDiscovery != nil {
in, out := &in.ServiceAccountIssuerDiscovery, &out.ServiceAccountIssuerDiscovery
*out = new(ServiceAccountIssuerDiscoveryConfig)
**out = **in
(*in).DeepCopyInto(*out)
}
if in.SnapshotController != nil {
in, out := &in.SnapshotController, &out.SnapshotController
@ -4654,6 +4654,11 @@ func (in *ServiceAccountExternalPermission) DeepCopy() *ServiceAccountExternalPe
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceAccountIssuerDiscoveryConfig) DeepCopyInto(out *ServiceAccountIssuerDiscoveryConfig) {
*out = *in
if in.AdditionalAudiences != nil {
in, out := &in.AdditionalAudiences, &out.AdditionalAudiences
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}

View File

@ -1269,7 +1269,7 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
if in.ServiceAccountIssuerDiscovery != nil {
in, out := &in.ServiceAccountIssuerDiscovery, &out.ServiceAccountIssuerDiscovery
*out = new(ServiceAccountIssuerDiscoveryConfig)
**out = **in
(*in).DeepCopyInto(*out)
}
if in.SnapshotController != nil {
in, out := &in.SnapshotController, &out.SnapshotController
@ -4836,6 +4836,11 @@ func (in *ServiceAccountExternalPermission) DeepCopy() *ServiceAccountExternalPe
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceAccountIssuerDiscoveryConfig) DeepCopyInto(out *ServiceAccountIssuerDiscoveryConfig) {
*out = *in
if in.AdditionalAudiences != nil {
in, out := &in.AdditionalAudiences, &out.AdditionalAudiences
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}

View File

@ -49,11 +49,16 @@ func (b *OIDCProviderBuilder) Build(c *fi.ModelBuilderContext) error {
thumbprints = append(thumbprints, fi.String(fingerprint))
}
audiences := []string{defaultAudience}
if b.Cluster.Spec.ServiceAccountIssuerDiscovery.AdditionalAudiences != nil {
audiences = append(audiences, b.Cluster.Spec.ServiceAccountIssuerDiscovery.AdditionalAudiences...)
}
c.AddTask(&awstasks.IAMOIDCProvider{
Name: fi.String(b.ClusterName()),
Lifecycle: b.Lifecycle,
URL: b.Cluster.Spec.KubeAPIServer.ServiceAccountIssuer,
ClientIDs: []*string{fi.String(defaultAudience)},
ClientIDs: fi.StringSlice(audiences),
Tags: b.CloudTags(b.ClusterName(), false),
Thumbprints: thumbprints,
})

View File

@ -201,6 +201,8 @@ spec:
podCIDR: 100.96.0.0/11
secretStore: memfs://clusters.example.com/minimal.example.com/secrets
serviceAccountIssuerDiscovery:
additionalAudiences:
- sts.amazonaws.com
discoveryStore: memfs://discovery.example.com/minimal.example.com
enableAWSOIDCProvider: true
serviceClusterIPRange: 100.64.0.0/13

View File

@ -58,6 +58,8 @@ spec:
serviceAccountIssuerDiscovery:
enableAWSOIDCProvider: true
discoveryStore: memfs://discovery.example.com/minimal.example.com
additionalAudiences:
- sts.amazonaws.com
sshAccess:
- 0.0.0.0/0
topology:

View File

@ -291,7 +291,7 @@ resource "aws_iam_instance_profile" "nodes-minimal-example-com" {
}
resource "aws_iam_openid_connect_provider" "minimal-example-com" {
client_id_list = ["amazonaws.com"]
client_id_list = ["amazonaws.com", "sts.amazonaws.com"]
tags = {
"KubernetesCluster" = "minimal.example.com"
"Name" = "minimal.example.com"

View File

@ -109,6 +109,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/service/iam:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/service/route53:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/service/sqs:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library",
],

View File

@ -23,6 +23,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iam"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
@ -110,9 +111,6 @@ func (s *IAMOIDCProvider) CheckChanges(a, e, changes *IAMOIDCProvider) error {
}
if a != nil {
if changes.ClientIDs != nil {
return fi.CannotChangeField("ClientIDs")
}
if changes.URL != nil {
return fi.CannotChangeField("URL")
}
@ -178,6 +176,38 @@ func (p *IAMOIDCProvider) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *IAMOID
}
}
}
if changes.ClientIDs != nil {
actual := sets.NewString()
for _, aud := range a.ClientIDs {
actual.Insert(*aud)
}
expected := sets.NewString()
for _, aud := range e.ClientIDs {
expected.Insert(*aud)
}
toRemove := actual.Difference(expected)
for _, elem := range toRemove.List() {
request := &iam.RemoveClientIDFromOpenIDConnectProviderInput{
OpenIDConnectProviderArn: a.arn,
ClientID: &elem,
}
_, err := t.Cloud.IAM().RemoveClientIDFromOpenIDConnectProvider(request)
if err != nil {
return fmt.Errorf("error removing audience %s to IAMOIDCProvider: %v", elem, err)
}
}
toAdd := expected.Difference(actual)
for _, elem := range toAdd.List() {
request := &iam.AddClientIDToOpenIDConnectProviderInput{
OpenIDConnectProviderArn: a.arn,
ClientID: &elem,
}
_, err := t.Cloud.IAM().AddClientIDToOpenIDConnectProvider(request)
if err != nil {
return fmt.Errorf("error adding audience %s to IAMOIDCProvider: %v", elem, err)
}
}
}
}
return nil
}