runtime icon indicating copy to clipboard operation
runtime copied to clipboard

String interpolation consistency in AML

Open mamiu opened this issue 2 years ago • 14 comments

The doc section about Template secrets gives the following example:

// ...
secrets: {
    "my-template": {
        type: "template" // required
        data: {
            template: """  // required
            a long \(localData.configValue.key)
            a ${secret://my-secret-data/key}
            """
        }
    }
    "my-secret-data": {
        type: "opaque"
        data: {
            key: "value"
        }
    }
}

So there are two ways of string interpolation in AML (if this will become the name of the acorn markup language):

  • \(some.referenced.key) (e.g. \(localData.configValue.key))
  • ${custom-URI-scheme://object-name/attribute} (e.g. ${secret://my-secret-data/key})

But IMHO the markup language would benefit a lot from having just one way of doing string interpolations. Or at least offer to write all string interpolations in only one syntax, but still support both of the current syntaxes.

For example: Since I really like the idea of using custom URI schemes (similar to how it's done with deep linking on mobile devices) it would be great to support a few more schemes like ref or reference, var or variable, etc.

Then the example of the referenced key above would look like this: ${reference://localData.configValue.key}

Or the string interpolation in the two examples in the docs about Stateful applications and Templates could look like this: ${var://i} or ${variable://Name}

mamiu avatar Aug 16 '22 05:08 mamiu

Thanks for the feedback. There's an important technical difference between the two syntax. I 100% agree we should be consistent, but let me explain why they are currently different. The \(...) syntax is evaluated by the markup language at parsing time. The ${...} syntax is evaluated by the backend after the fact. The reason for this is that the AML parser does not have access to secrets, by design, it just has a "late binding" reference.

We can make the two syntax consistent but I am concerned that someone will get confused about the slight different in behavior. For example, the following string "password: \(std.base64(${secret://my-secret/data}) will never work because the parser evaluating the base64 function will not have the value of the secret to base64 encode.

ibuildthecloud avatar Aug 16 '22 14:08 ibuildthecloud

@vincent99 Ideas?

ibuildthecloud avatar Aug 16 '22 14:08 ibuildthecloud

Maybe turn the info only available at runtime into an explicitly named made-up top-level variable? \(runtime.secret["my-secret"].data)

vincent99 avatar Aug 16 '22 14:08 vincent99

Thanks for the explanation @ibuildthecloud.

Would it theoretically be possible to evaluate both string interpolations by the backend? Because not only would this enable a uniform syntax, but it would also make use cases like the one you mentioned possible.

Just in case it were possible, I think it made more sense not to use the custom URI scheme syntax for functions (e.g. like password: ${func://std.base64(secret://my-secret/data)}) but rather treat all non URI strings within string interpolations as functions calls (e.g. password: ${std.base64(secret://my-secret/data)}).

mamiu avatar Aug 18 '22 02:08 mamiu

There's a danger of people misusing secrets if we allow the parser to have the value. We also need to be able to render the acornfile without context to do things like validation. But maybe it's possible... I need to figure out what is the actual danger. Right now it's theoretical.

ibuildthecloud avatar Aug 18 '22 13:08 ibuildthecloud

I see what you're saying. Keen to hear about your assessment or decision once you've figured out the actual danger.

mamiu avatar Aug 18 '22 16:08 mamiu

I add to this that doc is not clear about interpolation or substitution. https://docs.acorn.io/authoring/args-and-profiles#in-a-string-or-template You need to stress the \(some.referenced.key) is needed. I've read it the "()" are good way, so at first I tried this "image: ghcr.io/huma-engineering/huma-score-engine-server:(args.tag)" that is rendering the same "image: ghcr.io/huma-engineering/huma-score-engine-server:(args.tag)" string.

$ acorn render .
acorns: {}
args:
  dev: false
  tag: 97cb9bd
containers:
  server:
    entrypoint:
    - python
    - main.py
    env:
      HU_SE_LOGIN: milano
      HU_SE_PASSWORD: password
    files: {}
    image: ghcr.io/huma-engineering/huma-score-engine-server:(args.tag)
    permissions:
      clusterRules: []
      rules: []
    ports:
      expose: []
      internal: []
      publish: 8000/http
    sidecars: {}
images: {}
jobs: {}
profiles:
  dev:
    dev: true
secrets: {}
volumes: {}

denist-huma avatar Aug 29 '22 10:08 denist-huma

@ibuildthecloud I prefer to use client side string interpolation, so I can use "acorn render". I is just as convinient as "helm template ." or "kubectl --dry-run"

The (...) syntax is evaluated by the markup language at parsing time.

denist-huma avatar Aug 29 '22 10:08 denist-huma

moving out of v.0.4.0 because i dont think we are going to get to all of the AML work in october

cjellick avatar Oct 05 '22 18:10 cjellick

I need @ibuildthecloud to speak to this

cjellick avatar May 31 '23 16:05 cjellick

I think @ibuildthecloud addressed this (maybe?)

cjellick avatar Jun 30 '23 23:06 cjellick

Maybe addressed in NEXT aml rewrite?

cjellick avatar Aug 25 '23 16:08 cjellick

Only thing left here is to document the difference between () and @{} and ${}.

cjellick avatar Nov 02 '23 23:11 cjellick

@ibuildthecloud wants to revisit all this interpolation

cjellick avatar Nov 15 '23 14:11 cjellick