From 04c3bae2ef589aac748dbfca833bc47fb58f22af Mon Sep 17 00:00:00 2001 From: Becca Petrin Date: Mon, 10 Jun 2019 09:19:11 -0700 Subject: [PATCH] add elasticsearch database engine --- go.mod | 1 + go.sum | 4 + helper/builtinplugins/registry.go | 14 +- .../.gitignore | 19 + .../LICENSE | 373 ++++++++++++++++++ .../Makefile | 39 ++ .../README.md | 138 +++++++ .../client.go | 231 +++++++++++ .../elasticsearch.go | 336 ++++++++++++++++ .../go.mod | 16 + .../go.sum | 147 +++++++ vendor/golang.org/x/sys/unix/syscall_unix.go | 6 +- .../golang.org/x/sys/unix/ztypes_linux_386.go | 3 + .../x/sys/unix/ztypes_linux_amd64.go | 3 + .../golang.org/x/sys/unix/ztypes_linux_arm.go | 3 + .../x/sys/unix/ztypes_linux_arm64.go | 3 + .../x/sys/unix/ztypes_linux_mips.go | 3 + .../x/sys/unix/ztypes_linux_mips64.go | 3 + .../x/sys/unix/ztypes_linux_mips64le.go | 3 + .../x/sys/unix/ztypes_linux_mipsle.go | 3 + .../x/sys/unix/ztypes_linux_ppc64.go | 3 + .../x/sys/unix/ztypes_linux_ppc64le.go | 3 + .../x/sys/unix/ztypes_linux_riscv64.go | 3 + .../x/sys/unix/ztypes_linux_s390x.go | 3 + .../x/sys/unix/ztypes_linux_sparc64.go | 3 + vendor/modules.txt | 4 +- .../api/secret/databases/elasticdb.html.md | 100 +++++ .../docs/secrets/databases/elasticdb.html.md | 173 ++++++++ 28 files changed, 1632 insertions(+), 8 deletions(-) create mode 100644 vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/.gitignore create mode 100644 vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/LICENSE create mode 100644 vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/Makefile create mode 100644 vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/README.md create mode 100644 vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/client.go create mode 100644 vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/elasticsearch.go create mode 100644 vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.mod create mode 100644 vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.sum create mode 100644 website/source/api/secret/databases/elasticdb.html.md create mode 100644 website/source/docs/secrets/databases/elasticdb.html.md diff --git a/go.mod b/go.mod index b1de25ed4f..bd727fc4f3 100644 --- a/go.mod +++ b/go.mod @@ -74,6 +74,7 @@ require ( github.com/hashicorp/vault-plugin-auth-gcp v0.5.1 github.com/hashicorp/vault-plugin-auth-jwt v0.5.1 github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.1 + github.com/hashicorp/vault-plugin-database-elasticsearch v0.0.0-20190508211750-4152192cdc0f github.com/hashicorp/vault-plugin-secrets-ad v0.5.1 github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.1 github.com/hashicorp/vault-plugin-secrets-azure v0.5.1 diff --git a/go.sum b/go.sum index 1e6442fedc..6bb330ad4b 100644 --- a/go.sum +++ b/go.sum @@ -275,6 +275,8 @@ github.com/hashicorp/vault-plugin-auth-jwt v0.5.1 h1:d9WLI7oF6VMtwBZwS5bbChc4kW+ github.com/hashicorp/vault-plugin-auth-jwt v0.5.1/go.mod h1:5VU7gc6/BEEFQW/viqMs3LBxI1D1cxJmKqKQEP3JUP4= github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.1 h1:q6DGb12Vw/CpZ9xDWAmpzxVRKeClFqRFgbIZ3fZcvuY= github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.1/go.mod h1:qCDsm0njdfUrnN5sFKMLjxGjZKjQf2qB6dReQ4gr4YI= +github.com/hashicorp/vault-plugin-database-elasticsearch v0.0.0-20190508211750-4152192cdc0f h1:BYQVawXauMXQ26I3Pn1Nw9kp/aZD60xmh9ZP3jum0YM= +github.com/hashicorp/vault-plugin-database-elasticsearch v0.0.0-20190508211750-4152192cdc0f/go.mod h1:CkOYWfeuC5nAzehBztl94S6VOn2g50h1tffpcNoWCZ8= github.com/hashicorp/vault-plugin-secrets-ad v0.5.1 h1:BdiASUZLOvOUs317EnaUNjGxTSw0PYGQA7zJZhDKLC4= github.com/hashicorp/vault-plugin-secrets-ad v0.5.1/go.mod h1:EH9CI8+0aWRBz8eIgGth0QjttmHWlGvn+8ZmX/ZUetE= github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.1 h1:72K91p4uLhT/jgtBq2zV5Wn8ocvny4sAN56XOcTxK1w= @@ -558,6 +560,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e h1:nFYrTHrdrAOpShe27kaFHjsqYSEQ0KWqdWLu3xuZJts= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190410170021-cc4d4f50624c h1:OUGWoQpM/o3TxM7Fp3CEqRpaYCbg4H1hOVPnZoUtr2U= +golang.org/x/sys v0.0.0-20190410170021-cc4d4f50624c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/helper/builtinplugins/registry.go b/helper/builtinplugins/registry.go index 699f3d6fcd..1b585c05a7 100644 --- a/helper/builtinplugins/registry.go +++ b/helper/builtinplugins/registry.go @@ -21,6 +21,7 @@ import ( credRadius "github.com/hashicorp/vault/builtin/credential/radius" credUserpass "github.com/hashicorp/vault/builtin/credential/userpass" + dbElastic "github.com/hashicorp/vault-plugin-database-elasticsearch" dbCass "github.com/hashicorp/vault/plugins/database/cassandra" dbHana "github.com/hashicorp/vault/plugins/database/hana" dbInflux "github.com/hashicorp/vault/plugins/database/influxdb" @@ -86,12 +87,13 @@ func newRegistry() *registry { "mysql-rds-database-plugin": dbMysql.New(credsutil.NoneLength, dbMysql.LegacyMetadataLen, dbMysql.LegacyUsernameLen), "mysql-legacy-database-plugin": dbMysql.New(credsutil.NoneLength, dbMysql.LegacyMetadataLen, dbMysql.LegacyUsernameLen), - "postgresql-database-plugin": dbPostgres.New, - "mssql-database-plugin": dbMssql.New, - "cassandra-database-plugin": dbCass.New, - "mongodb-database-plugin": dbMongo.New, - "hana-database-plugin": dbHana.New, - "influxdb-database-plugin": dbInflux.New, + "postgresql-database-plugin": dbPostgres.New, + "mssql-database-plugin": dbMssql.New, + "cassandra-database-plugin": dbCass.New, + "mongodb-database-plugin": dbMongo.New, + "hana-database-plugin": dbHana.New, + "influxdb-database-plugin": dbInflux.New, + "elasticsearch-database-plugin": dbElastic.New, }, logicalBackends: map[string]logical.Factory{ "ad": logicalAd.Factory, diff --git a/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/.gitignore b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/.gitignore new file mode 100644 index 0000000000..05a65e4d0c --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/.gitignore @@ -0,0 +1,19 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Jetbrains IDE +.idea* + +# binaries and such +bin/* +pkg/* diff --git a/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/LICENSE b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/LICENSE new file mode 100644 index 0000000000..a612ad9813 --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/Makefile b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/Makefile new file mode 100644 index 0000000000..e475147199 --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/Makefile @@ -0,0 +1,39 @@ +# Determine this makefile's path. +# Be sure to place this BEFORE `include` directives, if any. +THIS_FILE := $(lastword $(MAKEFILE_LIST)) + +TEST?=$$(go list ./... | grep -v /vendor/ | grep -v /integ) +GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor) +EXTERNAL_TOOLS=\ + github.com/mitchellh/gox + +default: dev + +# bin generates the releaseable binaries for vault-plugin-database-elasticsearch +bin: fmtcheck generate + @CGO_ENABLED=1 BUILD_TAGS='$(BUILD_TAGS)' XC_ARCH="amd64" XC_OS="linux" XC_OSARCH="linux/amd64" sh -c "'$(CURDIR)/scripts/build.sh'" + +dev: fmtcheck + @CGO_ENABLED=1 BUILD_TAGS='$(BUILD_TAGS)' VAULT_DEV_BUILD=1 sh -c "'$(CURDIR)/scripts/build.sh'" + +# test runs the unit tests and vets the code +test: fmtcheck generate + CGO_ENABLED=1 go test -v -short -tags='$(BUILD_TAGS)' $(TEST) $(TESTARGS) -timeout=20m -parallel=1 + +testacc: fmtcheck generate + VAULT_ACC=1 VAULT_ADDR=http://localhost:8200 VAULT_TOKEN=root CGO_ENABLED=1 go test -v -race -tags='$(BUILD_TAGS)' $(TEST) $(TESTARGS) -timeout=20m -parallel=1 + +fmtcheck: + @sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'" + +fmt: + gofmt -w -s $(GOFMT_FILES) + +# bootstrap the build by downloading additional tools +bootstrap: + @for tool in $(EXTERNAL_TOOLS) ; do \ + echo "Installing/Updating $$tool" ; \ + go get -u $$tool; \ + done + +.PHONY: bin default generate test testacc fmt fmtcheck dev bootstrap \ No newline at end of file diff --git a/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/README.md b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/README.md new file mode 100644 index 0000000000..2ac74de0bb --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/README.md @@ -0,0 +1,138 @@ +# Elasticsearch Database Secrets Engine +This plugin provides unique, short-lived credentials for Elasticsearch using native X-Pack Security. + +## Getting Started + +To take advantage of this plugin, you must first enable Elasticsearch's native realm of security by activating X-Pack. These +instructions will walk you through doing this using ElasticSearch 6.6.1. At the time of writing, X-Pack was a paid feature. +To use it, you may need to enable a 30-day trial with Elasticsearch, or activate a paid version. + +### Enable X-Pack Security in Elasticsearch + +Read [Securing the Elastic Stack](https://www.elastic.co/guide/en/elastic-stack-overview/6.6/elasticsearch-security.html) and +follow [its instructions for enabling X-Pack Security](https://www.elastic.co/guide/en/elasticsearch/reference/6.6/setup-xpack.html). +When done, verify that you've enabled X-Pack by running `$ $ES_HOME/bin/elasticsearch-setup-passwords interactive`. You'll +know it's been set up successfully if it takes you through a number of password-inputting steps. + +### Recommended: Enable Encrypted Communications + +This plugin communicates with Elasticsearch's security API. We recommend you enable TLS for these communications so they can be +encrypted. + +To set up TLS in Elasticsearch, first read [encrypted communications](https://www.elastic.co/guide/en/elastic-stack-overview/6.6/encrypting-communications.html) +and go through its instructions on [encrypting HTTP client communications](https://www.elastic.co/guide/en/elasticsearch/reference/6.6/configuring-tls.html#tls-http). + +After enabling TLS on the Elasticsearch side, you'll need to convert the .p12 certificates you generated to other formats so they can be +used by Vault. [Here is an example using OpenSSL](https://stackoverflow.com/questions/15144046/converting-pkcs12-certificate-into-pem-using-openssl) +to convert our .p12 certs to the pem format. + +Also, on the instance running Elasticsearch, we needed to install our newly generated CA certificate that was originally in the .p12 format. +We did this by converting the .p12 CA cert to a pem, and then further converting that +[pem to a crt](https://stackoverflow.com/questions/13732826/convert-pem-to-crt-and-key), adding that crt to `/usr/share/ca-certificates/extra`, +and using `sudo dpkg-reconfigure ca-certificates`. + +The above instructions may vary if you are not using an Ubuntu machine. Please ensure you're using the methods specific to your operating +environment. Describing every operating environment is outside the scope of these instructions. + +### Create a Role for Vault + +Next, in Elasticsearch, we recommend that you create a user just for Vault to use in managing secrets. + +To do this, first create a role that will allow Vault the minimum privileges needed to administer users and passwords by performing a +POST to Elasticsearch. To do this, we used the `elastic` superuser whose password we created in the +`$ $ES_HOME/bin/elasticsearch-setup-passwords interactive` step. + +``` +$ curl \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"cluster": ["manage_security"]}' \ + http://elastic:$PASSWORD@localhost:9200/_xpack/security/role/vault +``` + +Next, create a user for Vault associated with that role. + +``` +$ curl \ + -X POST \ + -H "Content-Type: application/json" \ + -d @data.json \ + http://elastic:$PASSWORD@localhost:9200/_xpack/security/user/vault +``` + +The contents of `data.json` in this example are: +``` +{ + "password" : "myPa55word", + "roles" : [ "vault" ], + "full_name" : "Hashicorp Vault", + "metadata" : { + "plugin_name": "Vault Plugin Secrets ElasticSearch", + "plugin_url": "https://github.com/hashicorp/vault-plugin-secrets-elasticsearch" + } +} +``` + +Now, Elasticsearch is configured and ready to be used with Vault. + +## Example Walkthrough + +Here is an example of how to successfully configure and use this secrets engine using the Vault CLI. Note that the +`plugin_name` may need to be `vault-plugin-database-elasticsearch` if you manually mounted it rather than using the +version of the plugin built in to Vault. +``` +export ES_HOME=/home/somewhere/Applications/elasticsearch-6.6.1 + +vault secrets enable database + +vault write database/config/my-elasticsearch-database \ + plugin_name="elasticsearch-database-plugin" \ + allowed_roles="internally-defined-role,externally-defined-role" \ + username=vault \ + password=myPa55word \ + url=http://localhost:9200 \ + ca_cert=/usr/share/ca-certificates/extra/elastic-stack-ca.crt.pem \ + client_cert=$ES_HOME/config/certs/elastic-certificates.crt.pem \ + client_key=$ES_HOME/config/certs/elastic-certificates.key.pem + +# create and get creds with one type of role +vault write database/roles/internally-defined-role \ + db_name=my-elasticsearch-database \ + creation_statements='{"elasticsearch_role_definition": {"indices": [{"names":["*"], "privileges":["read"]}]}}' \ + default_ttl="1h" \ + max_ttl="24h" + +vault read database/creds/internally-defined-role + +# create and get creds with another type of role +vault write database/roles/externally-defined-role \ + db_name=my-elasticsearch-database \ + creation_statements='{"elasticsearch_roles": ["vault"]}' \ + default_ttl="1h" \ + max_ttl="24h" + +vault read database/creds/externally-defined-role + +# renew credentials +vault lease renew database/creds/internally-defined-role/nvJ6SveX9PN1E4BlxVWdKuX1 + +# revoke credentials +vault lease revoke database/creds/internally-defined-role/nvJ6SveX9PN1E4BlxVWdKuX1 + +# rotate root credentials +vault write -force database/rotate-root/my-elasticsearch-database +``` + +## Developing + +The Vault plugin system is documented on the [Vault documentation site](https://www.vaultproject.io/docs/internals/plugins.html). + +You will need to define a plugin directory using the `plugin_directory` configuration directive, then place the `vault-plugin-database-elasticsearch` executable generated above in the directory. + +Register the plugin using + +``` +vault write sys/plugins/catalog/vault-plugin-database-elasticsearch \ + sha256=$(sha256sum bin/vault-plugin-database-elasticsearch) \ + command="vault-plugin-database-elasticsearch" +``` diff --git a/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/client.go b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/client.go new file mode 100644 index 0000000000..b5adbfeef3 --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/client.go @@ -0,0 +1,231 @@ +package elasticsearch + +/* +This lightweight client implements only the methods needed for this secrets engine. +It consumes this API: +https://www.elastic.co/guide/en/elasticsearch/reference/6.6/security-api.html +*/ + +import ( + "bytes" + "context" + "crypto/tls" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/hashicorp/go-retryablehttp" + "github.com/hashicorp/go-rootcerts" +) + +type ClientConfig struct { + Username, Password, BaseURL string + + // Leave this nil to flag that TLS is not desired + TLSConfig *TLSConfig +} + +// TLSConfig contains the parameters needed to configure TLS on the HTTP client +// used to communicate with Elasticsearch. +type TLSConfig struct { + // CACert is the path to a PEM-encoded CA cert file to use to verify theHTTPClient + // Elasticsearch server SSL certificate. + CACert string + + // CAPath is the path to a directory of PEM-encoded CA cert files to verify + // the Elasticsearch server SSL certificate. + CAPath string + + // ClientCert is the path to the certificate for Elasticsearch communication + ClientCert string + + // ClientKey is the path to the private key for Elasticsearch communication + ClientKey string + + // TLSServerName, if set, is used to set the SNI host when connecting via + // TLS. + TLSServerName string + + // Insecure enables or disables SSL verification + Insecure bool +} + +func NewClient(config *ClientConfig) (*Client, error) { + client := retryablehttp.NewClient() + if config.TLSConfig != nil { + conf := &tls.Config{ + ServerName: config.TLSConfig.TLSServerName, + InsecureSkipVerify: config.TLSConfig.Insecure, + MinVersion: tls.VersionTLS12, + } + if config.TLSConfig.ClientCert != "" && config.TLSConfig.ClientKey != "" { + clientCertificate, err := tls.LoadX509KeyPair(config.TLSConfig.ClientCert, config.TLSConfig.ClientKey) + if err != nil { + return nil, err + } + conf.Certificates = append(conf.Certificates, clientCertificate) + } + if config.TLSConfig.CACert != "" || config.TLSConfig.CAPath != "" { + rootConfig := &rootcerts.Config{ + CAFile: config.TLSConfig.CACert, + CAPath: config.TLSConfig.CAPath, + } + if err := rootcerts.ConfigureTLS(conf, rootConfig); err != nil { + return nil, err + } + } + + client.HTTPClient.Transport = &http.Transport{TLSClientConfig: conf} + } + return &Client{ + username: config.Username, + password: config.Password, + baseURL: config.BaseURL, + client: client, + }, nil +} + +type Client struct { + username, password, baseURL string + client *retryablehttp.Client +} + +// Role management + +func (c *Client) CreateRole(ctx context.Context, name string, role map[string]interface{}) error { + endpoint := "/_xpack/security/role/" + name + method := http.MethodPost + + roleBytes, err := json.Marshal(role) + if err != nil { + return err + } + req, err := http.NewRequest(method, c.baseURL+endpoint, bytes.NewReader(roleBytes)) + if err != nil { + return err + } + return c.do(ctx, req, nil) +} + +// GetRole returns nil, nil if role is unfound. +func (c *Client) GetRole(ctx context.Context, name string) (map[string]interface{}, error) { + endpoint := "/_xpack/security/role/" + name + method := http.MethodGet + + req, err := http.NewRequest(method, c.baseURL+endpoint, nil) + if err != nil { + return nil, err + } + var roles map[string]map[string]interface{} + if err := c.do(ctx, req, &roles); err != nil { + return nil, err + } + return roles[name], nil +} + +func (c *Client) DeleteRole(ctx context.Context, name string) error { + endpoint := "/_xpack/security/role/" + name + method := http.MethodDelete + + req, err := http.NewRequest(method, c.baseURL+endpoint, nil) + if err != nil { + return err + } + return c.do(ctx, req, nil) +} + +// User management + +type User struct { + Password string `json:"password"` // Passwords must be at least 6 characters long. + Roles []string `json:"roles"` +} + +func (c *Client) CreateUser(ctx context.Context, name string, user *User) error { + endpoint := "/_xpack/security/user/" + name + method := http.MethodPost + + userJson, err := json.Marshal(user) + if err != nil { + return err + } + req, err := http.NewRequest(method, c.baseURL+endpoint, bytes.NewReader(userJson)) + if err != nil { + return err + } + return c.do(ctx, req, nil) +} + +func (c *Client) ChangePassword(ctx context.Context, name, newPassword string) error { + endpoint := "/_xpack/security/user/" + name + "/_password" + method := http.MethodPost + + pwdChangeBodyJson, err := json.Marshal(map[string]string{"password": newPassword}) + if err != nil { + return err + } + req, err := http.NewRequest(method, c.baseURL+endpoint, bytes.NewReader(pwdChangeBodyJson)) + if err != nil { + return err + } + return c.do(ctx, req, nil) +} + +func (c *Client) DeleteUser(ctx context.Context, name string) error { + endpoint := "/_xpack/security/user/" + name + method := http.MethodDelete + + req, err := http.NewRequest(method, c.baseURL+endpoint, nil) + if err != nil { + return err + } + return c.do(ctx, req, nil) +} + +// Low-level request handling + +func (c *Client) do(ctx context.Context, req *http.Request, ret interface{}) error { + // Prepare the request. + retryableReq, err := retryablehttp.NewRequest(req.Method, req.URL.String(), req.Body) + if err != nil { + return err + } + retryableReq.SetBasicAuth(c.username, c.password) + retryableReq.Header.Add("Content-Type", "application/json") + + // Execute the request. + resp, err := c.client.Do(retryableReq.WithContext(ctx)) + if err != nil { + return err + } + defer resp.Body.Close() + + // Read the body once so it can be retained for error output if needed. + // Since no responses are list responses, response bodies should have a small footprint + // and are very useful for debugging. + body, _ := ioutil.ReadAll(resp.Body) + + // If we were successful, try to unmarshal the body if the caller wants it. + if resp.StatusCode >= 200 && resp.StatusCode < 300 { + if ret == nil { + // No body to read out. + return nil + } + if err := json.Unmarshal(body, ret); err != nil { + // We received a success response from the ES API but the body was in an unexpected format. + return fmt.Errorf("%s; %d: %s", err, resp.StatusCode, body) + } + // Body has been successfully read out. + return nil + } + + // 404 is actually another form of success in the ES API. It just means that an object we were searching + // for wasn't found. + if resp.StatusCode == 404 { + return nil + } + + // We received some sort of API error. Let's return it. + return fmt.Errorf("%d: %s", resp.StatusCode, body) +} diff --git a/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/elasticsearch.go b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/elasticsearch.go new file mode 100644 index 0000000000..ff26e32032 --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/elasticsearch.go @@ -0,0 +1,336 @@ +package elasticsearch + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "sync" + "time" + + "github.com/hashicorp/errwrap" + multierror "github.com/hashicorp/go-multierror" + "github.com/hashicorp/vault/api" + "github.com/hashicorp/vault/sdk/database/dbplugin" + "github.com/hashicorp/vault/sdk/database/helper/credsutil" + "github.com/hashicorp/vault/sdk/database/helper/dbutil" +) + +func New() (interface{}, error) { + db := NewElasticsearch() + return dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.SecretValues), nil +} + +func Run(apiTLSConfig *api.TLSConfig) error { + dbplugin.Serve(NewElasticsearch(), api.VaultPluginTLSProvider(apiTLSConfig)) + return nil +} + +func NewElasticsearch() *Elasticsearch { + return &Elasticsearch{ + credentialProducer: &credsutil.SQLCredentialsProducer{ + DisplayNameLen: 15, + RoleNameLen: 15, + UsernameLen: 100, + Separator: "-", + }, + } +} + +// Elasticsearch implements dbplugin's Database interface. +type Elasticsearch struct { + + // The CredentialsProducer is never mutated and thus is inherently thread-safe. + credentialProducer credsutil.CredentialsProducer + + // This protects the config from races while also allowing multiple threads + // to read the config simultaneously when it's not changing. + mux sync.RWMutex + + // The root credential config. + config map[string]interface{} +} + +func (es *Elasticsearch) Type() (string, error) { + return "elasticsearch", nil +} + +// SecretValues is used by some error-sanitizing middleware in Vault that basically +// replaces the keys in the map with the values given so they're not leaked via +// error messages. +func (es *Elasticsearch) SecretValues() map[string]interface{} { + es.mux.RLock() + defer es.mux.RUnlock() + + replacements := make(map[string]interface{}) + for _, secretKey := range []string{"password", "client_key"} { + vIfc, found := es.config[secretKey] + if !found { + continue + } + secretVal, ok := vIfc.(string) + if !ok { + continue + } + // So, supposing a password of "0pen5e5ame", + // this will cause that string to get replaced with "[password]". + replacements[secretVal] = "[" + secretKey + "]" + } + return replacements +} + +// Init is called on `$ vault write database/config/:db-name`, +// or when you do a creds call after Vault's been restarted. +func (es *Elasticsearch) Init(ctx context.Context, config map[string]interface{}, verifyConnection bool) (map[string]interface{}, error) { + + // Validate the config to provide immediate feedback to the user. + // Ensure required string fields are provided in the expected format. + for _, requiredField := range []string{"username", "password", "url"} { + raw, ok := config[requiredField] + if !ok { + return nil, fmt.Errorf(`%q must be provided`, requiredField) + } + if _, ok := raw.(string); !ok { + return nil, fmt.Errorf(`%q must be a string`, requiredField) + } + } + + // Ensure optional string fields are provided in the expected format. + for _, optionalField := range []string{"ca_cert", "ca_path", "client_cert", "client_key", "tls_server_name"} { + raw, ok := config[optionalField] + if !ok { + continue + } + if _, ok = raw.(string); !ok { + return nil, fmt.Errorf(`%q must be a string`, optionalField) + } + } + + // Check the one optional bool field is in the expected format. + if raw, ok := config["insecure"]; ok { + if _, ok = raw.(bool); !ok { + return nil, errors.New(`"insecure" must be a bool`) + } + } + + // Test the given config to see if we can make a client. + client, err := buildClient(config) + if err != nil { + return nil, errwrap.Wrapf("couldn't make client with inbound config: {{err}}", err) + } + + // Optionally, test the given config to see if we can make a successful call. + if verifyConnection { + // Whether this role is found or unfound, if we're configured correctly there will + // be no err from the call. However, if something is misconfigured, this will yield + // an error response, which will be described in the returned error. + if _, err := client.GetRole(ctx, "vault-test"); err != nil { + return nil, errwrap.Wrapf("client test of getting a role failed: {{err}}", err) + } + } + + // Everything's working, write the new config to memory and storage. + es.mux.Lock() + defer es.mux.Unlock() + es.config = config + return es.config, nil +} + +// CreateUser is called on `$ vault read database/creds/:role-name` +// and it's the first time anything is touched from `$ vault write database/roles/:role-name`. +// This is likely to be the highest-throughput method for this plugin. +func (es *Elasticsearch) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, _ time.Time) (string, string, error) { + username, err := es.credentialProducer.GenerateUsername(usernameConfig) + if err != nil { + return "", "", errwrap.Wrapf(fmt.Sprintf("unable to generate username for %q: {{err}}", usernameConfig), err) + } + + password, err := es.credentialProducer.GeneratePassword() + if err != nil { + return "", "", errwrap.Wrapf("unable to generate password: {{err}}", err) + } + + stmt, err := newCreationStatement(statements) + if err != nil { + return "", "", errwrap.Wrapf("unable to read creation_statements: {{err}}", err) + } + + user := &User{ + Password: password, + Roles: stmt.PreexistingRoles, + } + + // Don't let anyone write the config while we're using it for our current client. + es.mux.RLock() + defer es.mux.RUnlock() + + client, err := buildClient(es.config) + if err != nil { + return "", "", errwrap.Wrapf("unable to get client: {{err}}", err) + } + + // If the RoleToCreate map has been populated with any data, we have one role to create. + // There can either be one RoleToCreate and no PreexistingRoles, or >= 1 PreexistingRoles + // and no RoleToCreate. They're mutually exclusive. + if len(stmt.RoleToCreate) > 0 { + // We'll simply name the role the same thing as the username, making it easy to tie back to this user. + if err := client.CreateRole(ctx, username, stmt.RoleToCreate); err != nil { + return "", "", errwrap.Wrapf(fmt.Sprintf("unable to create role name %s, role definition %q: {{err}}", username, stmt.RoleToCreate), err) + } + user.Roles = []string{username} + } + if err := client.CreateUser(ctx, username, user); err != nil { + return "", "", errwrap.Wrapf(fmt.Sprintf("unable to create user name %s, user %q: {{err}}", username, user), err) + } + return username, password, nil +} + +// RenewUser gets called on `$ vault lease renew {{lease-id}}`. It automatically pushes out the amount of time until +// the database secrets engine calls RevokeUser, if appropriate. +func (es *Elasticsearch) RenewUser(_ context.Context, _ dbplugin.Statements, _ string, _ time.Time) error { + // Normally, this function would update a "VALID UNTIL" statement on a database user + // but there's no similar need here. + return nil +} + +// RevokeUser is called when a lease expires. +func (es *Elasticsearch) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { + stmt, err := newCreationStatement(statements) + if err != nil { + return errwrap.Wrapf("unable to read creation_statements: {{err}}", err) + } + + // Don't let anyone write the config while we're using it for our current client. + es.mux.RLock() + defer es.mux.RUnlock() + + client, err := buildClient(es.config) + if err != nil { + return errwrap.Wrapf("unable to get client: {{err}}", err) + } + + var errs error + if len(stmt.RoleToCreate) > 0 { + // If the role already doesn't exist because it was successfully deleted on a previous + // attempt to run this code, there will be no error, so it's harmless to try. + if err := client.DeleteRole(ctx, username); err != nil { + errs = multierror.Append(errs, errwrap.Wrapf(fmt.Sprintf("unable to delete role name %s: {{err}}", username), err)) + } + } + // Same with the user. If it was already deleted on a previous attempt, there won't be an + // error. + if err := client.DeleteUser(ctx, username); err != nil { + errs = multierror.Append(errs, errwrap.Wrapf(fmt.Sprintf("unable to create user name %s: {{err}}", username), err)) + } + return errs +} + +// RotateRootCredentials doesn't require any statements from the user because it's not configurable in any +// way. We simply generate a new password and hit a pre-defined Elasticsearch REST API to rotate them. +func (es *Elasticsearch) RotateRootCredentials(ctx context.Context, _ []string) (map[string]interface{}, error) { + newPassword, err := es.credentialProducer.GeneratePassword() + if err != nil { + return nil, errwrap.Wrapf("unable to generate root password: {{err}}", err) + } + + // Don't let anyone read or write the config while we're in the process of rotating the password. + es.mux.Lock() + defer es.mux.Unlock() + + client, err := buildClient(es.config) + if err != nil { + return nil, errwrap.Wrapf("unable to get client: {{err}}", err) + } + + if err := client.ChangePassword(ctx, es.config["username"].(string), newPassword); err != nil { + return nil, errwrap.Wrapf("unable to change password: {{}}", err) + } + + es.config["password"] = newPassword + return es.config, nil +} + +func (es *Elasticsearch) Close() error { + // NOOP, nothing to close. + return nil +} + +// DEPRECATED, included for backward-compatibility until removal +func (es *Elasticsearch) Initialize(ctx context.Context, config map[string]interface{}, verifyConnection bool) error { + _, err := es.Init(ctx, config, verifyConnection) + return err +} + +func newCreationStatement(statements dbplugin.Statements) (*creationStatement, error) { + if len(statements.Creation) == 0 { + return nil, dbutil.ErrEmptyCreationStatement + } + stmt := &creationStatement{} + if err := json.Unmarshal([]byte(statements.Creation[0]), stmt); err != nil { + return nil, errwrap.Wrapf(fmt.Sprintf("unable to unmarshal %s: {{err}}", []byte(statements.Creation[0])), err) + } + if len(stmt.PreexistingRoles) > 0 && len(stmt.RoleToCreate) > 0 { + return nil, errors.New(`"elasticsearch_roles" and "elasticsearch_role_definition" are mutually exclusive`) + } + return stmt, nil +} + +type creationStatement struct { + PreexistingRoles []string `json:"elasticsearch_roles"` + RoleToCreate map[string]interface{} `json:"elasticsearch_role_definition"` +} + +// buildClient is a helper method for building a client from the present config, +// which is done often. +func buildClient(config map[string]interface{}) (*Client, error) { + + // We can presume these required fields are provided by strings + // because they're validated in Init. + clientConfig := &ClientConfig{ + Username: config["username"].(string), + Password: config["password"].(string), + BaseURL: config["url"].(string), + } + + hasTLSConf := false + tlsConf := &TLSConfig{} + + // We can presume that if these are provided, they're in the expected format + // because they're also validated in Init. + if raw, ok := config["ca_cert"]; ok { + tlsConf.CACert = raw.(string) + hasTLSConf = true + } + if raw, ok := config["ca_path"]; ok { + tlsConf.CAPath = raw.(string) + hasTLSConf = true + } + if raw, ok := config["client_cert"]; ok { + tlsConf.ClientCert = raw.(string) + hasTLSConf = true + } + if raw, ok := config["client_key"]; ok { + tlsConf.ClientKey = raw.(string) + hasTLSConf = true + } + if raw, ok := config["tls_server_name"]; ok { + tlsConf.TLSServerName = raw.(string) + hasTLSConf = true + } + if raw, ok := config["insecure"]; ok { + tlsConf.Insecure = raw.(bool) + hasTLSConf = true + } + + // We should only fulfill the clientConfig's TLSConfig pointer if we actually + // want the client to use TLS. + if hasTLSConf { + clientConfig.TLSConfig = tlsConf + } + + client, err := NewClient(clientConfig) + if err != nil { + return nil, err + } + return client, nil +} diff --git a/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.mod b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.mod new file mode 100644 index 0000000000..f8deb328eb --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.mod @@ -0,0 +1,16 @@ +module github.com/hashicorp/vault-plugin-database-elasticsearch + +go 1.12 + +require ( + github.com/hashicorp/errwrap v1.0.0 + github.com/hashicorp/go-cleanhttp v0.5.1 + github.com/hashicorp/go-multierror v1.0.0 + github.com/hashicorp/go-retryablehttp v0.5.3 + github.com/hashicorp/go-rootcerts v1.0.0 + github.com/hashicorp/vault/api v1.0.1 + github.com/hashicorp/vault/sdk v0.1.9 + github.com/mitchellh/go-homedir v1.1.0 // indirect + golang.org/x/sys v0.0.0-20190410170021-cc4d4f50624c // indirect + google.golang.org/grpc v1.20.0 // indirect +) diff --git a/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.sum b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.sum new file mode 100644 index 0000000000..309a2a840b --- /dev/null +++ b/vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.sum @@ -0,0 +1,147 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= +github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.8.0 h1:z3ollgGRg8RjfJH6UVBaG54R70GFd++QOkvnJH3VSBY= +github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.0.0 h1:/gQ1sNR8/LHpoxKRQq4PmLBuacfZb4tC93e9B30o/7c= +github.com/hashicorp/go-plugin v1.0.0/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/vault/api v1.0.1 h1:YQI4SgOlkmbEKZI8ZClo6fm9oXlBHJUlrbEtFiRPrng= +github.com/hashicorp/vault/api v1.0.1/go.mod h1:AV/+M5VPDpB90arloVX0rVDUIHkONiwz5Uza9HRtpUE= +github.com/hashicorp/vault/sdk v0.1.8/go.mod h1:tHZfc6St71twLizWNHvnnbiGFo1aq0eD2jGPLtP8kAU= +github.com/hashicorp/vault/sdk v0.1.9 h1:GkHLrt3ZU8j/ATmbLqW5P/frBCxPhCRC6nLD0kDP/yc= +github.com/hashicorp/vault/sdk v0.1.9/go.mod h1:tHZfc6St71twLizWNHvnnbiGFo1aq0eD2jGPLtP8kAU= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190410170021-cc4d4f50624c h1:OUGWoQpM/o3TxM7Fp3CEqRpaYCbg4H1hOVPnZoUtr2U= +golang.org/x/sys v0.0.0-20190410170021-cc4d4f50624c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0 h1:DlsSIrgEBuZAUFJcta2B5i/lzeHHbnfkNFAfFXLVFYQ= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 0ed1d58d57..3de37566c6 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -351,7 +351,11 @@ func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { } func SetsockoptString(fd, level, opt int, s string) (err error) { - return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s))) + var p unsafe.Pointer + if len(s) > 0 { + p = unsafe.Pointer(&[]byte(s)[0]) + } + return setsockopt(fd, level, opt, p, uintptr(len(s))) } func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index 6dfe56be76..16dd63e892 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -451,6 +451,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index 9f8cbf4cb3..9aa75fa374 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -452,6 +452,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index cbbf19a447..61927ab9ee 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -455,6 +455,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index be21189dbd..a7a280f30e 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -453,6 +453,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index d599ca2759..564d1e3971 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -454,6 +454,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 011be86bae..e79edadbcd 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -453,6 +453,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index 8163445163..94817e845b 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -453,6 +453,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index 4ecf7a8c77..ddb0bdbf37 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -454,6 +454,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index ea817bafba..2089ed0f5f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -454,6 +454,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 192ea3b105..c163848852 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -454,6 +454,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 673e5e7919..f9079a5049 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -453,6 +453,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index faafcddfcc..9f3c0f0be7 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -452,6 +452,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 392dd7375c..a8adf4fde3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -456,6 +456,9 @@ const ( IFA_ANYCAST = 0x5 IFA_CACHEINFO = 0x6 IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa IFLA_UNSPEC = 0x0 IFLA_ADDRESS = 0x1 IFLA_BROADCAST = 0x2 diff --git a/vendor/modules.txt b/vendor/modules.txt index 9b3f1816f8..1cd7a69a2d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -329,6 +329,8 @@ github.com/hashicorp/vault-plugin-auth-gcp/plugin/cache github.com/hashicorp/vault-plugin-auth-jwt # github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.1 github.com/hashicorp/vault-plugin-auth-kubernetes +# github.com/hashicorp/vault-plugin-database-elasticsearch v0.0.0-20190508211750-4152192cdc0f +github.com/hashicorp/vault-plugin-database-elasticsearch # github.com/hashicorp/vault-plugin-secrets-ad v0.5.1 github.com/hashicorp/vault-plugin-secrets-ad/plugin github.com/hashicorp/vault-plugin-secrets-ad/plugin/client @@ -642,7 +644,7 @@ golang.org/x/oauth2/jwt golang.org/x/oauth2/jws # golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 golang.org/x/sync/semaphore -# golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e +# golang.org/x/sys v0.0.0-20190410170021-cc4d4f50624c golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/cpu diff --git a/website/source/api/secret/databases/elasticdb.html.md b/website/source/api/secret/databases/elasticdb.html.md new file mode 100644 index 0000000000..46abdcbb1e --- /dev/null +++ b/website/source/api/secret/databases/elasticdb.html.md @@ -0,0 +1,100 @@ +--- +layout: "api" +page_title: "Elasticsearch - Database - Secrets Engines - HTTP API" +sidebar_title: "Elasticsearch" +sidebar_current: "api-http-secret-databases-elasticsearch" +description: |- + The Elasticsearch plugin for Vault's database secrets engine generates database credentials to access Elasticsearch. +--- + +# Elasticsearch Database Plugin HTTP API + +The Elasticsearch database plugin is one of the supported plugins for the database +secrets engine. This plugin generates credentials dynamically based on +configured roles for Elasticsearch. + +## Configure Connection + +In addition to the parameters defined by the [Database +Backend](/api/secret/databases/index.html#configure-connection), this plugin +has a number of parameters to further configure a connection. + +| Method | Path | +| :--------------------------- | :--------------------- | +| `POST` | `/database/config/:name` | + +### Parameters + +- `url` `(string: )` - The URL for Elasticsearch's API ("http://localhost:9200"). +- `username` `(string: )` - The username to be used in the connection URL ("vault"). +- `password` `(string: )` - The password to be used in the connection URL ("pa55w0rd"). +- `ca_cert` `(string: "")` - The path to a PEM-encoded CA cert file to use to verify the Elasticsearch server's identity. +- `ca_path` `(string: "")` - The path to a directory of PEM-encoded CA cert files to use to verify the Elasticsearch server's identity. +- `client_cert` `(string: "")` - The path to the certificate for the Elasticsearch client to present for communication. +- `client_key` `(string: "")` - The path to the key for the Elasticsearch client to use for communication. +- `tls_server_name` `(string: "")` - This, if set, is used to set the SNI host when connecting via 1TLS. +- `insecure` `(bool: false)` - Not recommended. Default to false. Can be set to true to disable SSL verification. + +### Sample Payload + +```json +{ + "plugin_name": "elasticsearch-database-plugin", + "allowed_roles": "internally-defined-role,externally-defined-role", + "url": "http://localhost:9200", + "username": "vault", + "password": "myPa55word", + "ca_cert": "/usr/share/ca-certificates/extra/elastic-stack-ca.crt.pem", + "client_cert": "$ES_HOME/config/certs/elastic-certificates.crt.pem", + "client_key": "$ES_HOME/config/certs/elastic-certificates.key.pem" +} +``` + +### Sample Request + +``` +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data @payload.json \ + http://127.0.0.1:8200/v1/database/config/my-elasticsearch-database +``` + +## Statements + +Statements are configured during role creation and are used by the plugin to +determine what is sent to the database on user creation, renewing, and +revocation. For more information on configuring roles see the [Role +API](/api/secret/databases/index.html#create-role) in the database secrets engine docs. + +### Parameters + +The following are the statements used by this plugin. If not mentioned in this +list the plugin does not support that statement type. + +- `creation_statements` `(string: )` – Using JSON, either defines an + `elasticsearch_role_definition` or a group of pre-existing `elasticsearch_roles`. + The object specified by the `elasticsearch_role_definition` is the JSON directly + passed through to the Elasticsearch API, so you can pass through anything shown + [here](https://www.elastic.co/guide/en/elasticsearch/reference/6.6/security-api-put-role.html). + For `elasticsearch_roles`, add the names of the roles only. They must pre-exist + in Elasticsearch. Defining roles in Vault is more secure than using pre-existing + roles because a privilege escalation could be performed by editing the roles used + out-of-band in Elasticsearch. + +### Sample Creation Statements +```json +{ + "elasticsearch_role_definition": { + "indices": [{ + "names": ["*"], + "privileges": ["read"] + }] + } +} +``` +```json +{ + "elasticsearch_roles": ["pre-existing-role-in-elasticsearch"] +} +``` \ No newline at end of file diff --git a/website/source/docs/secrets/databases/elasticdb.html.md b/website/source/docs/secrets/databases/elasticdb.html.md new file mode 100644 index 0000000000..31ec8b11e1 --- /dev/null +++ b/website/source/docs/secrets/databases/elasticdb.html.md @@ -0,0 +1,173 @@ +--- +layout: "docs" +page_title: "Elasticsearch - Database - Secrets Engines" +sidebar_title: "Elasticsearch" +sidebar_current: "docs-secrets-databases-elasticsearch" +description: |- + Elasticsearch is one of the supported plugins for the database secrets engine. This + plugin generates database credentials dynamically based on configured roles + for Elasticsearch. +--- + +# Elasticsearch Database Secrets Engine + +Elasticsearch is one of the supported plugins for the database secrets engine. This +plugin generates database credentials dynamically based on configured roles for +Elasticsearch. + +See the [database secrets engine](/docs/secrets/databases/index.html) docs for +more information about setting up the database secrets engine. + +## Getting Started + +To take advantage of this plugin, you must first enable Elasticsearch's native realm of security by activating X-Pack. These +instructions will walk you through doing this using Elasticsearch 6.6.1. However, Elasticsearch 7.x.x is also supported. +At the time of writing, X-Pack was a paid feature. To use it, you may need to enable a 30-day trial with Elasticsearch, +or activate a paid version. + +### Enable X-Pack Security in Elasticsearch + +Read [Securing the Elastic Stack](https://www.elastic.co/guide/en/elastic-stack-overview/6.6/elasticsearch-security.html) and +follow [its instructions for enabling X-Pack Security](https://www.elastic.co/guide/en/elasticsearch/reference/6.6/setup-xpack.html). +When done, verify that you've enabled X-Pack by running `$ $ES_HOME/bin/elasticsearch-setup-passwords interactive`. You'll +know it's been set up successfully if it takes you through a number of password-inputting steps. + +### Recommended: Enable Encrypted Communications + +This plugin communicates with Elasticsearch's security API. We recommend you enable TLS for these communications so they can be +encrypted. + +To set up TLS in Elasticsearch, first read [encrypted communications](https://www.elastic.co/guide/en/elastic-stack-overview/6.6/encrypting-communications.html) +and go through its instructions on [encrypting HTTP client communications](https://www.elastic.co/guide/en/elasticsearch/reference/6.6/configuring-tls.html#tls-http). + +After enabling TLS on the Elasticsearch side, you'll need to convert the .p12 certificates you generated to other formats so they can be +used by Vault. [Here is an example using OpenSSL](https://stackoverflow.com/questions/15144046/converting-pkcs12-certificate-into-pem-using-openssl) +to convert our .p12 certs to the pem format. + +Also, on the instance running Elasticsearch, we needed to install our newly generated CA certificate that was originally in the .p12 format. +We did this by converting the .p12 CA cert to a pem, and then further converting that +[pem to a crt](https://stackoverflow.com/questions/13732826/convert-pem-to-crt-and-key), adding that crt to `/usr/share/ca-certificates/extra`, +and using `sudo dpkg-reconfigure ca-certificates`. + +The above instructions may vary if you are not using an Ubuntu machine. Please ensure you're using the methods specific to your operating +environment. Describing every operating environment is outside the scope of these instructions. + +### Create a Role for Vault + +Next, in Elasticsearch, we recommend that you create a user just for Vault to use in managing secrets. + +To do this, first create a role that will allow Vault the minimum privileges needed to administer users and passwords by performing a +POST to Elasticsearch. To do this, we used the `elastic` superuser whose password we created in the +`$ $ES_HOME/bin/elasticsearch-setup-passwords interactive` step. + +``` +$ curl \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"cluster": ["manage_security"]}' \ + http://elastic:$PASSWORD@localhost:9200/_xpack/security/role/vault +``` + +Next, create a user for Vault associated with that role. + +``` +$ curl \ + -X POST \ + -H "Content-Type: application/json" \ + -d @data.json \ + http://elastic:$PASSWORD@localhost:9200/_xpack/security/user/vault +``` + +The contents of `data.json` in this example are: +``` +{ + "password" : "myPa55word", + "roles" : [ "vault" ], + "full_name" : "Hashicorp Vault", + "metadata" : { + "plugin_name": "Vault Plugin Database Elasticsearch", + "plugin_url": "https://github.com/hashicorp/vault-plugin-database-elasticsearch" + } +} +``` + +Now, Elasticsearch is configured and ready to be used with Vault. + +## Setup + +1. Enable the database secrets engine if it is not already enabled: + + ```text + $ vault secrets enable database + Success! Enabled the database secrets engine at: database/ + ``` + + By default, the secrets engine will enable at the name of the engine. To + enable the secrets engine at a different path, use the `-path` argument. + +1. Configure Vault with the proper plugin and connection information: + + ```text + $ vault write database/config/my-elasticsearch-database \ + plugin_name="elasticsearch-database-plugin" \ + allowed_roles="internally-defined-role,externally-defined-role" \ + username=vault \ + password=myPa55word \ + url=http://localhost:9200 \ + ca_cert=/usr/share/ca-certificates/extra/elastic-stack-ca.crt.pem \ + client_cert=$ES_HOME/config/certs/elastic-certificates.crt.pem \ + client_key=$ES_HOME/config/certs/elastic-certificates.key.pem + ``` + +1. Configure a role that maps a name in Vault to a role definition in Elasticsearch. +This is considered the most secure type of role because nobody can perform +a privilege escalation by editing a role's privileges out-of-band in +Elasticsearch: + + ```text + $ vault write database/roles/internally-defined-role \ + db_name=my-elasticsearch-database \ + creation_statements='{"elasticsearch_role_definition": {"indices": [{"names":["*"], "privileges":["read"]}]}}' \ + default_ttl="1h" \ + max_ttl="24h" + Success! Data written to: database/roles/internally-defined-role + ``` + +1. Alternatively, configure a role that maps a name in Vault to a pre-existing +role definition in Elasticsearch: + + ```text + $ vault write database/roles/externally-defined-role \ + db_name=my-elasticsearch-database \ + creation_statements='{"elasticsearch_roles": ["pre-existing-role-in-elasticsearch"]}' \ + default_ttl="1h" \ + max_ttl="24h" + Success! Data written to: database/roles/externally-defined-role + ``` + +## Usage + +After the secrets engine is configured and a user/machine has a Vault token with +the proper permission, it can generate credentials. + +1. Generate a new credential by reading from the `/creds` endpoint with the name +of the role: + + ```text + $ vault read database/creds/my-role + Key Value + --- ----- + lease_id database/creds/my-role/2f6a614c-4aa2-7b19-24b9-ad944a8d4de6 + lease_duration 1h + lease_renewable true + password 8cab931c-d62e-a73d-60d3-5ee85139cd66 + username v-root-e2978cd0- + ``` + +## API + +The full list of configurable options can be seen in the [Elasticsearch database +plugin API](/api/secret/databases/elasticdb.html) page. + +For more information on the database secrets engine's HTTP API please see the +[Database secrets engine API](/api/secret/databases/index.html) page.