argoproj / argo-workflows

Workflow Engine for Kubernetes
https://argo-workflows.readthedocs.io/
Apache License 2.0
14.75k stars 3.15k forks source link

Generate jsonnet lib for workflows #1262

Open discordianfish opened 5 years ago

discordianfish commented 5 years ago

FEATURE REQUEST: Generate jsonnet lib for workflows

Even though workflows support parameters, often customization for workflow variants beyond that are necessary. This requires generating the manifests to avoid duplication.

jsonnet/ksonnet became the de facto standard for complex manifest generation in the kubernetes ecosystem.

Argo should provide jsonnet libs for creating a workflow (and eventually for all other argo CRDs like sensor and gateway).

Ideally we can generate the jsonnet lib from the swagger spec like ksonnet/ksonnet-lib does: https://github.com/ksonnet/ksonnet-lib/tree/master/ksonnet-gen

Ark-kun commented 5 years ago

AFAIK, ksonnet is deprecated. See https://ksonnet.io/

discordianfish commented 5 years ago

That is true but the term is a bit confusing the the first place. 'ksonnet' is actually two things: A set of command line tools, which are deprecated, as well as a jsonnet library that can be generated automatically from the swagger definitions in kubernetes. That one is heavily used and will continue to be maintained (even though AFAIK it's still not clear who will do that). Either way, jsonnet is here to stay and in the k8s ecosystem one of the most common ways to generate manifests from.

haq204 commented 4 years ago

Are there any updates or a timeline for this? It would be really nice to be able to create workflows and templates in jsonnet.

If bandwidth is low, may I offer my help in pushing this forward? I was originally planning to create a library for workflows internally anyway.

In terms of approach there are few questions:

  1. Should we continue to use ksonnet-lib? I know ksonnet the cli tool is deprecated but ksonnet-lib is sort of in limbo state since I've heard someone else will be maintaining it. I've recently came across https://github.com/jsonnet-libs/k8s-alpha which appears to be a rewrite of the autogenerator for ksonnet-lib for k8s versions 1.14 and later since ksonnet-lib ends at 1.14 and it appears to be a part of a broader initiative to standardize libraries in the jsonnet ecosystem so maybe there is a future?
  2. In terms of autogeneration from swagger spec, that would be ideal but considering there are only 4 crds? (Workflow, CronWorkflow, WorkflowTemplate, ClusterWorkflowTemplate) we could handwrite the templates for the poc to keeps things simple for now.
  3. Should we use jsonnet-bundler https://github.com/jsonnet-bundler/jsonnet-bundler? afaik it's the only tool out there for packaging jsonnet libraries.
dcherman commented 3 years ago

I cooked up a POC for this over the last day or so, would be interesting to get some feedback on it - https://github.com/argoproj/argo/pull/4819. I am brand new with jsonnet and not sure how it's normally documented, and I'm sure I need to provide some additional constructors for WorkflowTemplates, CronWorkflow, etc., however it'd be good to get some feedback before adding those in.

Cicatrice commented 3 years ago

Hello,

I tried to build the library myself based on jsonnet generator.

It built actually, but I notice that the library miss new() method that would populate apiVersion and kind properties. It generate a withKind() method that is not really helpful as it is expected that kind property to be automatically set by constructor.

Here is the result of `grep` on the generated lib

``` ❯ grep -Ri kind argo/workflows-3.0.2 argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowTemplateUpdateRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowTemplateUpdateRequest.libsonnet: withKind(kind): { template+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/lintCronWorkflowRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/lintCronWorkflowRequest.libsonnet: withKind(kind): { cronWorkflow+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/submitOpts.libsonnet: '#withKind':: d.fn(help='Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/submitOpts.libsonnet: withKind(kind): { ownerReference+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/clusterWorkflowTemplateCreateRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/clusterWorkflowTemplateCreateRequest.libsonnet: withKind(kind): { template+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowSubmitRequest.libsonnet: '#withKind':: d.fn(help='Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowSubmitRequest.libsonnet: withKind(kind): { submitOptions+: { ownerReference+: { kind: kind } } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowSubmitRequest.libsonnet: '#withResourceKind':: d.fn(help='', args=[d.arg(name='resourceKind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowSubmitRequest.libsonnet: withResourceKind(resourceKind): { resourceKind: resourceKind }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowTemplateLintRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowTemplateLintRequest.libsonnet: withKind(kind): { template+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowTemplate.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowTemplate.libsonnet: withKind(kind): { kind: kind }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/clusterWorkflowTemplate.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/clusterWorkflowTemplate.libsonnet: withKind(kind): { kind: kind }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflow.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflow.libsonnet: withKind(kind): { kind: kind }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowCreateRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowCreateRequest.libsonnet: withKind(kind): { workflow+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/clusterWorkflowTemplateLintRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/clusterWorkflowTemplateLintRequest.libsonnet: withKind(kind): { template+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/createCronWorkflowRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/createCronWorkflowRequest.libsonnet: withKind(kind): { cronWorkflow+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowTemplateCreateRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowTemplateCreateRequest.libsonnet: withKind(kind): { template+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowWatchEvent.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowWatchEvent.libsonnet: withKind(kind): { object+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowLintRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowLintRequest.libsonnet: withKind(kind): { workflow+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/updateCronWorkflowRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/updateCronWorkflowRequest.libsonnet: withKind(kind): { cronWorkflow+: { kind: kind } }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowEventBinding.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/workflowEventBinding.libsonnet: withKind(kind): { kind: kind }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/cronWorkflow.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/cronWorkflow.libsonnet: withKind(kind): { kind: kind }, argo/workflows-3.0.2/_gen/workflow/v1alpha1/clusterWorkflowTemplateUpdateRequest.libsonnet: '#withKind':: d.fn(help='Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.io.k8s.community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', args=[d.arg(name='kind', type=d.T.string)]), argo/workflows-3.0.2/_gen/workflow/v1alpha1/clusterWorkflowTemplateUpdateRequest.libsonnet: withKind(kind): { template+: { kind: kind } }, ```

I tried to generate another lib (Istio) and it is working as expected, so I suspect there may be a problem with swagger.json format.

It seems also that https://github.com/argoproj/argo-workflows/pull/4819 is affected too (I notice there is a hack to generate the new() method for Workflow; it would be awesome this method to be created automatically, and for the other kind as well).

I tried also to generate the library from http://localhost:8001/openapi/v2 even if that time new() method was here also the apiVersion and kind properties, but the spec methods were missing.

Sadly, I have no clue what could be missing to generate the library in a good shape.

BeyondEvil commented 2 years ago

Any updates here?