Merge pull request #6857 from hashicorp/add-elasticsearch-auth
Add ElasticSearch database secrets engine
This commit is contained in:
commit
117d28d966
1
go.mod
1
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
|
||||
|
|
4
go.sum
4
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=
|
||||
|
|
|
@ -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,
|
||||
|
|
19
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/.gitignore
generated
vendored
Normal file
19
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/.gitignore
generated
vendored
Normal file
|
@ -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/*
|
373
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/LICENSE
generated
vendored
Normal file
373
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/LICENSE
generated
vendored
Normal file
|
@ -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.
|
39
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/Makefile
generated
vendored
Normal file
39
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/Makefile
generated
vendored
Normal file
|
@ -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
|
138
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/README.md
generated
vendored
Normal file
138
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/README.md
generated
vendored
Normal file
|
@ -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"
|
||||
```
|
231
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/client.go
generated
vendored
Normal file
231
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/client.go
generated
vendored
Normal file
|
@ -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)
|
||||
}
|
336
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/elasticsearch.go
generated
vendored
Normal file
336
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/elasticsearch.go
generated
vendored
Normal file
|
@ -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
|
||||
}
|
16
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.mod
generated
vendored
Normal file
16
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.mod
generated
vendored
Normal file
|
@ -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
|
||||
)
|
147
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.sum
generated
vendored
Normal file
147
vendor/github.com/hashicorp/vault-plugin-database-elasticsearch/go.sum
generated
vendored
Normal file
|
@ -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=
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -643,7 +645,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
|
||||
|
|
|
@ -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: <required>)` - The URL for Elasticsearch's API ("http://localhost:9200").
|
||||
- `username` `(string: <required>)` - The username to be used in the connection URL ("vault").
|
||||
- `password` `(string: <required>)` - 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: <required>)` – 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"]
|
||||
}
|
||||
```
|
|
@ -0,0 +1,176 @@
|
|||
---
|
||||
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 7.1.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/7.1/elasticsearch-security.html) and
|
||||
follow [its instructions for enabling X-Pack Security](https://www.elastic.co/guide/en/elasticsearch/reference/7.1/setup-xpack.html).
|
||||
|
||||
### Enable Encrypted Communications
|
||||
|
||||
This plugin communicates with Elasticsearch's security API. ES requires 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/7.1/encrypting-communications.html)
|
||||
and go through its instructions on [encrypting HTTP client communications](https://www.elastic.co/guide/en/elasticsearch/reference/7.1/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.
|
||||
|
||||
### Set Up Passwords
|
||||
|
||||
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.
|
||||
|
||||
### 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.
|
Loading…
Reference in New Issue