diff --git a/pkg/model/components/addonmanifests/kuberouter/iam.go b/pkg/model/components/addonmanifests/kuberouter/iam.go new file mode 100644 index 0000000000..337e36ec91 --- /dev/null +++ b/pkg/model/components/addonmanifests/kuberouter/iam.go @@ -0,0 +1,45 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kuberouter + +import ( + "k8s.io/apimachinery/pkg/types" + + "k8s.io/kops/pkg/model/iam" +) + +// ServiceAccount represents the service-account used by kube-router when we're using IRSA +// It implements iam.Subject to get AWS IAM permissions. +type ServiceAccount struct{} + +var _ iam.Subject = &ServiceAccount{} + +// BuildAWSPolicy generates a custom policy for a ServiceAccount IAM role. +func (r *ServiceAccount) BuildAWSPolicy(b *iam.PolicyBuilder) (*iam.Policy, error) { + clusterName := b.Cluster.ObjectMeta.Name + p := iam.NewPolicy(clusterName, b.Partition) + iam.AddKubeRouterPermissions(b, p) + return p, nil +} + +// ServiceAccount returns the kubernetes service account used. +func (r *ServiceAccount) ServiceAccount() (types.NamespacedName, bool) { + return types.NamespacedName{ + Namespace: "kube-system", + Name: "kube-router", + }, true +} diff --git a/pkg/model/components/addonmanifests/remap.go b/pkg/model/components/addonmanifests/remap.go index 30dc06a8b4..6ac9147e22 100644 --- a/pkg/model/components/addonmanifests/remap.go +++ b/pkg/model/components/addonmanifests/remap.go @@ -33,6 +33,7 @@ import ( "k8s.io/kops/pkg/model/components/addonmanifests/dnscontroller" "k8s.io/kops/pkg/model/components/addonmanifests/externaldns" "k8s.io/kops/pkg/model/components/addonmanifests/karpenter" + "k8s.io/kops/pkg/model/components/addonmanifests/kuberouter" "k8s.io/kops/pkg/model/components/addonmanifests/nodeterminationhandler" "k8s.io/kops/pkg/model/iam" "k8s.io/kops/upup/pkg/fi" @@ -129,6 +130,8 @@ func getWellknownServiceAccount(name string) iam.Subject { return &externaldns.ServiceAccount{} case "karpenter": return &karpenter.ServiceAccount{} + case "kube-router": + return &kuberouter.ServiceAccount{} default: return nil } diff --git a/pkg/model/iam/iam_builder.go b/pkg/model/iam/iam_builder.go index 72a9ebf128..0684201ea1 100644 --- a/pkg/model/iam/iam_builder.go +++ b/pkg/model/iam/iam_builder.go @@ -1115,6 +1115,14 @@ func AddDNSControllerPermissions(b *PolicyBuilder, p *Policy) { }) } +// AddKubeRouterPermissions adds IAM permissions used by kube-router +// for disabling the source/destination check on EC2 instances. +func AddKubeRouterPermissions(b *PolicyBuilder, p *Policy) { + p.clusterTaggedAction.Insert( + "ec2:ModifyInstanceAttribute", + ) +} + func addKMSIAMPolicies(p *Policy, resource stringorslice.StringOrSlice) { // TODO could use "kms:ViaService" Condition Key here? p.unconditionalAction.Insert( diff --git a/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go b/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go index e55fc7eba2..60b6375960 100644 --- a/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go +++ b/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go @@ -37,6 +37,7 @@ import ( "k8s.io/kops/pkg/model/components/addonmanifests/dnscontroller" "k8s.io/kops/pkg/model/components/addonmanifests/externaldns" "k8s.io/kops/pkg/model/components/addonmanifests/karpenter" + "k8s.io/kops/pkg/model/components/addonmanifests/kuberouter" "k8s.io/kops/pkg/model/components/addonmanifests/nodeterminationhandler" "k8s.io/kops/pkg/model/iam" "k8s.io/kops/pkg/templates" @@ -956,6 +957,11 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.ModelBuilderContext) (*Addon Id: id, }) } + + // Generate kube-router ServiceAccount IAM permissions + if b.UseServiceAccountExternalPermissions() { + serviceAccountRoles = append(serviceAccountRoles, &kuberouter.ServiceAccount{}) + } } if b.Cluster.Spec.Networking.AmazonVPC != nil {