Skip to content

Conversation

@jklap
Copy link
Contributor

@jklap jklap commented Nov 20, 2025

Support use of json matching as a transformer such as:

sources:
  default:
...
    transformers:
      - jsonmatch:
          # search key as expected by daselV2 
          key: ".ver"
          # when a match is NOT found, then return this string 
          # The following special values are also recognized:
          # "<input>" -- will return the original input
          # "<blank>" -- will return an empty string, ie ""
          # Note: if this is not set and we don't find a result we will throw an exception
          nomatchresult: "<blank>"
          # if the key returns multiple values then join the multiple values by this string
          # Note: if this is not defined and we found multiple values we will throw an exception
          # Note: an empty string is not supported here
          joinmultiplematches: ","
          # if multiple values were found we can also choose to select one using "first" or "last" or "[x]" where X is an index
          # Note: "[0]" or "[-1]" can also be used to return the first or last value
          # Note: index is 0 based
          multiplevalueselector: "first"
Input Key Output Options
{ "ver": "1.17.0" } .ver 1.17.0 None
{ "key": "test" } .ver { "key": "test" } NoMatchResult="<input>"
{ "key": "test" } .ver "" NoMatchResult="<blank>"
{ "key": "test" } .ver {} NoMatchResult="{}"
{ "key": "test" } .ver Failure None
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() Failure None
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() 1.17.0 MultipleValueSelect="first"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() 1.17.1 MultipleValueSelect="last"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() 1.17.0 MultipleValueSelect="[0]"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() Failure MultipleValueSelect="[3]"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() 1.17.1 MultipleValueSelect="[-1]"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() 1.17.0 MultipleValueSelect="[-2]"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() Failure MultipleValueSelect="[-3]"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() Failure MultipleValueSelect="blah"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() Failure MultipleValueSelect="[blah]"
{ "ver": [ "1.17.0", "1.17.1" ] } .ver.all() 1.17.0,1.17.1 JoinMultipleMatches=","

@olblak
Copy link
Member

olblak commented Nov 21, 2025

Thanks for the PR

Isnt't the source of kind "json" enough?
You can have different kind of usage by looking at https://github.com/updatecli/updatecli/blob/main/e2e/updatecli.d/success.d/json.yaml

Have you considered chaining multiple sources with one of the kind "json" instead of using it in the transformers?
I like the transformer because it's more concise but I am concerned about adding a new way to achieve a similar behavior

@olblak olblak added the transformers Related to transformers label Nov 21, 2025
@jklap
Copy link
Contributor Author

jklap commented Nov 21, 2025

@olblak -- I'm not exactly sure what you mean by chaining sources together -- so

  1. curious about that, and
  2. Yes, had considered the JSON source.

The actual data is coming from an HTTP source -- and while I know you can use a URL with the JSON source, the HTTP call itself is a POST with a body (hence my other PR!) and additional auth headers, which can't be done with the simple URL support within the JSON source.

I had considered looking at supporting this type of HTTP support within the JSON source (and other file-based sources) but that looked like a much bigger change!

I had also considered (and even PoC'ed) a HTTP source -> File Target -> JSON source -> File Target... BUT that is a heck of a lot of steps vs just HTTP source (w/transformer) -> File Target...

I also felt that while that PoC was a viable solution (if clunky), it spreads the logic of getting the source data (and cleaning it) into multiple places... unlike simply using transforms within the originating source to output the data exactly as needed by the next steps.

To your concern though, I would suggest being able to process JSON data as both a source and as a transformer is actually powerful. Originally I thought it could deprecate the JSON source -- ie use a File source and a JSON transformer BUT I think the way you think about this is that the transformer is for more simple cases, or where (like my case) the source data isn't coming from a file whereas the JSON source is what you use if you need a more powerful solution, ie could support more powerful JSON handling in the future without overly complicating the transformers

@olblak
Copy link
Member

olblak commented Nov 22, 2025

Thanks for the detailed explanation.

I had considered looking at supporting this type of HTTP support within the JSON source (and other file-based sources) but that looked like a much bigger change!

I agree with your observation, we decided to add a HTTP source because we didn't want to bloat the current file sources used for json, yaml,etc.

@olblak -- I'm not exactly sure what you mean by chaining sources together -- so

When we need to pass information from one source to another one, we use something like:

sources:
    debian:
        name: get latest image tag for "debian"
        kind: dockerimage
        spec:
            image: debian
            tagfilter: ^\d*$
            versionfilter:
                kind: semver
                pattern: '>=8'
    debian-digest:
        dependson:
            - debian
        name: get latest image "debian" digest
        kind: dockerdigest
        spec:
            image: debian
            tag: '{{ source "debian" }}'

where dependson ensure that source "debian-digest" is executed after "debian"

That's how I thought about having a source of kind "HTTP" followed by a source of kind "JSON"

But I agree that your proposal about using a json transformer would simplify the manifest

@olblak olblak merged commit e1ebe34 into updatecli:main Nov 22, 2025
4 checks passed
@olblak olblak added the enhancement New feature or request label Nov 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request transformers Related to transformers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants