Repository: kubernetes/kops (go)

Issue:
Creating a cluster on GCP using Terraform target fails
/kind bug

**1. What `kops` version are you running?**

`Version 1.23.1 (git-83ccae81a636b8e870e430b6faaeeb5d10d9b832)`

**2. What Kubernetes version are you running?**

1.23.5

**3. What cloud provider are you using?**

GCP

**4. What commands did you run?  What is the simplest way to reproduce this issue?**

Issue can be reproduced by running:

```
kops create cluster k8s.local --zones=us-east1-b --cloud=gce --target=terraform --out=.
```

**5. What happened after the commands executed?**

After running the `kops create cluster` command, kops panics when trying to render Terraform code for managed files, due to an incorrect type assertion:

```
panic: interface conversion: vfs.ACL is *vfs.GSAcl, not vfs.GSAcl               
                                                               
goroutine 170 [running]:
k8s.io/kops/util/pkg/vfs.(*GSPath).RenderTerraform(0xc0014fc100, 0x5122c08, {0xc000c422c0, 0x3d}, {0x4f6b5e0, 0xc001415ad0}, {0x3cad5a0, 0xc00123b560})
        util/pkg/vfs/gsfs.go:431 +0x825
k8s.io/kops/upup/pkg/fi/fitasks.(*ManagedFile).RenderTerraform(0x6, 0x0, 0xc00111a100, 0x2, 0xc0009fd480, 0xc0014f4078)
        upup/pkg/fi/fitasks/managedfile.go:211 +0x247
reflect.Value.call({0x42b4de0, 0xc0009fd480, 0x5}, {0x469c1e3, 0x4}, {0xc00118a000, 0x5, 0x5147d60})
        GOROOT/src/reflect/value.go:543 +0x814
reflect.Value.Call({0x42b4de0, 0xc0009fd480, 0x0}, {0xc00118a000, 0x5, 0x8})
        GOROOT/src/reflect/value.go:339 +0xc5
k8s.io/kops/upup/pkg/fi.(*Context).Render(0xc00062c460, {0x4f6d500, 0x0}, {0x4f6d500, 0xc0009fd480}, {0x4f6d500, 0xc0014fc000})
        upup/pkg/fi/context.go:225 +0xf85
k8s.io/kops/upup/pkg/fi.DefaultDeltaRunMethod({0x4f6d500, 0xc0009fd480}, 0xc00062c460)
        upup/pkg/fi/default_methods.go:82 +0x46c
k8s.io/kops/upup/pkg/fi/fitasks.(*ManagedFile).Run(0xc0008e85f0, 0x49)
        upup/pkg/fi/fitasks/managedfile.go:97 +0x26
k8s.io/kops/upup/pkg/fi.(*executor).forkJoin.func1(0xc001153730, 0x9)
        upup/pkg/fi/executor.go:187 +0x263
created by k8s.io/kops/upup/pkg/fi.(*executor).forkJoin
        upup/pkg/fi/executor.go:183 +0x85
```

**6. What did you expect to happen?**

Terraform code to create the cluster written to current directory.

**7. Please provide your cluster manifest.**

```yaml
apiVersion: kops.k8s.io/v1alpha2
kind: Cluster
metadata:
  creationTimestamp: "2022-04-20T18:29:51Z"
  name: k8s.local
spec:
  api:
    loadBalancer:
      type: Public
  authorization:
    rbac: {}
  channel: stable
  cloudConfig:
    gceServiceAccount: default
  cloudProvider: gce
  configBase: gs://bucket/k8s.local
  etcdClusters:
  - cpuRequest: 200m
    etcdMembers:
    - instanceGroup: master-us-east1-b
      name: b
    memoryRequest: 100Mi
    name: main
  - cpuRequest: 100m
    etcdMembers:
    - instanceGroup: master-us-east1-b
      name: b
    memoryRequest: 100Mi
    name: events
  iam:
    allowContainerRegistry: true
    legacy: false
  kubelet:
    anonymousAuth: false
  kubernetesApiAccess:
  - 0.0.0.0/0
  - ::/0
  kubernetesVersion: 1.23.5
  masterPublicName: api.k8s.local
  networking:
    kubenet: {}
  nonMasqueradeCIDR: 100.64.0.0/10
  project: redacted
  sshAccess:
  - 0.0.0.0/0
  - ::/0
  subnets:
  - cidr: 10.0.16.0/20
    name: us-east1
    region: us-east1
    type: Public
  topology:
    dns:
      type: Public
    masters: public
    nodes: public
```

