Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report Templates for Home Assistant, JSON and at Large #1267

Open
fanuch opened this issue Apr 8, 2022 · 6 comments
Open

Report Templates for Home Assistant, JSON and at Large #1267

fanuch opened this issue Apr 8, 2022 · 6 comments

Comments

@fanuch
Copy link

fanuch commented Apr 8, 2022

Having the same needs as #1203 for notifications to be handled by Home Assistant, I've gone down the rabbit hole and have a means to potentially contribute to #1204

The ability to format messages in JSON template would be really valuable for manipulation down-stream.

My apologies as my go is quite underdeveloped but I came up with this go template solution:

template='
[
    {{ $len := len .Entries }}
    {{range $idx, $e := .Entries }}
        {
            "level": "{{ $e.Level}}",
            "message": "{{ $e.Message}}"
            {{println}}
        }{{if ne ($idx) (Dec $len)}},{{end}}
    {{end}}
]'

and ran with the following as a test:

./watchtower \
    --notifications shoutrrr \
    --notification-url "$url" \
    --notification-template "$template" \
    --debug \
    --run-once \
    --no-pull \
    --notification-report \
    --monitor-only 

Which results in:

[
  {
    "level": "info",
    "message": "Watchtower v1.4.0-3-ga5c60a9"
  },
  {
    "level": "info",
    "message": "Using notifications: generic"
  },
  {
    "level": "info",
    "message": "Checking all containers (except explicitly disabled with label)"
  },
  {
    "level": "info",
    "message": "Running a one time update."
  }
]

Two notes

  1. For some reason, rendering on {{ range . }} (as is every example) fails as Data.Report are returned as nil. This forced me to run {{ range .Entries }} instead.
  2. I couldn't determine any way to avoid an extra , at the end of the JSON array which may be problematic. I had to add in my own template function for decrement so that the final loop index would be able to match the size of the slice. Simply added:
func getShoutrrrTemplate(tplString string, legacy bool) (tpl *template.Template, err error) {
	funcs := template.FuncMap{
		"ToUpper": strings.ToUpper,
		"ToLower": strings.ToLower,
		"Title":   strings.Title,
                // I added this part in
                "Dec": func(i int) int {
                    return i - 1
                 },
          }

What do you think? Is there a way to make this a little neater? Does this help with documenting the notification-report issue?

@piksel
Copy link
Member

piksel commented Apr 8, 2022

  1. This is due to --notification-report which adds the .Report extra data to the template data (and moves the entries into .Entries). .Report is only populated at the end of a "Session", it then contains the number of containers checked/updated/failed etc.

  2. You could add the comma at the start instead:

[
    {{range $idx, $e := .Entries }}
        {{if ne $idx 0)}},{{end}}{
            "level": "{{ $e.Level}}",
            "message": "{{ $e.Message}}"
            {{println}}
        }
    {{end}}
]

Thanks a lot for your effort, it does help a lot. Hopefully I will get time this or the next weekend to put together something. My idea is to basically mimic the Data struct in JSON, so it will be more like:

{ 
    "entries": [
        {{- range $idx, $e := .Entries -}}
        {{- if ne $idx 0 -}},{{- end}}
        {
            "level": "{{ $e.Level}}",
            "message": "{{ $e.Message}}"
        }{{end}}
    ],
    "report": {{if .Report -}}{{- with .Report -}}{
        scanned: {{len .Scanned}},
        updated: {{len .Updated}},
        failed: {{len .Failed}},
        skipped: {{len .Skipped}},
        stale: {{len .Stale}},
        fresh: {{len .Fresh}},
    }{{- end -}}{{- else -}}null{{- end}}
}

goplay link

I would like to include information about the containers as well though, but I haven't written that part yet.

@fanuch
Copy link
Author

fanuch commented Apr 9, 2022

I'm happy I could help - even in a small way!

  1. Thanks for explaining what happened on .Report - I was starting to thing I was doing something very wrong.
  2. I'm dumb. That's a way better suggestion haha

Your rendered template looks amazing and I will definitely be using that 👍

I would like to include information about the containers as well though

That would be a good addition.

If you wouldn't mind pointing me to a stub I would be happy to start fleshing out some documentation around this as a PR to help others

@stale
Copy link

stale bot commented Jun 13, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale label Jun 13, 2022
@piksel
Copy link
Member

piksel commented Jun 15, 2022

I still aim to do this at some point...

@stale stale bot removed the Status: Stale label Jun 15, 2022
@evantaur
Copy link

evantaur commented Dec 1, 2023

spent a while trying to get this to work (Go is absolute mystery to me), not sure if this helps anyone else but here's what i did

it only sends updates and failed notifications in JSON payload:

{
  "title" : "watchtower",
  "message" : "updated the following containers:\n- container 1\n - container 2"
}

Template:

{{- if .Report -}}
 {{- with .Report -}}
  {{- if (or .Updated .Failed) -}} 
{ "title": "Watchtower", "message": "updated the following containers:\n{{- range .Updated }}\n- {{.Name}} ({{.ImageName}}): {{.CurrentImageID.ShortID}} updated to {{.LatestImageID.ShortID}}
   {{- end }}
   {{- if .Failed }}\n\nFailed to update:
    {{- range .Failed }}\n- {{.Name}} ({{.ImageName}}): {{.State}}: {{.Error}}
    {{- end }}
  {{- end - }}
" }
  {{- end -}}
 {{- end -}}
{{- end -}}

image
Edit: updated txt file since github absolutely butchered the formatting

docker.txt

@piksel
Copy link
Member

piksel commented Dec 2, 2023

I don't think this is mentioned in the docs, but if you put json.v1 as the template it will give you a JSON representation of the notification data.

Also you can use the template preview (alpha quality) to easier test your templates:
https://containrrr.dev/watchtower/template-preview/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants