diff --git a/workflow/controller/container_set_template.go b/workflow/controller/container_set_template.go index 87bdd00c9df7..d7b9efd62231 100644 --- a/workflow/controller/container_set_template.go +++ b/workflow/controller/container_set_template.go @@ -12,7 +12,7 @@ func (woc *wfOperationCtx) executeContainerSet(ctx context.Context, nodeName str if err != nil { node = woc.initializeExecutableNode(ctx, nodeName, wfv1.NodeTypePod, templateScope, tmpl, orgTmpl, opts.boundaryID, wfv1.NodePending, opts.nodeFlag) } - includeScriptOutput, err := woc.includeScriptOutput(nodeName, opts.boundaryID) + includeScriptOutput, err := woc.includeScriptOutput(ctx, nodeName, opts.boundaryID) if err != nil { return node, err } diff --git a/workflow/controller/dag.go b/workflow/controller/dag.go index 652b5b03f605..fbcbd8613f05 100644 --- a/workflow/controller/dag.go +++ b/workflow/controller/dag.go @@ -433,7 +433,7 @@ func (woc *wfOperationCtx) executeDAGTask(ctx context.Context, dagCtx *dagContex if node != nil && node.Fulfilled() { // Collect the completed task metrics - _, tmpl, _, tmplErr := dagCtx.tmplCtx.ResolveTemplate(task) + _, tmpl, _, tmplErr := dagCtx.tmplCtx.ResolveTemplate(ctx, task) if tmplErr != nil { woc.markNodeError(ctx, node.Name, tmplErr) return @@ -664,7 +664,7 @@ func (woc *wfOperationCtx) buildLocalScopeFromTask(ctx context.Context, dagCtx * ancestorNodes = append(ancestorNodes, node) } } - _, _, templateStored, err := dagCtx.tmplCtx.ResolveTemplate(ancestorNode) + _, _, templateStored, err := dagCtx.tmplCtx.ResolveTemplate(ctx, ancestorNode) if err != nil { return nil, errors.InternalWrapError(err) } diff --git a/workflow/controller/operator.go b/workflow/controller/operator.go index 79c2ca0f69b3..41ea3ad171e7 100644 --- a/workflow/controller/operator.go +++ b/workflow/controller/operator.go @@ -1905,7 +1905,7 @@ func (woc *wfOperationCtx) executeTemplate(ctx context.Context, nodeName string, return woc.initializeNodeOrMarkError(ctx, node, nodeName, templateScope, orgTmpl, opts.boundaryID, opts.nodeFlag, ErrMaxDepthExceeded), ErrMaxDepthExceeded } - newTmplCtx, resolvedTmpl, templateStored, err := tmplCtx.ResolveTemplate(orgTmpl) + newTmplCtx, resolvedTmpl, templateStored, err := tmplCtx.ResolveTemplate(ctx, orgTmpl) if err != nil { return woc.initializeNodeOrMarkError(ctx, node, nodeName, templateScope, orgTmpl, opts.boundaryID, opts.nodeFlag, err), err } @@ -2458,7 +2458,7 @@ func (woc *wfOperationCtx) GetNodeTemplate(ctx context.Context, node *wfv1.NodeS woc.markNodeError(ctx, node.Name, err) return nil, err } - tmpl, err := tmplCtx.GetTemplateFromRef(node.TemplateRef) + tmpl, err := tmplCtx.GetTemplateFromRef(ctx, node.TemplateRef) if err != nil { woc.markNodeError(ctx, node.Name, err) return tmpl, err @@ -2807,7 +2807,7 @@ func (woc *wfOperationCtx) checkParallelism(ctx context.Context, tmpl *wfv1.Temp return err } - boundaryTemplate, templateStored, err := woc.GetTemplateByBoundaryID(boundaryID) + boundaryTemplate, templateStored, err := woc.GetTemplateByBoundaryID(ctx, boundaryID) if err != nil { return err } @@ -2839,7 +2839,7 @@ func (woc *wfOperationCtx) executeContainer(ctx context.Context, nodeName string // Check if the output of this container is referenced elsewhere in the Workflow. If so, make sure to include it during // execution. - includeScriptOutput, err := woc.includeScriptOutput(nodeName, opts.boundaryID) + includeScriptOutput, err := woc.includeScriptOutput(ctx, nodeName, opts.boundaryID) if err != nil { return node, err } @@ -2873,7 +2873,7 @@ func (woc *wfOperationCtx) getOutboundNodes(ctx context.Context, nodeID string) if err != nil { return []string{node.ID} } - _, parentTemplate, _, err := tmplCtx.ResolveTemplate(node) + _, parentTemplate, _, err := tmplCtx.ResolveTemplate(ctx, node) if err != nil { return []string{node.ID} } @@ -3057,7 +3057,7 @@ func (woc *wfOperationCtx) executeScript(ctx context.Context, nodeName string, t // Check if the output of this script is referenced elsewhere in the Workflow. If so, make sure to include it during // execution. - includeScriptOutput, err := woc.includeScriptOutput(nodeName, opts.boundaryID) + includeScriptOutput, err := woc.includeScriptOutput(ctx, nodeName, opts.boundaryID) if err != nil { return node, err } @@ -3684,7 +3684,7 @@ func (woc *wfOperationCtx) createTemplateContext(scope wfv1.ResourceScope, resou } else { clusterWorkflowTemplateGetter = &templateresolution.NullClusterWorkflowTemplateGetter{} } - ctx := templateresolution.NewContext(woc.controller.wftmplInformer.Lister().WorkflowTemplates(woc.wf.Namespace), clusterWorkflowTemplateGetter, woc.execWf, woc.wf) + ctx := templateresolution.NewContext(woc.controller.wftmplInformer.Lister().WorkflowTemplates(woc.wf.Namespace), clusterWorkflowTemplateGetter, woc.execWf, woc.wf, woc.log) switch scope { case wfv1.ResourceScopeNamespaced: @@ -3868,12 +3868,12 @@ func (woc *wfOperationCtx) deletePDBResource(ctx context.Context) error { // Check if the output of this node is referenced elsewhere in the Workflow. If so, make sure to include it during // execution. -func (woc *wfOperationCtx) includeScriptOutput(nodeName, boundaryID string) (bool, error) { +func (woc *wfOperationCtx) includeScriptOutput(ctx context.Context, nodeName, boundaryID string) (bool, error) { if boundaryID == "" { return false, nil } - parentTemplate, templateStored, err := woc.GetTemplateByBoundaryID(boundaryID) + parentTemplate, templateStored, err := woc.GetTemplateByBoundaryID(ctx, boundaryID) if err != nil { return false, err } diff --git a/workflow/controller/steps.go b/workflow/controller/steps.go index 09bd56c4b405..a82670299f9c 100644 --- a/workflow/controller/steps.go +++ b/workflow/controller/steps.go @@ -141,7 +141,7 @@ func (woc *wfOperationCtx) executeSteps(ctx context.Context, nodeName string, tm } if len(childNodes) > 0 { // Expanded child nodes should be created from the same template. - _, _, templateStored, err := stepsCtx.tmplCtx.ResolveTemplate(&childNodes[0]) + _, _, templateStored, err := stepsCtx.tmplCtx.ResolveTemplate(ctx, &childNodes[0]) if err != nil { return node, err } diff --git a/workflow/controller/workflowpod.go b/workflow/controller/workflowpod.go index 6dcd7c96aa2d..86ed233c9372 100644 --- a/workflow/controller/workflowpod.go +++ b/workflow/controller/workflowpod.go @@ -54,7 +54,7 @@ var ( // scheduleOnDifferentHost adds affinity to prevent retry on the same host when // retryStrategy.affinity.nodeAntiAffinity{} is specified -func (woc *wfOperationCtx) scheduleOnDifferentHost(node *wfv1.NodeStatus, pod *apiv1.Pod) error { +func (woc *wfOperationCtx) scheduleOnDifferentHost(ctx context.Context, node *wfv1.NodeStatus, pod *apiv1.Pod) error { if node != nil && pod != nil { if retryNode := FindRetryNode(woc.wf.Status.Nodes, node.ID); retryNode != nil { // recover template for the retry node @@ -62,7 +62,7 @@ func (woc *wfOperationCtx) scheduleOnDifferentHost(node *wfv1.NodeStatus, pod *a if err != nil { return err } - _, retryTmpl, _, err := tmplCtx.ResolveTemplate(retryNode) + _, retryTmpl, _, err := tmplCtx.ResolveTemplate(ctx, retryNode) if err != nil { return err } @@ -496,7 +496,7 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin return nil, err } - if err := woc.scheduleOnDifferentHost(node, pod); err != nil { + if err := woc.scheduleOnDifferentHost(ctx, node, pod); err != nil { return nil, err } @@ -830,7 +830,7 @@ func (woc *wfOperationCtx) GetBoundaryTemplate(ctx context.Context, nodeName str woc.log.Warnf(ctx, "couldn't retrieve node for nodeName %s, will get nil templateDeadline", nodeName) return nil, err } - boundaryTmpl, _, err := woc.GetTemplateByBoundaryID(node.BoundaryID) + boundaryTmpl, _, err := woc.GetTemplateByBoundaryID(ctx, node.BoundaryID) if err != nil { return nil, err } @@ -838,7 +838,7 @@ func (woc *wfOperationCtx) GetBoundaryTemplate(ctx context.Context, nodeName str } // GetTemplateByBoundaryID get a template through the node's BoundaryID. -func (woc *wfOperationCtx) GetTemplateByBoundaryID(boundaryID string) (*wfv1.Template, bool, error) { +func (woc *wfOperationCtx) GetTemplateByBoundaryID(ctx context.Context, boundaryID string) (*wfv1.Template, bool, error) { boundaryNode, err := woc.wf.Status.Nodes.Get(boundaryID) if err != nil { return nil, false, err @@ -847,7 +847,7 @@ func (woc *wfOperationCtx) GetTemplateByBoundaryID(boundaryID string) (*wfv1.Tem if err != nil { return nil, false, err } - _, boundaryTmpl, templateStored, err := tmplCtx.ResolveTemplate(boundaryNode) + _, boundaryTmpl, templateStored, err := tmplCtx.ResolveTemplate(ctx, boundaryNode) if err != nil { return nil, templateStored, err } diff --git a/workflow/templateresolution/context.go b/workflow/templateresolution/context.go index 131864685887..02b9f04208ca 100644 --- a/workflow/templateresolution/context.go +++ b/workflow/templateresolution/context.go @@ -4,13 +4,13 @@ import ( "context" "fmt" - log "github.com/sirupsen/logrus" apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-workflows/v3/errors" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" typed "github.com/argoproj/argo-workflows/v3/pkg/client/clientset/versioned/typed/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/util/logging" "github.com/argoproj/argo-workflows/v3/workflow/common" ) @@ -73,35 +73,35 @@ type Context struct { tmplBase wfv1.TemplateHolder // workflow is the Workflow where templates will be stored workflow *wfv1.Workflow - // log is a logrus entry. - log *log.Entry + // log is a logging entry. + log logging.Logger } // NewContext returns new Context. -func NewContext(wftmplGetter WorkflowTemplateNamespacedGetter, cwftmplGetter ClusterWorkflowTemplateGetter, tmplBase wfv1.TemplateHolder, workflow *wfv1.Workflow) *Context { +func NewContext(wftmplGetter WorkflowTemplateNamespacedGetter, cwftmplGetter ClusterWorkflowTemplateGetter, tmplBase wfv1.TemplateHolder, workflow *wfv1.Workflow, log logging.Logger) *Context { return &Context{ wftmplGetter: wftmplGetter, cwftmplGetter: cwftmplGetter, tmplBase: tmplBase, workflow: workflow, - log: log.WithFields(log.Fields{}), + log: log, } } // NewContextFromClientSet returns new Context. -func NewContextFromClientSet(wftmplClientset typed.WorkflowTemplateInterface, clusterWftmplClient typed.ClusterWorkflowTemplateInterface, tmplBase wfv1.TemplateHolder, workflow *wfv1.Workflow) *Context { +func NewContextFromClientSet(wftmplClientset typed.WorkflowTemplateInterface, clusterWftmplClient typed.ClusterWorkflowTemplateInterface, tmplBase wfv1.TemplateHolder, workflow *wfv1.Workflow, log logging.Logger) *Context { return &Context{ wftmplGetter: WrapWorkflowTemplateInterface(wftmplClientset), cwftmplGetter: WrapClusterWorkflowTemplateInterface(clusterWftmplClient), tmplBase: tmplBase, workflow: workflow, - log: log.WithFields(log.Fields{}), + log: log, } } // GetTemplateByName returns a template by name in the context. -func (ctx *Context) GetTemplateByName(name string) (*wfv1.Template, error) { - ctx.log.Debugf("Getting the template by name: %s", name) +func (ctx *Context) GetTemplateByName(c context.Context, name string) (*wfv1.Template, error) { + ctx.log.Debugf(c, "Getting the template by name: %s", name) tmpl := ctx.tmplBase.GetTemplateByName(name) if tmpl == nil { @@ -118,8 +118,8 @@ func (ctx *Context) GetTemplateGetterFromRef(tmplRef *wfv1.TemplateRef) (wfv1.Te } // GetTemplateFromRef returns a template found by a given template ref. -func (ctx *Context) GetTemplateFromRef(tmplRef *wfv1.TemplateRef) (*wfv1.Template, error) { - ctx.log.Debug("Getting the template from ref") +func (ctx *Context) GetTemplateFromRef(c context.Context, tmplRef *wfv1.TemplateRef) (*wfv1.Template, error) { + ctx.log.Debug(c, "Getting the template from ref") var template *wfv1.Template var wftmpl wfv1.TemplateHolder var err error @@ -145,14 +145,14 @@ func (ctx *Context) GetTemplateFromRef(tmplRef *wfv1.TemplateRef) (*wfv1.Templat } // GetTemplate returns a template found by template name or template ref. -func (ctx *Context) GetTemplate(h wfv1.TemplateReferenceHolder) (*wfv1.Template, error) { - ctx.log.Debug("Getting the template") +func (ctx *Context) GetTemplate(c context.Context, h wfv1.TemplateReferenceHolder) (*wfv1.Template, error) { + ctx.log.Debug(c, "Getting the template") if x := h.GetTemplate(); x != nil { return x, nil } else if x := h.GetTemplateRef(); x != nil { - return ctx.GetTemplateFromRef(x) + return ctx.GetTemplateFromRef(c, x) } else if x := h.GetTemplateName(); x != "" { - return ctx.GetTemplateByName(x) + return ctx.GetTemplateByName(c, x) } return nil, errors.Errorf(errors.CodeInternal, "failed to get a template") } @@ -168,20 +168,20 @@ func (ctx *Context) GetTemplateScope() string { // ResolveTemplate digs into referenes and returns a merged template. // This method is the public start point of template resolution. -func (ctx *Context) ResolveTemplate(tmplHolder wfv1.TemplateReferenceHolder) (*Context, *wfv1.Template, bool, error) { - return ctx.resolveTemplateImpl(tmplHolder) +func (ctx *Context) ResolveTemplate(c context.Context, tmplHolder wfv1.TemplateReferenceHolder) (*Context, *wfv1.Template, bool, error) { + return ctx.resolveTemplateImpl(c, tmplHolder) } // resolveTemplateImpl digs into references and returns a merged template. // This method processes inputs and arguments so the inputs of the final // resolved template include intermediate parameter passing. // The other fields are just merged and shallower templates overwrite deeper. -func (ctx *Context) resolveTemplateImpl(tmplHolder wfv1.TemplateReferenceHolder) (*Context, *wfv1.Template, bool, error) { - ctx.log = ctx.log.WithFields(log.Fields{ +func (ctx *Context) resolveTemplateImpl(c context.Context, tmplHolder wfv1.TemplateReferenceHolder) (*Context, *wfv1.Template, bool, error) { + ctx.log = ctx.log.WithFields(c, logging.Fields{ "base": common.GetTemplateGetterString(ctx.tmplBase), "tmpl": common.GetTemplateHolderString(tmplHolder), }) - ctx.log.Debug("Resolving the template") + ctx.log.Debug(c, "Resolving the template") templateStored := false var tmpl *wfv1.Template @@ -192,10 +192,10 @@ func (ctx *Context) resolveTemplateImpl(tmplHolder wfv1.TemplateReferenceHolder) tmpl = ctx.workflow.GetStoredTemplate(scope, resourceName, tmplHolder) } if tmpl != nil { - ctx.log.Debug("Found stored template") + ctx.log.Debug(c, "Found stored template") } else { // Find newly appeared template. - newTmpl, err := ctx.GetTemplate(tmplHolder) + newTmpl, err := ctx.GetTemplate(c, tmplHolder) if err != nil { return nil, nil, false, err } @@ -208,12 +208,12 @@ func (ctx *Context) resolveTemplateImpl(tmplHolder wfv1.TemplateReferenceHolder) return nil, nil, false, err } if stored { - ctx.log.Debug("Stored the template") + ctx.log.Debug(c, "Stored the template") templateStored = true } err = ctx.workflow.SetStoredInlineTemplate(scope, resourceName, newTmpl) if err != nil { - ctx.log.Errorf("Failed to store the inline template: %v", err) + ctx.log.Errorf(c, "Failed to store the inline template: %v", err) } } tmpl = newTmpl @@ -248,7 +248,7 @@ func (ctx *Context) WithTemplateHolder(tmplHolder wfv1.TemplateReferenceHolder) // WithTemplateBase creates new context with a wfv1.TemplateHolder. func (ctx *Context) WithTemplateBase(tmplBase wfv1.TemplateHolder) *Context { - return NewContext(ctx.wftmplGetter, ctx.cwftmplGetter, tmplBase, ctx.workflow) + return NewContext(ctx.wftmplGetter, ctx.cwftmplGetter, tmplBase, ctx.workflow, ctx.log) } // WithWorkflowTemplate creates new context with a wfv1.TemplateHolder. diff --git a/workflow/templateresolution/context_test.go b/workflow/templateresolution/context_test.go index 70abade41c04..9fe2148c7fe3 100644 --- a/workflow/templateresolution/context_test.go +++ b/workflow/templateresolution/context_test.go @@ -12,6 +12,7 @@ import ( wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" wfclientset "github.com/argoproj/argo-workflows/v3/pkg/client/clientset/versioned" fakewfclientset "github.com/argoproj/argo-workflows/v3/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-workflows/v3/util/logging" ) func createWorkflowTemplate(wfClientset wfclientset.Interface, yamlStr string) error { @@ -103,14 +104,16 @@ spec: func TestGetTemplateByName(t *testing.T) { wfClientset := fakewfclientset.NewSimpleClientset() wftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml) - ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil) + log := logging.NewSlogLogger() + c := context.Background() + ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil, log) - tmpl, err := ctx.GetTemplateByName("whalesay") + tmpl, err := ctx.GetTemplateByName(c, "whalesay") require.NoError(t, err) assert.Equal(t, "whalesay", tmpl.Name) assert.NotNil(t, tmpl.Container) - _, err = ctx.GetTemplateByName("unknown") + _, err = ctx.GetTemplateByName(c, "unknown") require.EqualError(t, err, "template unknown not found") } @@ -125,23 +128,25 @@ func TestGetTemplateFromRef(t *testing.T) { t.Fatal(err) } wftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml) - ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil) + log := logging.NewSlogLogger() + c := context.Background() + ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil, log) // Get the template of existing template reference. tmplRef := wfv1.TemplateRef{Name: "some-workflow-template", Template: "whalesay"} - tmpl, err := ctx.GetTemplateFromRef(&tmplRef) + tmpl, err := ctx.GetTemplateFromRef(c, &tmplRef) require.NoError(t, err) assert.Equal(t, "whalesay", tmpl.Name) assert.NotNil(t, tmpl.Container) // Get the template of unexisting template reference. tmplRef = wfv1.TemplateRef{Name: "unknown-workflow-template", Template: "whalesay"} - _, err = ctx.GetTemplateFromRef(&tmplRef) + _, err = ctx.GetTemplateFromRef(c, &tmplRef) require.EqualError(t, err, "workflow template unknown-workflow-template not found") // Get the template of unexisting template name of existing template reference. tmplRef = wfv1.TemplateRef{Name: "some-workflow-template", Template: "unknown"} - _, err = ctx.GetTemplateFromRef(&tmplRef) + _, err = ctx.GetTemplateFromRef(c, &tmplRef) require.EqualError(t, err, "template unknown not found in workflow template some-workflow-template") } @@ -156,37 +161,40 @@ func TestGetTemplate(t *testing.T) { t.Fatal(err) } wftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml) - ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil) + log := logging.NewSlogLogger() + c := context.Background() + ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil, log) // Get the template of existing template name. tmplHolder := wfv1.WorkflowStep{Template: "whalesay"} - tmpl, err := ctx.GetTemplate(&tmplHolder) + tmpl, err := ctx.GetTemplate(c, &tmplHolder) require.NoError(t, err) assert.Equal(t, "whalesay", tmpl.Name) assert.NotNil(t, tmpl.Container) // Get the template of unexisting template name. tmplHolder = wfv1.WorkflowStep{Template: "unexisting"} - _, err = ctx.GetTemplate(&tmplHolder) + _, err = ctx.GetTemplate(c, &tmplHolder) require.EqualError(t, err, "template unexisting not found") // Get the template of existing template reference. tmplHolder = wfv1.WorkflowStep{TemplateRef: &wfv1.TemplateRef{Name: "some-workflow-template", Template: "whalesay"}} - tmpl, err = ctx.GetTemplate(&tmplHolder) + tmpl, err = ctx.GetTemplate(c, &tmplHolder) require.NoError(t, err) assert.Equal(t, "whalesay", tmpl.Name) assert.NotNil(t, tmpl.Container) // Get the template of unexisting template reference. tmplHolder = wfv1.WorkflowStep{TemplateRef: &wfv1.TemplateRef{Name: "unknown-workflow-template", Template: "whalesay"}} - _, err = ctx.GetTemplate(&tmplHolder) + _, err = ctx.GetTemplate(c, &tmplHolder) require.EqualError(t, err, "workflow template unknown-workflow-template not found") } func TestGetCurrentTemplateBase(t *testing.T) { wfClientset := fakewfclientset.NewSimpleClientset() wftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml) - ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil) + log := logging.NewSlogLogger() + ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil, log) // Get the template base of existing template name. tmplBase := ctx.GetCurrentTemplateBase() @@ -206,7 +214,8 @@ func TestWithTemplateHolder(t *testing.T) { t.Fatal(err) } wftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml) - ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil) + log := logging.NewSlogLogger() + ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil, log) var tmplGetter wfv1.TemplateHolder // Get the template base of existing template name. @@ -248,11 +257,13 @@ func TestResolveTemplate(t *testing.T) { require.NoError(t, err) wftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml) - ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil) + log := logging.NewSlogLogger() + c := context.Background() + ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil, log) // Get the template of template name. tmplHolder := wfv1.WorkflowStep{Template: "whalesay"} - ctx, tmpl, _, err := ctx.ResolveTemplate(&tmplHolder) + ctx, tmpl, _, err := ctx.ResolveTemplate(c, &tmplHolder) require.NoError(t, err) wftmpl, ok := ctx.tmplBase.(*wfv1.WorkflowTemplate) require.True(t, ok, "tmplBase is not a WorkflowTemplate") @@ -262,7 +273,7 @@ func TestResolveTemplate(t *testing.T) { var tmplGetter wfv1.TemplateHolder // Get the template of template reference. tmplHolder = wfv1.WorkflowStep{TemplateRef: &wfv1.TemplateRef{Name: "some-workflow-template", Template: "whalesay"}} - ctx, tmpl, _, err = ctx.ResolveTemplate(&tmplHolder) + ctx, tmpl, _, err = ctx.ResolveTemplate(c, &tmplHolder) require.NoError(t, err) tmplGetter, ok = ctx.tmplBase.(*wfv1.WorkflowTemplate) @@ -273,7 +284,7 @@ func TestResolveTemplate(t *testing.T) { // Get the template of local nested template reference. tmplHolder = wfv1.WorkflowStep{TemplateRef: &wfv1.TemplateRef{Name: "some-workflow-template", Template: "local-whalesay"}} - ctx, tmpl, _, err = ctx.ResolveTemplate(&tmplHolder) + ctx, tmpl, _, err = ctx.ResolveTemplate(c, &tmplHolder) require.NoError(t, err) tmplGetter, ok = ctx.tmplBase.(*wfv1.WorkflowTemplate) @@ -284,7 +295,7 @@ func TestResolveTemplate(t *testing.T) { // Get the template of nested template reference. tmplHolder = wfv1.WorkflowStep{TemplateRef: &wfv1.TemplateRef{Name: "some-workflow-template", Template: "another-whalesay"}} - ctx, tmpl, _, err = ctx.ResolveTemplate(&tmplHolder) + ctx, tmpl, _, err = ctx.ResolveTemplate(c, &tmplHolder) require.NoError(t, err) tmplGetter, ok = ctx.tmplBase.(*wfv1.WorkflowTemplate) @@ -297,7 +308,7 @@ func TestResolveTemplate(t *testing.T) { tmplHolder = wfv1.WorkflowStep{ TemplateRef: &wfv1.TemplateRef{Name: "some-workflow-template", Template: "whalesay-with-arguments"}, } - ctx, tmpl, _, err = ctx.ResolveTemplate(&tmplHolder) + ctx, tmpl, _, err = ctx.ResolveTemplate(c, &tmplHolder) require.NoError(t, err) tmplGetter, ok = ctx.tmplBase.(*wfv1.WorkflowTemplate) @@ -309,7 +320,7 @@ func TestResolveTemplate(t *testing.T) { tmplHolder = wfv1.WorkflowStep{ TemplateRef: &wfv1.TemplateRef{Name: "some-workflow-template", Template: "nested-whalesay-with-arguments"}, } - ctx, tmpl, _, err = ctx.ResolveTemplate(&tmplHolder) + ctx, tmpl, _, err = ctx.ResolveTemplate(c, &tmplHolder) require.NoError(t, err) tmplGetter, ok = ctx.tmplBase.(*wfv1.WorkflowTemplate) @@ -321,7 +332,8 @@ func TestResolveTemplate(t *testing.T) { func TestWithTemplateBase(t *testing.T) { wfClientset := fakewfclientset.NewSimpleClientset() wftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml) - ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil) + log := logging.NewSlogLogger() + ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil, log) anotherWftmpl := unmarshalWftmpl(anotherWorkflowTemplateYaml) @@ -335,7 +347,8 @@ func TestWithTemplateBase(t *testing.T) { func TestOnWorkflowTemplate(t *testing.T) { wfClientset := fakewfclientset.NewSimpleClientset() wftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml) - ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil) + log := logging.NewSlogLogger() + ctx := NewContextFromClientSet(wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault), wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(), wftmpl, nil, log) err := createWorkflowTemplate(wfClientset, anotherWorkflowTemplateYaml) require.NoError(t, err) diff --git a/workflow/validate/validate.go b/workflow/validate/validate.go index 2856d30fd447..6f5bf31cd713 100644 --- a/workflow/validate/validate.go +++ b/workflow/validate/validate.go @@ -22,6 +22,7 @@ import ( wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util" "github.com/argoproj/argo-workflows/v3/util/intstr" + "github.com/argoproj/argo-workflows/v3/util/logging" "github.com/argoproj/argo-workflows/v3/util/sorting" "github.com/argoproj/argo-workflows/v3/util/template" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/hdfs" @@ -140,7 +141,8 @@ func validateHooks(hooks wfv1.LifecycleHooks, hookBaseName string) error { // ValidateWorkflow accepts a workflow and performs validation against it. func ValidateWorkflow(wftmplGetter templateresolution.WorkflowTemplateNamespacedGetter, cwftmplGetter templateresolution.ClusterWorkflowTemplateGetter, wf *wfv1.Workflow, opts ValidateOpts) error { ctx := newTemplateValidationCtx(wf, opts) - tmplCtx := templateresolution.NewContext(wftmplGetter, cwftmplGetter, wf, wf) + log := logging.NewSlogLogger() + tmplCtx := templateresolution.NewContext(wftmplGetter, cwftmplGetter, wf, wf, log) var wfSpecHolder wfv1.WorkflowSpecHolder var wfTmplRef *wfv1.TemplateRef var err error @@ -557,7 +559,7 @@ func (tctx *templateValidationCtx) validateTemplateHolder(tmplHolder wfv1.Templa return nil, nil } } else if tmplName != "" { - _, err := tmplCtx.GetTemplateByName(tmplName) + _, err := tmplCtx.GetTemplateByName(ctx, tmplName) if err != nil { if argoerr, ok := err.(errors.ArgoError); ok && argoerr.Code() == errors.CodeNotFound { return nil, errors.Errorf(errors.CodeBadRequest, "template name '%s' undefined", tmplName) @@ -566,7 +568,7 @@ func (tctx *templateValidationCtx) validateTemplateHolder(tmplHolder wfv1.Templa } } - tmplCtx, resolvedTmpl, _, err := tmplCtx.ResolveTemplate(tmplHolder) + tmplCtx, resolvedTmpl, _, err := tmplCtx.ResolveTemplate(ctx, tmplHolder) if err != nil { if argoerr, ok := err.(errors.ArgoError); ok && argoerr.Code() == errors.CodeNotFound { if tmplRef != nil {