diff --git a/kubernetes/structures_container.go b/kubernetes/structures_container.go index 5562ef0366..5080331474 100644 --- a/kubernetes/structures_container.go +++ b/kubernetes/structures_container.go @@ -4,6 +4,7 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/intstr" + "regexp" ) func flattenCapability(in []v1.Capability) []string { @@ -259,6 +260,7 @@ func flattenValueFrom(in *v1.EnvVarSource) []interface{} { func flattenContainerVolumeMounts(in []v1.VolumeMount) ([]interface{}, error) { att := make([]interface{}, len(in)) + for i, v := range in { m := map[string]interface{}{} m["read_only"] = v.ReadOnly @@ -351,7 +353,7 @@ func flattenContainerResourceRequirements(in v1.ResourceRequirements) ([]interfa return []interface{}{att}, nil } -func flattenContainers(in []v1.Container) ([]interface{}, error) { +func flattenContainers(in []v1.Container, serviceAccountRegex string) ([]interface{}, error) { att := make([]interface{}, len(in)) for i, v := range in { c := make(map[string]interface{}) @@ -404,6 +406,18 @@ func flattenContainers(in []v1.Container) ([]interface{}, error) { } if len(v.VolumeMounts) > 0 { + for num, m := range v.VolumeMounts { + // To avoid perpetual diff, remove the default service account token volume from the container's list of volumeMounts. + nameMatchesDefaultToken, err := regexp.MatchString(serviceAccountRegex, m.Name) + if err != nil { + return att, err + } + if nameMatchesDefaultToken { + v.VolumeMounts = removeVolumeMountFromContainer(num, v.VolumeMounts) + break + } + } + volumeMounts, err := flattenContainerVolumeMounts(v.VolumeMounts) if err != nil { return nil, err @@ -415,6 +429,11 @@ func flattenContainers(in []v1.Container) ([]interface{}, error) { return att, nil } +// removeVolumeMountFromContainer removes the specified VolumeMount index (i) from the given list of VolumeMounts. +func removeVolumeMountFromContainer(i int, v []v1.VolumeMount) []v1.VolumeMount { + return append(v[:i], v[i+1:]...) +} + func expandContainers(ctrs []interface{}) ([]v1.Container, error) { if len(ctrs) == 0 { return []v1.Container{}, nil diff --git a/kubernetes/structures_pod.go b/kubernetes/structures_pod.go index 5453837bfe..1a66185e5c 100644 --- a/kubernetes/structures_pod.go +++ b/kubernetes/structures_pod.go @@ -3,6 +3,7 @@ package kubernetes import ( "fmt" "log" + "regexp" "strconv" "strings" @@ -27,7 +28,14 @@ func flattenPodSpec(in v1.PodSpec) ([]interface{}, error) { att["automount_service_account_token"] = *in.AutomountServiceAccountToken } - containers, err := flattenContainers(in.Containers) + // To avoid perpetual diff, remove the service account token volume from PodSpec. + serviceAccountName := "default" + if in.ServiceAccountName != "" { + serviceAccountName = in.ServiceAccountName + } + serviceAccountRegex := fmt.Sprintf("%s-token-([a-z0-9]{5})", serviceAccountName) + + containers, err := flattenContainers(in.Containers, serviceAccountRegex) if err != nil { return nil, err } @@ -39,7 +47,7 @@ func flattenPodSpec(in v1.PodSpec) ([]interface{}, error) { } att["readiness_gate"] = gates - initContainers, err := flattenContainers(in.InitContainers) + initContainers, err := flattenContainers(in.InitContainers, serviceAccountRegex) if err != nil { return nil, err } @@ -87,6 +95,7 @@ func flattenPodSpec(in v1.PodSpec) ([]interface{}, error) { if in.SecurityContext != nil { att["security_context"] = flattenPodSecurityContext(in.SecurityContext) } + if in.ServiceAccountName != "" { att["service_account_name"] = in.ServiceAccountName } @@ -107,6 +116,18 @@ func flattenPodSpec(in v1.PodSpec) ([]interface{}, error) { } if len(in.Volumes) > 0 { + for i, volume := range in.Volumes { + // To avoid perpetual diff, remove the service account token volume from PodSpec. + nameMatchesDefaultToken, err := regexp.MatchString(serviceAccountRegex, volume.Name) + if err != nil { + return []interface{}{att}, err + } + if nameMatchesDefaultToken { + in.Volumes = removeVolumeFromPodSpec(i, in.Volumes) + break + } + } + v, err := flattenVolumes(in.Volumes) if err != nil { return []interface{}{att}, err @@ -116,6 +137,11 @@ func flattenPodSpec(in v1.PodSpec) ([]interface{}, error) { return []interface{}{att}, nil } +// removeVolumeFromPodSpec removes the specified Volume index (i) from the given list of Volumes. +func removeVolumeFromPodSpec(i int, v []v1.Volume) []v1.Volume { + return append(v[:i], v[i+1:]...) +} + func flattenPodDNSConfig(in *v1.PodDNSConfig) ([]interface{}, error) { att := make(map[string]interface{})