Azure / draft

A day 0 tool for getting your app on k8s fast
MIT License
493 stars 58 forks source link

Enhance the `draft info` output #266

Open peterbom opened 2 months ago

peterbom commented 2 months ago

Is your feature request related to a problem? Please describe.

It would be really nice if the info command could provide enough information to build an experience like that of the Azure Portal: image

In the above, selection of a language version allows consumers to infer both runtime and builder images, as well as a default port.

Mention what platform you want to support the new feature

All

Describe the solution you'd like

Currently, Draft outputs this (to take Java as an example):

    {
      "name": "java",
      "displayName": "Java",
      "variableExampleValues": {
        "BUILDERVERSION": [
          "3-jdk-11"
        ],
        "VERSION": [
          "8-jre",
          "11-jre",
          "17-jre",
          "19-jre"
        ]
      }

But an Azure Portal-like experience would require something like this:

{
    "name": "java",
    "displayName": "Java",
    "defaultPort": 8080,
    "versions": [
        {
            "name": "Java 8",
            "imageVersion": "8-jre",
            "builderVersion": "3-eclipse-temurin-8"
        },
        {
            "name": "Java 11",
            "imageVersion": "11-jre",
            "builderVersion": "3-eclipse-temurin-11"
        },
        {
            "name": "Java 17",
            "imageVersion": "17-jre",
            "builderVersion": "3-eclipse-temurin-17"
        },
        {
            "name": "Java 19",
            "imageVersion": "19-jre",
            "builderVersion": "3-eclipse-temurin-19"
        },
    ]
}

I.e. in addition to the current output, it would also allow consumers to extract:

Describe alternatives you've considered

As a consumer of Draft, I can maintain my own JSON mapping of languages to versions and ports, just as the Portal has to.

Additional context

I understand that maintaining a list of available versions (and associated images for each) is a maintenance overhead, but if Draft doesn't do that then consuming tools all have to, meaning it's hard to keep them in sync.

peterbom commented 2 months ago

I'm trying to piece together the original intent of the variableExampleValues property from #164 and #165, and I think a key comment is this, that "users are free to use languages beyond just what the CLI would pre-populate" (I assume that refers to language versions and build/runtime images).

That might suggest that what I'm asking for here is both infeasible, and actually too restrictive for users. I'm guessing the thinking behind the original feature is that it supports a UI for consuming tools in which users are presented with free-text fields for language/image versions, but with some examples/presets to aid them. Am I interpreting that correctly?

peterbom commented 2 months ago

If the ask for a reasonably comprehensive list of details for each language version is not feasible or sensible, an alternative thing that would be really useful would be builderImage and runtimeImage for each language. So, taking Java as an example:

{
    "name": "java",
    "displayName": "Java",
    "defaultPort": 8080,
    "builderImage": "maven",
    "runtimeImage": "eclipse-temurin",
}

That way, consuming applications can present some kind of UX that informs users what image they need to enter a tag/version for (e.g. maven), or potentially retrieve tags dynamically to allow user selection.

qpetraroia commented 2 months ago

Thanks @peterbom, I have ack'd this request.

davidgamero commented 2 months ago

thank you for including such a thorough description of the request, and i can see how including a display title while grouping the builder version would make it easier to best keep the options synchronized

i wonder where it would be best to store the display name within the draft.yaml as it looks like this:

language: java
displayName: Java
nameOverrides:
  - path: "dockerignore"
    prefix: "."
variables:
  - name: "PORT"
    description: "the port exposed in the application"
    type: int
  - name: "BUILDERVERSION"
    description: "the version of maven used during the builder stage to generate the executable"
    exampleValues: ["3-eclipse-temurin-11", "3-eclipse-temurin-17", "3-eclipse-temurin-21", "3 (jdk-21)"]
  - name: "VERSION"
    description: "the java version used by the application"
    exampleValues: ["11-jre","17-jre","19-jre","21-jre"]
variableDefaults:
  - name: "BUILDERVERSION"
    value: "3"
  - name: "VERSION"
    value: "21-jre"
  - name: "PORT"
    value: "80"

potentially adding an "exampleLabels" field or making exampleValues take a list of objects with value and label fields could solve this?

davidgamero commented 2 months ago

the "exampleLabels" approach would maintain backward compatibility, but make potentially jagged array configurations that would have to be validated externally, instead the "example object" approach would group it more naturally, but then you can have a label on both the VERSION and BUILDERVERSION either way

davidgamero commented 2 months ago

something like

type Example struct {
         Value string
         Label string
}
type BuilderVar struct {
    Name             string   `yaml:"name"`
    Description      string   `yaml:"description"`
    VarType          string   `yaml:"type"`
    ExampleValues    []Example `yaml:"exampleValues"`
    IsPromptDisabled bool     `yaml:"disablePrompt"`
}

since the BUILDERVERSION and VERSION are not intrinsically linked in the current config