**8. Anything else do we need to know?**

This seems like a fairly trivial issue caused by an incorrect type assertion, not being a pointer type where it should be, in file `util/pkg/vfs/gsfs.go:431`. I will submit a PR to fix this panic.

Pull request:
Use expected pointer type in type assertion when iterating over GS ACLs
When creating a new cluster for GCP and using the Terraform target, fix kops panic by using expected pointer type in a type assertion in `util/pkg/vfs/gsfs.go` instead of interface type.

Fixes #13533

Patch:
diff --git a/pkg/model/components/addonmanifests/clusterautoscaler/iam.go b/pkg/model/components/addonmanifests/clusterautoscaler/iam.go
index dafd88ed31..65dc258402 100644
--- a/pkg/model/components/addonmanifests/clusterautoscaler/iam.go
+++ b/pkg/model/components/addonmanifests/clusterautoscaler/iam.go
@@ -19,10 +19,9 @@ package clusterautoscaler
 import (
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/kops/pkg/model/iam"
-	"k8s.io/kops/upup/pkg/fi"
 )
 
-// ServiceAccount represents the service account used by the cluster autoscaler.
+// ServiceAccount represents the service-account used by the dns-controller.
 // It implements iam.Subject to get AWS IAM permissions.
 type ServiceAccount struct{}
 
@@ -33,11 +32,7 @@ func (r *ServiceAccount) BuildAWSPolicy(b *iam.PolicyBuilder) (*iam.Policy, erro
 	clusterName := b.Cluster.ObjectMeta.Name
 	p := iam.NewPolicy(clusterName, b.Partition)
 
-	var useStaticInstanceList bool
-	if ca := b.Cluster.Spec.ClusterAutoscaler; ca != nil && fi.BoolValue(ca.AWSUseStaticInstanceList) {
-		useStaticInstanceList = true
-	}
-	iam.AddClusterAutoscalerPermissions(p, useStaticInstanceList)
+	iam.AddClusterAutoscalerPermissions(p)
 
 	return p, nil
 }
diff --git a/pkg/model/iam/iam_builder.go b/pkg/model/iam/iam_builder.go
index 72a9ebf128..ec8d35b2e1 100644
--- a/pkg/model/iam/iam_builder.go
+++ b/pkg/model/iam/iam_builder.go
@@ -427,12 +427,7 @@ func (r *NodeRoleMaster) BuildAWSPolicy(b *PolicyBuilder) (*Policy, error) {
 		if b.Cluster.Spec.AWSLoadBalancerController != nil && fi.BoolValue(b.Cluster.Spec.AWSLoadBalancerController.Enabled) {
 			AddAWSLoadbalancerControllerPermissions(p)
 		}
-
-		var useStaticInstanceList bool
-		if ca := b.Cluster.Spec.ClusterAutoscaler; ca != nil && fi.BoolValue(ca.AWSUseStaticInstanceList) {
-			useStaticInstanceList = true
-		}
-		AddClusterAutoscalerPermissions(p, useStaticInstanceList)
+		AddClusterAutoscalerPermissions(p)
 
 		nth := b.Cluster.Spec.NodeTerminationHandler
 		if nth != nil && fi.BoolValue(nth.Enabled) && fi.BoolValue(nth.EnableSQSTerminationDraining) {
@@ -1018,7 +1013,7 @@ func AddAWSLoadbalancerControllerPermissions(p *Policy) {
 	)
 }
 
-func AddClusterAutoscalerPermissions(p *Policy, useStaticInstanceList bool) {
+func AddClusterAutoscalerPermissions(p *Policy) {
 	p.clusterTaggedAction.Insert(
 		"autoscaling:SetDesiredCapacity",
 		"autoscaling:TerminateInstanceInAutoScalingGroup",
@@ -1029,11 +1024,6 @@ func AddClusterAutoscalerPermissions(p *Policy, useStaticInstanceList bool) {
 		"autoscaling:DescribeLaunchConfigurations",
 		"ec2:DescribeLaunchTemplateVersions",
 	)
-	if !useStaticInstanceList {
-		p.unconditionalAction.Insert(
-			"ec2:DescribeInstanceTypes",
-		)
-	}
 }
 
 // AddAWSEBSCSIDriverPermissions appens policy statements that the AWS EBS CSI Driver needs to operate.
diff --git a/util/pkg/vfs/gsfs.go b/util/pkg/vfs/gsfs.go
index fdb23d2355..81228fafa2 100644
--- a/util/pkg/vfs/gsfs.go
+++ b/util/pkg/vfs/gsfs.go
@@ -428,7 +428,7 @@ func (p *GSPath) RenderTerraform(w *terraformWriter.TerraformWriter, name string
 		RoleEntity: make([]string, 0),
 		Provider:   terraformWriter.LiteralTokens("google", "files"),
 	}
-	for _, re := range acl.(GSAcl).Acl {
+	for _, re := range acl.(*GSAcl).Acl {
 		// https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_object_acl#role_entity
 		tfACL.RoleEntity = append(tfACL.RoleEntity, fmt.Sprintf("%v:%v", re.Role, re.Entity))
 	}


Test patch:
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_iam_role_policy_cluster-autoscaler.kube-system.sa.minimal.example.com_policy b/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_iam_role_policy_cluster-autoscaler.kube-system.sa.minimal.example.com_policy
index c199ab36e4..0b9e34dd1c 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_iam_role_policy_cluster-autoscaler.kube-system.sa.minimal.example.com_policy
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa/data/aws_iam_role_policy_cluster-autoscaler.kube-system.sa.minimal.example.com_policy
@@ -5,7 +5,6 @@
         "autoscaling:DescribeAutoScalingGroups",
         "autoscaling:DescribeAutoScalingInstances",
         "autoscaling:DescribeLaunchConfigurations",
-        "ec2:DescribeInstanceTypes",
         "ec2:DescribeLaunchTemplateVersions"
       ],
       "Effect": "Allow",
diff --git a/tests/integration/update_cluster/many-addons-ccm-irsa23/data/aws_iam_role_policy_cluster-autoscaler.kube-system.sa.minimal.example.com_policy b/tests/integration/update_cluster/many-addons-ccm-irsa23/data/aws_iam_role_policy_cluster-autoscaler.kube-system.sa.minimal.example.com_policy
index c199ab36e4..0b9e34dd1c 100644
--- a/tests/integration/update_cluster/many-addons-ccm-irsa23/data/aws_iam_role_policy_cluster-autoscaler.kube-system.sa.minimal.example.com_policy
+++ b/tests/integration/update_cluster/many-addons-ccm-irsa23/data/aws_iam_role_policy_cluster-autoscaler.kube-system.sa.minimal.example.com_policy
@@ -5,7 +5,6 @@
         "autoscaling:DescribeAutoScalingGroups",
         "autoscaling:DescribeAutoScalingInstances",
         "autoscaling:DescribeLaunchConfigurations",
-        "ec2:DescribeInstanceTypes",
         "ec2:DescribeLaunchTemplateVersions"
       ],
       "Effect": "Allow",
diff --git a/util/pkg/vfs/tests/gsfs_test.go b/util/pkg/vfs/tests/gsfs_test.go
index 3711395533..4301c56709 100644
--- a/util/pkg/vfs/tests/gsfs_test.go
+++ b/util/pkg/vfs/tests/gsfs_test.go
@@ -90,7 +90,7 @@ func TestGSRenderTerraform(t *testing.T) {
 			}
 			target := terraform.NewTerraformTarget(cloud, "", vfsProvider, "/dev/null", nil)
 
-			acl := vfs.GSAcl{
+			acl := &vfs.GSAcl{
 				Acl: []*storage.ObjectAccessControl{
 					{
 						Entity: fmt.Sprintf("user-%v", tc.serviceAcct),