diff --git a/charts/aws-efs-csi-driver/templates/controller-serviceaccount.yaml b/charts/aws-efs-csi-driver/templates/controller-serviceaccount.yaml index bc1d11d1a..48d1a90c1 100644 --- a/charts/aws-efs-csi-driver/templates/controller-serviceaccount.yaml +++ b/charts/aws-efs-csi-driver/templates/controller-serviceaccount.yaml @@ -40,12 +40,19 @@ rules: - apiGroups: ["coordination.k8s.io"] resources: ["leases"] verbs: ["get", "watch", "list", "delete", "update", "create"] - # - apiGroups: [ "" ] - # resources: [ "secrets" ] - # verbs: [ "get", "watch", "list" ] - --- - +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: efs-csi-external-provisioner-role-describe-secrets + labels: + app.kubernetes.io/name: {{ include "aws-efs-csi-driver.name" . }} +rules: + - apiGroups: [ "" ] + resources: [ "secrets" ] + resourceNames: ["x-account"] + verbs: [ "get", "watch", "list" ] +--- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: @@ -60,3 +67,20 @@ roleRef: kind: ClusterRole name: efs-csi-external-provisioner-role apiGroup: rbac.authorization.k8s.io +--- +# We use a RoleBinding to restrict Secret access to the namespace that the +# RoleBinding is created in (typically kube-system) +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: efs-csi-provisioner-binding-describe-secrets + labels: + app.kubernetes.io/name: {{ include "aws-efs-csi-driver.name" . }} +subjects: + - kind: ServiceAccount + name: {{ .Values.controller.serviceAccount.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: efs-csi-external-provisioner-role-describe-secrets + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/deploy/kubernetes/base/controller-serviceaccount.yaml b/deploy/kubernetes/base/controller-serviceaccount.yaml index 655c0268c..41fce01af 100644 --- a/deploy/kubernetes/base/controller-serviceaccount.yaml +++ b/deploy/kubernetes/base/controller-serviceaccount.yaml @@ -36,9 +36,19 @@ rules: - apiGroups: ["coordination.k8s.io"] resources: ["leases"] verbs: ["get", "watch", "list", "delete", "update", "create"] - # - apiGroups: [ "" ] - # resources: [ "secrets" ] - # verbs: [ "get", "watch", "list" ] +--- +# Source: aws-efs-csi-driver/templates/controller-serviceaccount.yaml +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: efs-csi-external-provisioner-role-describe-secrets + labels: + app.kubernetes.io/name: aws-efs-csi-driver +rules: + - apiGroups: [ "" ] + resources: [ "secrets" ] + resourceNames: ["x-account"] + verbs: [ "get", "watch", "list" ] --- # Source: aws-efs-csi-driver/templates/controller-serviceaccount.yaml kind: ClusterRoleBinding @@ -55,3 +65,20 @@ roleRef: kind: ClusterRole name: efs-csi-external-provisioner-role apiGroup: rbac.authorization.k8s.io +--- +# We use a RoleBinding to restrict Secret access to the namespace that the +# RoleBinding is created in (typically kube-system) +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: efs-csi-provisioner-binding-describe-secrets + labels: + app.kubernetes.io/name: aws-efs-csi-driver +subjects: + - kind: ServiceAccount + name: efs-csi-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: efs-csi-external-provisioner-role-describe-secrets + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/examples/kubernetes/cross_account_mount/iam-policy-examples/describe-mount-target-example.json b/examples/kubernetes/cross_account_mount/iam-policy-examples/describe-mount-target-example.json index 93b4428c5..102ec526c 100644 --- a/examples/kubernetes/cross_account_mount/iam-policy-examples/describe-mount-target-example.json +++ b/examples/kubernetes/cross_account_mount/iam-policy-examples/describe-mount-target-example.json @@ -1,24 +1,62 @@ { "Version": "2012-10-17", "Statement": [ - { - "Sid" : "Stmt1DescribeMountTargets", - "Effect": "Allow", - "Action": [ - "elasticfilesystem:DescribeFileSystems", - "elasticfilesystem:DescribeMountTargets", - "elasticfilesystem:CreateAccessPoint" - ], - "Resource": "arn:aws:elasticfilesystem:us-west-2:123456789012:file-system/file-system-ID" - }, - { - "Sid" : "Stmt2AdditionalEC2PermissionsToDescribeMountTarget", - "Effect": "Allow", - "Action": [ - "ec2:DescribeSubnets", - "ec2:DescribeNetworkInterfaces" - ], - "Resource": "*" - } + { + "Sid": "AllowDescribe", + "Effect": "Allow", + "Action": [ + "elasticfilesystem:DescribeAccessPoints", + "elasticfilesystem:DescribeFileSystems", + "elasticfilesystem:DescribeMountTargets", + "ec2:DescribeAvailabilityZones" + ], + "Resource": "*" + }, + { + "Sid": "AllowCreateAccessPoint", + "Effect": "Allow", + "Action": [ + "elasticfilesystem:CreateAccessPoint" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:RequestTag/efs.csi.aws.com/cluster": "false" + }, + "ForAllValues:StringEquals": { + "aws:TagKeys": "efs.csi.aws.com/cluster" + } + } + }, + { + "Sid": "AllowTagNewAccessPoints", + "Effect": "Allow", + "Action": [ + "elasticfilesystem:TagResource" + ], + "Resource": "*", + "Condition": { + "StringEquals": { + "elasticfilesystem:CreateAction": "CreateAccessPoint" + }, + "Null": { + "aws:RequestTag/efs.csi.aws.com/cluster": "false" + }, + "ForAllValues:StringEquals": { + "aws:TagKeys": "efs.csi.aws.com/cluster" + } + } + }, + { + "Sid": "AllowDeleteAccessPoint", + "Effect": "Allow", + "Action": "elasticfilesystem:DeleteAccessPoint", + "Resource": "*", + "Condition": { + "Null": { + "aws:ResourceTag/efs.csi.aws.com/cluster": "false" + } + } + } ] -} +} \ No newline at end of file diff --git a/pkg/cloud/k8s_metadata.go b/pkg/cloud/k8s_metadata.go index bf250aa6d..91ab339cc 100644 --- a/pkg/cloud/k8s_metadata.go +++ b/pkg/cloud/k8s_metadata.go @@ -44,7 +44,7 @@ func (k kubernetesApiMetadataProvider) getMetadata() (MetadataService, error) { return nil, fmt.Errorf("node providerID empty, cannot parse") } - re := regexp.MustCompile("i-[a-z0-9]+$") + re := regexp.MustCompile("i-[a-z0-9]+$|[a-z0-9]{32}") instanceID := re.FindString(providerId) if instanceID == "" { return nil, fmt.Errorf("did not find aws instance ID in node providerID string") diff --git a/pkg/cloud/k8s_metadata_test.go b/pkg/cloud/k8s_metadata_test.go index 6c329c624..54edc45da 100644 --- a/pkg/cloud/k8s_metadata_test.go +++ b/pkg/cloud/k8s_metadata_test.go @@ -78,6 +78,20 @@ func TestInstanceIdParsedFromProviderIdCorrectly(t *testing.T) { } } +func TestTaskIdParsedFromProviderIdCorrectly(t *testing.T) { + clientSet := setupKubernetesClient(t, nodeName, createFargateNode()) + k8sMp := kubernetesApiMetadataProvider{api: clientSet} + + metadata, err := k8sMp.getMetadata() + + if err != nil { + t.Fatalf("Error occurred when parsing instance ID, %v", err) + } + if metadata.GetInstanceID() != taskId { + t.Fatalf("Instance ID not extracted correctly, expected %s, got %s", taskId, metadata.GetInstanceID()) + } +} + func TestRegionAndZoneExtractedCorrectlyFromLabels(t *testing.T) { clientSet := setupKubernetesClient(t, nodeName, createDefaultNode()) k8sMp := kubernetesApiMetadataProvider{api: clientSet} @@ -123,3 +137,7 @@ func createNode(nodeName string, nodeRegion string, nodeZone string, providerId func createDefaultNode() *v1.Node { return createNode(nodeName, nodeRegion, nodeZone, fmt.Sprintf("aws:///%s/%s", nodeZone, instanceId)) } + +func createFargateNode() *v1.Node { + return createNode(nodeName, nodeRegion, nodeZone, fmt.Sprintf("aws:///%s/1234567890-%s/%s", nodeZone, taskId, nodeName)) +}