| 4283 | } |
| 4284 | |
| 4285 | func (woc *wfOperationCtx) setExecWorkflow(ctx context.Context) error { |
| 4286 | if woc.wf.Spec.WorkflowTemplateRef != nil { // not-woc-misuse |
| 4287 | // When workflow restrictions require template referencing (Strict/Secure mode), |
| 4288 | // reject workflows that set any non-allowed fields, as they could override |
| 4289 | // security settings defined in the WorkflowTemplate. |
| 4290 | if woc.controller.Config.WorkflowRestrictions.MustUseReference() { // not-woc-misuse: intentionally checking the user-submitted spec |
| 4291 | if err := wfutil.ValidateUserOverrides(&woc.wf.Spec); err != nil { // not-woc-misuse |
| 4292 | woc.markWorkflowError(ctx, err) |
| 4293 | return err |
| 4294 | } |
| 4295 | } |
| 4296 | err := woc.setStoredWfSpec(ctx) |
| 4297 | if err != nil { |
| 4298 | woc.markWorkflowError(ctx, err) |
| 4299 | return err |
| 4300 | } |
| 4301 | woc.execWf = &wfv1.Workflow{Spec: *woc.wf.Status.StoredWorkflowSpec.DeepCopy()} |
| 4302 | woc.volumes = woc.execWf.Spec.DeepCopy().Volumes |
| 4303 | } else if woc.controller.Config.WorkflowRestrictions.MustUseReference() { |
| 4304 | err := fmt.Errorf("workflows must use workflowTemplateRef to be executed when the controller is in reference mode") |
| 4305 | woc.markWorkflowError(ctx, err) |
| 4306 | return err |
| 4307 | } else { |
| 4308 | err := woc.controller.setWorkflowDefaults(woc.wf) |
| 4309 | if err != nil { |
| 4310 | woc.markWorkflowError(ctx, err) |
| 4311 | return err |
| 4312 | } |
| 4313 | woc.volumes = woc.wf.Spec.DeepCopy().Volumes // not-woc-misuse |
| 4314 | } |
| 4315 | |
| 4316 | // Perform one-time workflow validation |
| 4317 | if woc.wf.Status.Phase == wfv1.WorkflowUnknown { |
| 4318 | validateOpts := validate.ValidateOpts{} |
| 4319 | wftmplGetter := templateresolution.WrapWorkflowTemplateInterface(woc.controller.wfclientset.ArgoprojV1alpha1().WorkflowTemplates(woc.wf.Namespace)) |
| 4320 | cwftmplGetter := templateresolution.WrapClusterWorkflowTemplateInterface(woc.controller.wfclientset.ArgoprojV1alpha1().ClusterWorkflowTemplates()) |
| 4321 | |
| 4322 | // Validate the execution wfSpec |
| 4323 | err := waitutil.Backoff(retry.DefaultRetry(ctx), |
| 4324 | func() (bool, error) { |
| 4325 | validationErr := validate.ValidateWorkflow(ctx, wftmplGetter, cwftmplGetter, woc.wf, woc.controller.Config.WorkflowDefaults, validateOpts) |
| 4326 | if validationErr != nil { |
| 4327 | return !errorsutil.IsTransientErr(ctx, validationErr), validationErr |
| 4328 | } |
| 4329 | return true, nil |
| 4330 | }) |
| 4331 | if err != nil { |
| 4332 | msg := fmt.Sprintf("invalid spec: %s", err.Error()) |
| 4333 | woc.markWorkflowFailed(ctx, msg) |
| 4334 | return err |
| 4335 | } |
| 4336 | } |
| 4337 | err := woc.setGlobalParameters(woc.execWf.Spec.Arguments) |
| 4338 | if err != nil { |
| 4339 | woc.markWorkflowFailed(ctx, fmt.Sprintf("failed to set global parameters: %s", err.Error())) |
| 4340 | return err |
| 4341 | } |
| 4342 | |