-
-
Notifications
You must be signed in to change notification settings - Fork 193
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
Add Consul & BoltDB datasource support #178
Conversation
dffe7a4
to
bf8e501
Compare
Please note integration tests are currently failing due to the Docker image not containing Consul |
Ok, cool - I'm adding |
Ok, I've added |
libkv.go
Outdated
sourceType = "" | ||
client = "" | ||
|
||
if strings.HasPrefix(url, "consul:") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change the function's signature to accept a *url.URL
, you can switch on url.Scheme
instead - would probably be a little less verbose, and cleaner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Had thought the same as I nodded off last night. Much cleaner and needed anyway for the BoltDB support
Looks like the Appveyor test is failing because it's testing a merged build. You'll need to rebase and adjust your use of Were you planning on adding integration tests for I would like to see unit tests too, if possible 🙂 Also, from looking at how |
Yes I'm hoping to add additional integration tests (once I figure out how to do so in a sensible way). The intention is to be able to specify multiple datasources & mix the types. What are you seeing that might not make that possible? |
1285da6
to
b58787e
Compare
Clearly it was too early in the morning for me when I read that code 😂 - I think I was thinking that |
Good. At least I've not messed something up |
libkv.go
Outdated
} | ||
options.ConnectionTimeout = time.Duration(num) * time.Second | ||
} | ||
if ssl := env.Getenv("CONSUL_HTTP_SSL", ""); ssl != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this necessary? Wouldn't the CONSUL_HTTP_ADDR
's scheme reflect whether it's HTTPS or not?
I do see that it doesn't have a scheme in the default above, and I think that should probably be changed.
Additionally, what might make sense (maybe in a followup PR though?) is to also support a consul://
URL that has the host in it, something like:
$ gomplate -d consul=consul+http://consul.server:8500/ -i '{{ ds "consul" "mykey" }}'
some value from consul...
Or with HTTPS:
$ gomplate -d consul=consul+https://tls-protected-consul.server:8533/ -i '{{ ds "consul" "mykey" }}'
some value from consul...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately CONSUL_HTTP_ADDR doesn't specify if it is TLS or not. Instead there is a separate CONSUL_HTTP_SSL option which needs setting to true if using TLS.
I'll look at adding consul+http / consul+https as additional options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stuart-c hmm... on the consul docs, CONSUL_HTTP_ADDR
doesn't refer to a remote Consul agent, but the local Consul agent that you're starting. So maybe we're overloading it in a bit of a confusing way.
Also, from the docs:
This can also be specified via the CONSUL_HTTP_ADDR environment
variable. The default value is http://127.0.0.1:8500. The scheme
can also be set to HTTPS by setting the environment variable
CONSUL_HTTP_SSL=true.
In that example (in https://www.consul.io/docs/commands/index.html) a scheme is used, but in a further example for CONSUL_HTTP_ADDR
directly, the value is scheme-less.
I'd recommend changing to CONSUL_URL
to reduce the confusion (and potential conflicts), and using the scheme to reflect TLS or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CONSUL_HTTP_ADDR is the expected environment variable:
http://techblog.zeomega.com/devops/golang/2015/06/09/consul-kv-api-in-golang.html
The reason it talks about "local agent" is that the expected usage is you run an agent on every machine (and therefore always refer to it as localhost), but the full servers (1, 3 or 5) are the ones which actually store the data and are talked to via the agents.
The go API will automatically pick up that env variable, it is just libkv which overwrites it.
I think it would be more confusing for users of Consul to have all the normal env variables (e.g. CONSUL_HTTP_TOKEN - as per https://www.consul.io/docs/commands/index.html#environment-variables) but then something totally different for the server address (a bit like we are using the same env variable for Vault as you would with the Vault CLI).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added support for consul+https, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The go API will automatically pick up that env variable, it is just libkv which overwrites it.
Ok, I understand.
Added support for consul+https, etc.
👍
libkv.go
Outdated
} | ||
if url.Scheme == "boltdb" { | ||
boltdb.Register() | ||
sourceType = store.BOLTDB | ||
client = url.Path | ||
if client == "" { | ||
client = env.Getenv("BOLTDB_PATH", "") | ||
client = env.Getenv("BOLTDB_DATABASE", "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you wouldn't just use url.Path
all the time? Or is there a use-case for setting the path with an environment variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind either way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, let's keep it simple and start by only supporting url.Path
- it's easy to add it later if necessary :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed
libkv.go
Outdated
logFatal("boltdb missing bucket") | ||
} | ||
if timeout := env.Getenv("BOLTDB_TIMEOUT", ""); timeout != "" { | ||
num, err := strconv.ParseInt(timeout, 10, 16) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a curiosity, why 16
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No real reason
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok 🙂
…passing BoltDB filename
…nvironment variables
…+http & etcd+https schemes
libkv/libkv.go
Outdated
if err != nil { | ||
logFatal("consul setup error", err) | ||
} | ||
s = setup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like an unnecessary assignment - could just name the variable setup
on ln39 and remove this (and the rest of the occurrences below
gomplate -d consul=consul:// -i '{{(datasource "consul" "foo")}}' | ||
[ "$status" -eq 0 ] | ||
[[ "${output}" == "$BATS_TEST_DESCRIPTION" ]] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add the following tests:
@test "Consul datasource works with hostname in URL" {
consul kv put foo "$BATS_TEST_DESCRIPTION"
unset CONSUL_HTTP_ADDR
gomplate -d consul=consul+http://localhost:8500/ -i '{{(datasource "consul" "foo")}}'
[ "$status" -eq 0 ]
[[ "${output}" == "$BATS_TEST_DESCRIPTION" ]]
}
@test "Consul datasource works with consul+http scheme" {
consul kv put foo "$BATS_TEST_DESCRIPTION"
unset CONSUL_HTTP_ADDR
gomplate -d consul=consul+http:// -i '{{(datasource "consul" "foo")}}'
[ "$status" -eq 0 ]
[[ "${output}" == "$BATS_TEST_DESCRIPTION" ]]
}
I guess it'd be pretty onerous to test consul+https
because we'd have to set up a self-signed cert... So no need for that now.
@stuart-c As useful as it is to have etcd and ZooKeeper support "for free" from How do you feel about removing the |
I've removed Etcd & Zookeeper from this PR (will re-add via separate PRs). I've added integration tests for BoltDB |
|
||
@test "Consul datasource works with consul+http scheme" { | ||
consul kv put foo "$BATS_TEST_DESCRIPTION" | ||
unset CONSUL_HTTP_ADDR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops - this actually won't work (since the addr isn't getting set in the URL on the next line)
It'd probably be best to set CONSUL_HTTP_ADDR
explicitly in setup
Looks like there are still dependencies in
Great! |
@stuart-c is there anything else you want to do with this PR, or do you think it's ready to go? I'm not seeing any unit tests, but I can add those later. There's also the question of docs - I can add those later too. |
I've just added some documentation. If you are happy looking after unit tests then I don't think I have anything further to add... |
Awesome! Thanks for the docs, they look good. Thanks so much for persisting with this, @stuart-c, I really appreciate it! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Currently tested with Consul, but will be possible to enable etcd, zookeeper & boltdb