diff --git a/pkg/apiclient/argo-kube-client.go b/pkg/apiclient/argo-kube-client.go index 1c45a23be4e0..8fe3b13903c9 100644 --- a/pkg/apiclient/argo-kube-client.go +++ b/pkg/apiclient/argo-kube-client.go @@ -168,6 +168,8 @@ func (a *argoKubeClient) startStores(ctx context.Context, restConfig *restclient } else { a.cwfTmplStore = clusterworkflowtmplserver.NewClusterWorkflowTemplateClientStore() } + } else { + a.cwfTmplStore = clusterworkflowtmplserver.NewNullClusterWorkflowTemplate() } return nil diff --git a/server/apiserver/argoserver.go b/server/apiserver/argoserver.go index ae18b07a44ba..bcd25186a8c5 100644 --- a/server/apiserver/argoserver.go +++ b/server/apiserver/argoserver.go @@ -239,12 +239,14 @@ func (as *argoServer) Run(ctx context.Context, port int, browserOpenFunc func(st log.WithFatal().Error(ctx, err.Error()) } kubeclientset := kubernetes.NewForConfigOrDie(as.restConfig) - var cwftmplInformer *clusterworkflowtemplate.Informer + var cwftmplInformer clusterworkflowtemplate.ClusterWorkflowTemplateInformer if rbacutil.HasAccessToClusterWorkflowTemplates(ctx, kubeclientset, resourceCacheNamespace) { cwftmplInformer, err = clusterworkflowtemplate.NewInformer(as.restConfig) if err != nil { log.WithFatal().Error(ctx, err.Error()) } + } else { + cwftmplInformer = clusterworkflowtemplate.NewNullClusterWorkflowTemplate() } eventRecorderManager := events.NewEventRecorderManager(as.clients.Kubernetes) artifactRepositories := artifactrepositories.New(as.clients.Kubernetes, as.managedNamespace, &config.ArtifactRepository) diff --git a/server/clusterworkflowtemplate/informer.go b/server/clusterworkflowtemplate/informer.go index 7f435bc72932..212b517bb5ee 100644 --- a/server/clusterworkflowtemplate/informer.go +++ b/server/clusterworkflowtemplate/informer.go @@ -20,6 +20,11 @@ const ( workflowTemplateResyncPeriod = 20 * time.Minute ) +type ClusterWorkflowTemplateInformer interface { + Run(ctx context.Context, stopCh <-chan struct{}) + Getter(ctx context.Context) templateresolution.ClusterWorkflowTemplateGetter +} + var _ types.ClusterWorkflowTemplateStore = &Informer{} type Informer struct { @@ -56,9 +61,9 @@ func (cwti *Informer) Run(ctx context.Context, stopCh <-chan struct{}) { // if namespace contains empty string Lister will use the namespace provided during initialization func (cwti *Informer) Getter(ctx context.Context) templateresolution.ClusterWorkflowTemplateGetter { - if cwti.informer == nil { - logging.RequireLoggerFromContext(ctx).WithFatal().Error(ctx, "Template informer not started") - os.Exit(1) + if cwti == nil || cwti.informer == nil { + logging.RequireLoggerFromContext(ctx).Error(ctx, "Template informer not started") + return nil } return templateresolution.WrapClusterWorkflowTemplateLister(cwti.informer.Lister()) } diff --git a/server/clusterworkflowtemplate/null_client_store.go b/server/clusterworkflowtemplate/null_client_store.go new file mode 100644 index 000000000000..fd725e05f334 --- /dev/null +++ b/server/clusterworkflowtemplate/null_client_store.go @@ -0,0 +1,21 @@ +package clusterworkflowtemplate + +import ( + "context" + + "github.com/argoproj/argo-workflows/v3/workflow/templateresolution" +) + +// NullClusterWorkflowTemplateStore is a no-op implementation of ClusterWorkflowTemplateStore +// implements both informer and store interfaces +type NullClusterWorkflowTemplateStore struct{} + +func NewNullClusterWorkflowTemplate() *NullClusterWorkflowTemplateStore { + return &NullClusterWorkflowTemplateStore{} +} + +func (NullClusterWorkflowTemplateStore) Getter(context.Context) templateresolution.ClusterWorkflowTemplateGetter { + return &templateresolution.NullClusterWorkflowTemplateGetter{} +} + +func (NullClusterWorkflowTemplateStore) Run(ctx context.Context, stopCh <-chan struct{}) {}