Closed bryanlarsen closed 9 years ago
@bryanlarsen what is the use case here? Any reason you couldn't do something like:
service("consul")[0].IP
You are definitely opening yourself up to a panic there though...
Use case: starting registrator (and similar apps), which take as their arguments a single consul URL.
I tried what you suggest (surrounded by {{}}
) and I get: [ERR] template: out:1: unexpected "(" in operand; missing space?
. Adding spaces judiciously will get me past that but I can't get past unexpected "[" in operand; missing space?
The reason I'm trying 'index' is because that's what is mentioned in the text/template package documentation, there's no mention of a []
operator.
In my vagrant test box there's only a single consul running, so http://{{ range service "consul-8500" }}{{ .Address }}:{{ .Port }}{{ end }}
works fine. However, there will presumably be more than one consul running in a production environment, so I assume that would produce a very strange URL in that situation.
As far as the panic, this appears to work, and should prevent the panic.
{{ if gt ( len ( service "consul-8500" ) ) 0 }}
thanks for your help!
Awesome!
Sorry, the main issue hasn't been solved. I think I have a solution for the 'panic problem you raised', but I still cannot get the address or port of a single service.
{{range $index, $element := service "consul"}}
{{if $index == 0}}{{.IP}}{{end}}
{{end}}
There's also the index
function:
index
Returns the result of indexing its first argument by the
following arguments. Thus "index x 1 2 3" is, in Go syntax,
x[1][2][3]. Each indexed item must be a map, slice, or array.
That doesn't work, but this does:
{{range $index, $element := service "consul"}}
{{if eq $index 0}}{{.Address}}{{end}}
{{end}}
Thanks!
Also, the index
function is what I was trying originally, that didn't work.
I also ran across this recently. I'd like to know why the index
function (pipeline?) doesn't work…
This is old and closed, but certainly still a "gotcha". I spent an hour trying to figure out what I was doing wrong, only to realize this is a known issue.
Hey @nik-johnson-net, is the issue you were having a similar case to the original issue report here? Ie. something like {{ index (service "consul") 0 }}
?
Yes, exactly the same issue.
I've figured out what's going on here and why {{ index (service "consul") 0 }}
doesn't work.
Consul-template uses a multi-pass rendering strategy which means that templates need to work on the first pass with no data as that pass is used to start the async lookups in Consul (et al.).
So if you use index without checking the length it will always fail as the first time it will be called it will always have a 0 length.
The simplest way to deal with this is with a conditional around the index. Eg. (formatted for readability, not usefulness)
{{ $svs := (service "consul") }}
{{ if gt (len $svs) 0 }}
{{ index $svs 0 }}
{{end}}
There was a proposal (to golang) at one point to have index return nil in these cases which would have fixed this issue without requiring the test, but it was rejected as it made the template behavior different from the language behavior.
That golang proposal... https://github.com/golang/go/issues/14751
Suppose I would like to get the IP address of any consul agent. I would expect something like this to work:
What am I doing wrong? Thanks.