diff --git a/test/e2e/manifests/minimal/kustomization.yaml b/test/e2e/manifests/minimal/kustomization.yaml index b1a5e2110728..2a2f4f702d76 100644 --- a/test/e2e/manifests/minimal/kustomization.yaml +++ b/test/e2e/manifests/minimal/kustomization.yaml @@ -8,6 +8,7 @@ resources: - https://raw.githubusercontent.com/argoproj/argo-events/stable/manifests/base/crds/argoproj.io_sensors.yaml - ../mixins/argo-workflows-agent-ca-certificates.yaml - ../mixins/argo-server.service-account-token-secret.yaml +- ../mixins/argo.service-account-token-secret.yaml patchesStrategicMerge: - ../mixins/argo-server-deployment.yaml diff --git a/test/e2e/manifests/mixins/argo.service-account-token-secret.yaml b/test/e2e/manifests/mixins/argo.service-account-token-secret.yaml new file mode 100644 index 000000000000..9cfb79e648d9 --- /dev/null +++ b/test/e2e/manifests/mixins/argo.service-account-token-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: argo.service-account-token + annotations: + kubernetes.io/service-account.name: argo +type: kubernetes.io/service-account-token \ No newline at end of file diff --git a/test/e2e/workflow_test.go b/test/e2e/workflow_test.go new file mode 100644 index 000000000000..53958206f385 --- /dev/null +++ b/test/e2e/workflow_test.go @@ -0,0 +1,90 @@ +//go:build functional +// +build functional + +package e2e + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/test/e2e/fixtures" +) + +type WorkflowSuite struct { + fixtures.E2ESuite +} + +func (s *WorkflowSuite) TestContainerTemplateAutomountServiceAccountTokenDisabled() { + s.Given().Workflow(` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: get-resources-via-container-template- + namespace: argo +spec: + serviceAccountName: argo + automountServiceAccountToken: false + executor: + serviceAccountName: argo + entrypoint: main + templates: + - name: main + container: + name: main + image: bitnami/kubectl + command: + - sh + args: + - -c + - | + kubectl get cm +`). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded, time.Minute*10). + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.WorkflowSucceeded, status.Phase) + }) +} + +func (s *WorkflowSuite) TestScriptTemplateAutomountServiceAccountTokenDisabled() { + s.Given().Workflow(` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: get-resources-via-script-template- + namespace: argo +spec: + serviceAccountName: argo + automountServiceAccountToken: false + executor: + serviceAccountName: argo + entrypoint: main + templates: + - name: main + script: + name: main + image: bitnami/kubectl + command: + - sh + source: + kubectl get cm +`). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded, time.Minute*10). + Then(). + ExpectWorkflow(func(t *testing.T, metadata *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.WorkflowSucceeded, status.Phase) + }) +} + +func TestWorkflowSuite(t *testing.T) { + suite.Run(t, new(WorkflowSuite)) +} diff --git a/workflow/controller/workflowpod.go b/workflow/controller/workflowpod.go index 803327c505a1..7f66f3b41045 100644 --- a/workflow/controller/workflowpod.go +++ b/workflow/controller/workflowpod.go @@ -222,6 +222,22 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin // container's PID and root filesystem. pod.Spec.Containers = append(pod.Spec.Containers, mainCtrs...) + // Configure service account token volume for the main container when AutomountServiceAccountToken is disabled + if (woc.execWf.Spec.AutomountServiceAccountToken != nil && !*woc.execWf.Spec.AutomountServiceAccountToken) || + (tmpl.AutomountServiceAccountToken != nil && !*tmpl.AutomountServiceAccountToken) { + for i, c := range pod.Spec.Containers { + if c.Name == common.WaitContainerName { + continue + } + c.VolumeMounts = append(c.VolumeMounts, apiv1.VolumeMount{ + Name: common.ServiceAccountTokenVolumeName, + MountPath: common.ServiceAccountTokenMountPath, + ReadOnly: true, + }) + pod.Spec.Containers[i] = c + } + } + // Configuring default container to be used with commands like "kubectl exec/logs". // Select "main" container if it's available. In other case use the last container (can happent when pod created from ContainerSet). defaultContainer := pod.Spec.Containers[len(pod.Spec.Containers)-1].Name