mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 11:00:25 +00:00
rebase: bump github.com/hashicorp/vault/api from 1.5.0 to 1.6.0
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.5.0 to 1.6.0. - [Release notes](https://github.com/hashicorp/vault/releases) - [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/vault/compare/v1.5.0...v1.6.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/vault/api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
01923ab166
commit
3c0e1b4970
10
go.mod
10
go.mod
@ -15,7 +15,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/hashicorp/vault/api v1.5.0
|
||||
github.com/hashicorp/vault/api v1.6.0
|
||||
github.com/kubernetes-csi/csi-lib-utils v0.11.0
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0
|
||||
github.com/libopenstorage/secrets v0.0.0-20210908194121-a1d19aa9713a
|
||||
@ -86,15 +86,15 @@ require (
|
||||
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.5 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.2 // indirect
|
||||
github.com/hashicorp/go-version v1.2.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/vault v1.4.2 // indirect
|
||||
github.com/hashicorp/vault/sdk v0.4.1 // indirect
|
||||
github.com/hashicorp/vault/sdk v0.5.0 // indirect
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
@ -108,7 +108,7 @@ require (
|
||||
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.2 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.1 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
|
18
go.sum
18
go.sum
@ -592,12 +592,14 @@ github.com/hashicorp/go-secure-stdlib/base62 v0.1.1 h1:6KMBnfEv0/kLAz0O76sliN5mX
|
||||
github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw=
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc=
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.5 h1:MBgwAFPUbfuI0+tmDU/aeM1MARvdbqWmiieXIalKqDE=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.5/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
|
||||
github.com/hashicorp/go-secure-stdlib/password v0.1.1 h1:6JzmBqXprakgFEHwBgdchsjaA9x3GyjdI568bXKxa60=
|
||||
github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo=
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788=
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
|
||||
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 h1:Yc026VyMyIpq1UWRnakHRG01U8fJm+nEfEmjoAb00n8=
|
||||
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
@ -662,8 +664,8 @@ github.com/hashicorp/vault/api v1.0.5-0.20191122173911-80fcc7907c78/go.mod h1:Uf
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20200215224050-f6547fa8e820/go.mod h1:3f12BMfgDGjTsTtIUj+ZKZwSobQpZtYGFIEehOv5z1o=
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20200317185738-82f498082f02/go.mod h1:3f12BMfgDGjTsTtIUj+ZKZwSobQpZtYGFIEehOv5z1o=
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20200902155336-f9d5ce5a171a/go.mod h1:R3Umvhlxi2TN7Ex2hzOowyeNb+SfbVWI973N+ctaFMk=
|
||||
github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28=
|
||||
github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM=
|
||||
github.com/hashicorp/vault/api v1.6.0 h1:B8UUYod1y1OoiGHq9GtpiqSnGOUEWHaA26AY8RQEDY4=
|
||||
github.com/hashicorp/vault/api v1.6.0/go.mod h1:h1K70EO2DgnBaTz5IsL6D5ERsNt5Pce93ueVS2+t0Xc=
|
||||
github.com/hashicorp/vault/sdk v0.1.8/go.mod h1:tHZfc6St71twLizWNHvnnbiGFo1aq0eD2jGPLtP8kAU=
|
||||
github.com/hashicorp/vault/sdk v0.1.14-0.20190730042320-0dc007d98cc8/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
|
||||
github.com/hashicorp/vault/sdk v0.1.14-0.20191108161836-82f2b5571044/go.mod h1:PcekaFGiPJyHnFy+NZhP6ll650zEw51Ag7g/YEa+EOU=
|
||||
@ -673,8 +675,8 @@ github.com/hashicorp/vault/sdk v0.1.14-0.20200317185738-82f498082f02/go.mod h1:W
|
||||
github.com/hashicorp/vault/sdk v0.1.14-0.20200427170607-03332aaf8d18/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10=
|
||||
github.com/hashicorp/vault/sdk v0.1.14-0.20200429182704-29fce8f27ce4/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10=
|
||||
github.com/hashicorp/vault/sdk v0.1.14-0.20200519221838-e0cfd64bc267/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10=
|
||||
github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo=
|
||||
github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0=
|
||||
github.com/hashicorp/vault/sdk v0.5.0 h1:EED7p0OCU3OY5SAqJwSANofY1YKMytm+jDHDQ2EzGVQ=
|
||||
github.com/hashicorp/vault/sdk v0.5.0/go.mod h1:UJZHlfwj7qUJG8g22CuxUgkdJouFrBNvBHCyx8XAPdo=
|
||||
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=
|
||||
@ -825,8 +827,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo=
|
||||
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/pointerstructure v0.0.0-20190430161007-f252a8fd71c8/go.mod h1:k4XwG94++jLVsSiTxo7qdIfXA9pj9EAeo0QsNNJOLZ8=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
|
||||
|
220
vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go
generated
vendored
220
vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -92,6 +93,9 @@ func ParseCapacityString(in interface{}) (uint64, error) {
|
||||
return cap, nil
|
||||
}
|
||||
|
||||
// Parse a duration from an arbitrary value (a string or numeric value) into
|
||||
// a time.Duration; when units are missing (such as when a numeric type is
|
||||
// provided), the duration is assumed to be in seconds.
|
||||
func ParseDurationSecond(in interface{}) (time.Duration, error) {
|
||||
var dur time.Duration
|
||||
jsonIn, ok := in.(json.Number)
|
||||
@ -105,20 +109,22 @@ func ParseDurationSecond(in interface{}) (time.Duration, error) {
|
||||
if inp == "" {
|
||||
return dur, nil
|
||||
}
|
||||
|
||||
if v, err := strconv.ParseInt(inp, 10, 64); err == nil {
|
||||
return time.Duration(v) * time.Second, nil
|
||||
}
|
||||
|
||||
if strings.HasSuffix(inp, "d") {
|
||||
v, err := strconv.ParseInt(inp[:len(inp)-1], 10, 64)
|
||||
if err != nil {
|
||||
return dur, err
|
||||
}
|
||||
return time.Duration(v) * 24 * time.Hour, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
// Look for a suffix otherwise its a plain second value
|
||||
if strings.HasSuffix(inp, "s") || strings.HasSuffix(inp, "m") || strings.HasSuffix(inp, "h") || strings.HasSuffix(inp, "ms") {
|
||||
dur, err = time.ParseDuration(inp)
|
||||
if err != nil {
|
||||
return dur, err
|
||||
}
|
||||
} else {
|
||||
// Plain integer
|
||||
secs, err := strconv.ParseInt(inp, 10, 64)
|
||||
if err != nil {
|
||||
return dur, err
|
||||
}
|
||||
dur = time.Duration(secs) * time.Second
|
||||
if dur, err = time.ParseDuration(inp); err != nil {
|
||||
return dur, err
|
||||
}
|
||||
case int:
|
||||
dur = time.Duration(inp) * time.Second
|
||||
@ -145,6 +151,9 @@ func ParseDurationSecond(in interface{}) (time.Duration, error) {
|
||||
return dur, nil
|
||||
}
|
||||
|
||||
// Parse an absolute timestamp from the provided arbitrary value (string or
|
||||
// numeric value). When an untyped numeric value is provided, it is assumed
|
||||
// to be seconds from the Unix Epoch.
|
||||
func ParseAbsoluteTime(in interface{}) (time.Time, error) {
|
||||
var t time.Time
|
||||
switch inp := in.(type) {
|
||||
@ -193,6 +202,13 @@ func ParseAbsoluteTime(in interface{}) (time.Time, error) {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// ParseInt takes an arbitrary value (either a string or numeric type) and
|
||||
// parses it as an int64 value. This value is assumed to be larger than the
|
||||
// provided type, but cannot safely be cast.
|
||||
//
|
||||
// When the end value is bounded (such as an int value), it is recommended
|
||||
// to instead call SafeParseInt or SafeParseIntRange to safely cast to a
|
||||
// more restrictive type.
|
||||
func ParseInt(in interface{}) (int64, error) {
|
||||
var ret int64
|
||||
jsonIn, ok := in.(json.Number)
|
||||
@ -230,6 +246,104 @@ func ParseInt(in interface{}) (int64, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// ParseDirectIntSlice behaves similarly to ParseInt, but accepts typed
|
||||
// slices, returning a slice of int64s.
|
||||
//
|
||||
// If the starting value may not be in slice form (e.g.. a bare numeric value
|
||||
// could be provided), it is suggested to call ParseIntSlice instead.
|
||||
func ParseDirectIntSlice(in interface{}) ([]int64, error) {
|
||||
var ret []int64
|
||||
|
||||
switch in.(type) {
|
||||
case []int:
|
||||
for _, v := range in.([]int) {
|
||||
ret = append(ret, int64(v))
|
||||
}
|
||||
case []int32:
|
||||
for _, v := range in.([]int32) {
|
||||
ret = append(ret, int64(v))
|
||||
}
|
||||
case []int64:
|
||||
// For consistency to ensure callers can always modify ret without
|
||||
// impacting in.
|
||||
for _, v := range in.([]int64) {
|
||||
ret = append(ret, v)
|
||||
}
|
||||
case []uint:
|
||||
for _, v := range in.([]uint) {
|
||||
ret = append(ret, int64(v))
|
||||
}
|
||||
case []uint32:
|
||||
for _, v := range in.([]uint32) {
|
||||
ret = append(ret, int64(v))
|
||||
}
|
||||
case []uint64:
|
||||
for _, v := range in.([]uint64) {
|
||||
ret = append(ret, int64(v))
|
||||
}
|
||||
case []json.Number:
|
||||
for _, v := range in.([]json.Number) {
|
||||
element, err := ParseInt(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, element)
|
||||
}
|
||||
case []string:
|
||||
for _, v := range in.([]string) {
|
||||
element, err := ParseInt(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, element)
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("could not parse value from input")
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// ParseIntSlice is a helper function for handling upgrades of optional
|
||||
// slices; that is, if the API accepts a type similar to <int|[]int>,
|
||||
// nicely handle the common cases of providing only an int-ish, providing
|
||||
// an actual slice of int-ishes, or providing a comma-separated list of
|
||||
// numbers.
|
||||
//
|
||||
// When []int64 is not the desired final type (or the values should be
|
||||
// range-bound), it is suggested to call SafeParseIntSlice or
|
||||
// SafeParseIntSliceRange instead.
|
||||
func ParseIntSlice(in interface{}) ([]int64, error) {
|
||||
if ret, err := ParseInt(in); err == nil {
|
||||
return []int64{ret}, nil
|
||||
}
|
||||
|
||||
if ret, err := ParseDirectIntSlice(in); err == nil {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
if strings, err := ParseCommaStringSlice(in); err == nil {
|
||||
var ret []int64
|
||||
for _, v := range strings {
|
||||
if v == "" {
|
||||
// Ignore empty fields
|
||||
continue
|
||||
}
|
||||
|
||||
element, err := ParseInt(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, element)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("could not parse value from input")
|
||||
}
|
||||
|
||||
// Parses the provided arbitrary value as a boolean-like value.
|
||||
func ParseBool(in interface{}) (bool, error) {
|
||||
var result bool
|
||||
if err := mapstructure.WeakDecode(in, &result); err != nil {
|
||||
@ -238,6 +352,7 @@ func ParseBool(in interface{}) (bool, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Parses the provided arbitrary value as a string.
|
||||
func ParseString(in interface{}) (string, error) {
|
||||
var result string
|
||||
if err := mapstructure.WeakDecode(in, &result); err != nil {
|
||||
@ -246,7 +361,13 @@ func ParseString(in interface{}) (string, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Parses the provided string-like value as a comma-separated list of values.
|
||||
func ParseCommaStringSlice(in interface{}) ([]string, error) {
|
||||
jsonIn, ok := in.(json.Number)
|
||||
if ok {
|
||||
in = jsonIn.String()
|
||||
}
|
||||
|
||||
rawString, ok := in.(string)
|
||||
if ok && rawString == "" {
|
||||
return []string{}, nil
|
||||
@ -267,6 +388,7 @@ func ParseCommaStringSlice(in interface{}) ([]string, error) {
|
||||
return strutil.TrimStrings(result), nil
|
||||
}
|
||||
|
||||
// Parses the specified value as one or more addresses, separated by commas.
|
||||
func ParseAddrs(addrs interface{}) ([]*sockaddr.SockAddrMarshaler, error) {
|
||||
out := make([]*sockaddr.SockAddrMarshaler, 0)
|
||||
stringAddrs := make([]string, 0)
|
||||
@ -306,3 +428,75 @@ func ParseAddrs(addrs interface{}) ([]*sockaddr.SockAddrMarshaler, error) {
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Parses the provided arbitrary value (see ParseInt), ensuring it is within
|
||||
// the specified range (inclusive of bounds). If this range corresponds to a
|
||||
// smaller type, the returned value can then be safely cast without risking
|
||||
// overflow.
|
||||
func SafeParseIntRange(in interface{}, min int64, max int64) (int64, error) {
|
||||
raw, err := ParseInt(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if raw < min || raw > max {
|
||||
return 0, fmt.Errorf("error parsing int value; out of range [%v to %v]: %v", min, max, raw)
|
||||
}
|
||||
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
// Parses the specified arbitrary value (see ParseInt), ensuring that the
|
||||
// resulting value is within the range for an int value. If no error occurred,
|
||||
// the caller knows no overflow occurred.
|
||||
func SafeParseInt(in interface{}) (int, error) {
|
||||
raw, err := SafeParseIntRange(in, math.MinInt, math.MaxInt)
|
||||
return int(raw), err
|
||||
}
|
||||
|
||||
// Parses the provided arbitrary value (see ParseIntSlice) into a slice of
|
||||
// int64 values, ensuring each is within the specified range (inclusive of
|
||||
// bounds). If this range corresponds to a smaller type, the returned value
|
||||
// can then be safely cast without risking overflow.
|
||||
//
|
||||
// If elements is positive, it is used to ensure the resulting slice is
|
||||
// bounded above by that many number of elements (inclusive).
|
||||
func SafeParseIntSliceRange(in interface{}, minValue int64, maxValue int64, elements int) ([]int64, error) {
|
||||
raw, err := ParseIntSlice(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if elements > 0 && len(raw) > elements {
|
||||
return nil, fmt.Errorf("error parsing value from input: got %v but expected at most %v elements", len(raw), elements)
|
||||
}
|
||||
|
||||
for index, value := range raw {
|
||||
if value < minValue || value > maxValue {
|
||||
return nil, fmt.Errorf("error parsing value from input: element %v was outside of range [%v to %v]: %v", index, minValue, maxValue, value)
|
||||
}
|
||||
}
|
||||
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
// Parses the provided arbitrary value (see ParseIntSlice) into a slice of
|
||||
// int values, ensuring the each resulting value in the slice is within the
|
||||
// range for an int value. If no error occurred, the caller knows no overflow
|
||||
// occurred.
|
||||
//
|
||||
// If elements is positive, it is used to ensure the resulting slice is
|
||||
// bounded above by that many number of elements (inclusive).
|
||||
func SafeParseIntSlice(in interface{}, elements int) ([]int, error) {
|
||||
raw, err := SafeParseIntSliceRange(in, math.MinInt, math.MaxInt, elements)
|
||||
if err != nil || raw == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result = make([]int, len(raw))
|
||||
for _, element := range raw {
|
||||
result = append(result, int(element))
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
42
vendor/github.com/hashicorp/go-secure-stdlib/strutil/strutil.go
generated
vendored
42
vendor/github.com/hashicorp/go-secure-stdlib/strutil/strutil.go
generated
vendored
@ -230,16 +230,16 @@ func TrimStrings(items []string) []string {
|
||||
// strings. This also may convert the items in the slice to lower case and
|
||||
// returns a sorted slice.
|
||||
func RemoveDuplicates(items []string, lowercase bool) []string {
|
||||
itemsMap := map[string]bool{}
|
||||
itemsMap := make(map[string]struct{}, len(items))
|
||||
for _, item := range items {
|
||||
item = strings.TrimSpace(item)
|
||||
if lowercase {
|
||||
item = strings.ToLower(item)
|
||||
}
|
||||
if item == "" {
|
||||
continue
|
||||
}
|
||||
itemsMap[item] = true
|
||||
if lowercase {
|
||||
item = strings.ToLower(item)
|
||||
}
|
||||
itemsMap[item] = struct{}{}
|
||||
}
|
||||
items = make([]string, 0, len(itemsMap))
|
||||
for item := range itemsMap {
|
||||
@ -254,18 +254,21 @@ func RemoveDuplicates(items []string, lowercase bool) []string {
|
||||
// In all cases, strings are compared after trimming whitespace
|
||||
// If caseInsensitive, strings will be compared after ToLower()
|
||||
func RemoveDuplicatesStable(items []string, caseInsensitive bool) []string {
|
||||
itemsMap := make(map[string]bool, len(items))
|
||||
itemsMap := make(map[string]struct{}, len(items))
|
||||
deduplicated := make([]string, 0, len(items))
|
||||
|
||||
for _, item := range items {
|
||||
key := strings.TrimSpace(item)
|
||||
if _, ok := itemsMap[key]; ok || key == "" {
|
||||
continue
|
||||
}
|
||||
if caseInsensitive {
|
||||
key = strings.ToLower(key)
|
||||
}
|
||||
if key == "" || itemsMap[key] {
|
||||
if _, ok := itemsMap[key]; ok {
|
||||
continue
|
||||
}
|
||||
itemsMap[key] = true
|
||||
itemsMap[key] = struct{}{}
|
||||
deduplicated = append(deduplicated, item)
|
||||
}
|
||||
return deduplicated
|
||||
@ -299,17 +302,18 @@ func EquivalentSlices(a, b []string) bool {
|
||||
}
|
||||
|
||||
// First we'll build maps to ensure unique values
|
||||
mapA := map[string]bool{}
|
||||
mapB := map[string]bool{}
|
||||
mapA := make(map[string]struct{}, len(a))
|
||||
mapB := make(map[string]struct{}, len(b))
|
||||
for _, keyA := range a {
|
||||
mapA[keyA] = true
|
||||
mapA[keyA] = struct{}{}
|
||||
}
|
||||
for _, keyB := range b {
|
||||
mapB[keyB] = true
|
||||
mapB[keyB] = struct{}{}
|
||||
}
|
||||
|
||||
// Now we'll build our checking slices
|
||||
var sortedA, sortedB []string
|
||||
sortedA := make([]string, 0, len(mapA))
|
||||
sortedB := make([]string, 0, len(mapB))
|
||||
for keyA := range mapA {
|
||||
sortedA = append(sortedA, keyA)
|
||||
}
|
||||
@ -434,23 +438,21 @@ func Difference(a, b []string, lowercase bool) []string {
|
||||
a = RemoveDuplicates(a, lowercase)
|
||||
b = RemoveDuplicates(b, lowercase)
|
||||
|
||||
itemsMap := map[string]bool{}
|
||||
itemsMap := map[string]struct{}{}
|
||||
for _, aVal := range a {
|
||||
itemsMap[aVal] = true
|
||||
itemsMap[aVal] = struct{}{}
|
||||
}
|
||||
|
||||
// Perform difference calculation
|
||||
for _, bVal := range b {
|
||||
if _, ok := itemsMap[bVal]; ok {
|
||||
itemsMap[bVal] = false
|
||||
delete(itemsMap, bVal)
|
||||
}
|
||||
}
|
||||
|
||||
items := []string{}
|
||||
for item, exists := range itemsMap {
|
||||
if exists {
|
||||
items = append(items, item)
|
||||
}
|
||||
for item := range itemsMap {
|
||||
items = append(items, item)
|
||||
}
|
||||
sort.Strings(items)
|
||||
return items
|
||||
|
78
vendor/github.com/hashicorp/vault/api/auth.go
generated
vendored
78
vendor/github.com/hashicorp/vault/api/auth.go
generated
vendored
@ -31,16 +31,82 @@ func (a *Auth) Login(ctx context.Context, authMethod AuthMethod) (*Secret, error
|
||||
if authMethod == nil {
|
||||
return nil, fmt.Errorf("no auth method provided for login")
|
||||
}
|
||||
return a.login(ctx, authMethod)
|
||||
}
|
||||
|
||||
authSecret, err := authMethod.Login(ctx, a.c)
|
||||
// MFALogin is a wrapper that helps satisfy Vault's MFA implementation.
|
||||
// If optional credentials are provided a single-phase login will be attempted
|
||||
// and the resulting Secret will contain a ClientToken if the authentication is successful.
|
||||
// The client's token will also be set accordingly.
|
||||
//
|
||||
// If no credentials are provided a two-phase MFA login will be assumed and the resulting
|
||||
// Secret will have a MFARequirement containing the MFARequestID to be used in a follow-up
|
||||
// call to `sys/mfa/validate` or by passing it to the method (*Auth).MFAValidate.
|
||||
func (a *Auth) MFALogin(ctx context.Context, authMethod AuthMethod, creds ...string) (*Secret, error) {
|
||||
if len(creds) > 0 {
|
||||
a.c.SetMFACreds(creds)
|
||||
return a.login(ctx, authMethod)
|
||||
}
|
||||
|
||||
return a.twoPhaseMFALogin(ctx, authMethod)
|
||||
}
|
||||
|
||||
// MFAValidate validates an MFA request using the appropriate payload and a secret containing
|
||||
// Auth.MFARequirement, like the one returned by MFALogin when credentials are not provided.
|
||||
// Upon successful validation the client token will be set accordingly.
|
||||
//
|
||||
// The Secret returned is the authentication secret, which if desired can be
|
||||
// passed as input to the NewLifetimeWatcher method in order to start
|
||||
// automatically renewing the token.
|
||||
func (a *Auth) MFAValidate(ctx context.Context, mfaSecret *Secret, payload map[string]interface{}) (*Secret, error) {
|
||||
if mfaSecret == nil || mfaSecret.Auth == nil || mfaSecret.Auth.MFARequirement == nil {
|
||||
return nil, fmt.Errorf("secret does not contain MFARequirements")
|
||||
}
|
||||
|
||||
s, err := a.c.Sys().MFAValidateWithContext(ctx, mfaSecret.Auth.MFARequirement.GetMFARequestID(), payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a.checkAndSetToken(s)
|
||||
}
|
||||
|
||||
// login performs the (*AuthMethod).Login() with the configured client and checks that a ClientToken is returned
|
||||
func (a *Auth) login(ctx context.Context, authMethod AuthMethod) (*Secret, error) {
|
||||
s, err := authMethod.Login(ctx, a.c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to log in to auth method: %w", err)
|
||||
}
|
||||
if authSecret == nil || authSecret.Auth == nil || authSecret.Auth.ClientToken == "" {
|
||||
return nil, fmt.Errorf("login response from auth method did not return client token")
|
||||
|
||||
return a.checkAndSetToken(s)
|
||||
}
|
||||
|
||||
// twoPhaseMFALogin performs the (*AuthMethod).Login() with the configured client
|
||||
// and checks that an MFARequirement is returned
|
||||
func (a *Auth) twoPhaseMFALogin(ctx context.Context, authMethod AuthMethod) (*Secret, error) {
|
||||
s, err := authMethod.Login(ctx, a.c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to log in: %w", err)
|
||||
}
|
||||
if s == nil || s.Auth == nil || s.Auth.MFARequirement == nil {
|
||||
if s != nil {
|
||||
s.Warnings = append(s.Warnings, "expected secret to contain MFARequirements")
|
||||
}
|
||||
return s, fmt.Errorf("assumed two-phase MFA login, returned secret is missing MFARequirements")
|
||||
}
|
||||
|
||||
a.c.SetToken(authSecret.Auth.ClientToken)
|
||||
|
||||
return authSecret, nil
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (a *Auth) checkAndSetToken(s *Secret) (*Secret, error) {
|
||||
if s == nil || s.Auth == nil || s.Auth.ClientToken == "" {
|
||||
if s != nil {
|
||||
s.Warnings = append(s.Warnings, "expected secret to contain ClientToken")
|
||||
}
|
||||
return s, fmt.Errorf("response did not return ClientToken, client token not set")
|
||||
}
|
||||
|
||||
a.c.SetToken(s.Auth.ClientToken)
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
169
vendor/github.com/hashicorp/vault/api/client.go
generated
vendored
169
vendor/github.com/hashicorp/vault/api/client.go
generated
vendored
@ -36,6 +36,7 @@ const (
|
||||
EnvVaultAddress = "VAULT_ADDR"
|
||||
EnvVaultAgentAddr = "VAULT_AGENT_ADDR"
|
||||
EnvVaultCACert = "VAULT_CACERT"
|
||||
EnvVaultCACertBytes = "VAULT_CACERT_BYTES"
|
||||
EnvVaultCAPath = "VAULT_CAPATH"
|
||||
EnvVaultClientCert = "VAULT_CLIENT_CERT"
|
||||
EnvVaultClientKey = "VAULT_CLIENT_KEY"
|
||||
@ -50,6 +51,7 @@ const (
|
||||
EnvVaultMFA = "VAULT_MFA"
|
||||
EnvRateLimit = "VAULT_RATE_LIMIT"
|
||||
EnvHTTPProxy = "VAULT_HTTP_PROXY"
|
||||
EnvVaultProxyAddr = "VAULT_PROXY_ADDR"
|
||||
HeaderIndex = "X-Vault-Index"
|
||||
HeaderForward = "X-Vault-Forward"
|
||||
HeaderInconsistent = "X-Vault-Inconsistent"
|
||||
@ -142,6 +144,14 @@ type Config struct {
|
||||
// with the same client. Cloning a client will not clone this value.
|
||||
OutputCurlString bool
|
||||
|
||||
// OutputPolicy causes the actual request to return an error of type
|
||||
// *OutputPolicyError. Type asserting the error message will display
|
||||
// an example of the required policy HCL needed for the operation.
|
||||
//
|
||||
// Note: It is not thread-safe to set this and make concurrent requests
|
||||
// with the same client. Cloning a client will not clone this value.
|
||||
OutputPolicy bool
|
||||
|
||||
// curlCACert, curlCAPath, curlClientCert and curlClientKey are used to keep
|
||||
// track of the name of the TLS certs and keys when OutputCurlString is set.
|
||||
// Cloning a client will also not clone those values.
|
||||
@ -172,9 +182,14 @@ type Config struct {
|
||||
// used to communicate with Vault.
|
||||
type TLSConfig struct {
|
||||
// CACert is the path to a PEM-encoded CA cert file to use to verify the
|
||||
// Vault server SSL certificate.
|
||||
// Vault server SSL certificate. It takes precedence over CACertBytes
|
||||
// and CAPath.
|
||||
CACert string
|
||||
|
||||
// CACertBytes is a PEM-encoded certificate or bundle. It takes precedence
|
||||
// over CAPath.
|
||||
CACertBytes []byte
|
||||
|
||||
// CAPath is the path to a directory of PEM-encoded CA cert files to verify
|
||||
// the Vault server SSL certificate.
|
||||
CAPath string
|
||||
@ -266,12 +281,13 @@ func (c *Config) configureTLS(t *TLSConfig) error {
|
||||
return fmt.Errorf("both client cert and client key must be provided")
|
||||
}
|
||||
|
||||
if t.CACert != "" || t.CAPath != "" {
|
||||
if t.CACert != "" || len(t.CACertBytes) != 0 || t.CAPath != "" {
|
||||
c.curlCACert = t.CACert
|
||||
c.curlCAPath = t.CAPath
|
||||
rootConfig := &rootcerts.Config{
|
||||
CAFile: t.CACert,
|
||||
CAPath: t.CAPath,
|
||||
CAFile: t.CACert,
|
||||
CACertificate: t.CACertBytes,
|
||||
CAPath: t.CAPath,
|
||||
}
|
||||
if err := rootcerts.ConfigureTLS(clientTLSConfig, rootConfig); err != nil {
|
||||
return err
|
||||
@ -313,6 +329,7 @@ func (c *Config) ReadEnvironment() error {
|
||||
var envAddress string
|
||||
var envAgentAddress string
|
||||
var envCACert string
|
||||
var envCACertBytes []byte
|
||||
var envCAPath string
|
||||
var envClientCert string
|
||||
var envClientKey string
|
||||
@ -322,7 +339,7 @@ func (c *Config) ReadEnvironment() error {
|
||||
var envMaxRetries *uint64
|
||||
var envSRVLookup bool
|
||||
var limit *rate.Limiter
|
||||
var envHTTPProxy string
|
||||
var envVaultProxy string
|
||||
|
||||
// Parse the environment variables
|
||||
if v := os.Getenv(EnvVaultAddress); v != "" {
|
||||
@ -343,6 +360,9 @@ func (c *Config) ReadEnvironment() error {
|
||||
if v := os.Getenv(EnvVaultCACert); v != "" {
|
||||
envCACert = v
|
||||
}
|
||||
if v := os.Getenv(EnvVaultCACertBytes); v != "" {
|
||||
envCACertBytes = []byte(v)
|
||||
}
|
||||
if v := os.Getenv(EnvVaultCAPath); v != "" {
|
||||
envCAPath = v
|
||||
}
|
||||
@ -392,12 +412,18 @@ func (c *Config) ReadEnvironment() error {
|
||||
}
|
||||
|
||||
if v := os.Getenv(EnvHTTPProxy); v != "" {
|
||||
envHTTPProxy = v
|
||||
envVaultProxy = v
|
||||
}
|
||||
|
||||
// VAULT_PROXY_ADDR supersedes VAULT_HTTP_PROXY
|
||||
if v := os.Getenv(EnvVaultProxyAddr); v != "" {
|
||||
envVaultProxy = v
|
||||
}
|
||||
|
||||
// Configure the HTTP clients TLS configuration.
|
||||
t := &TLSConfig{
|
||||
CACert: envCACert,
|
||||
CACertBytes: envCACertBytes,
|
||||
CAPath: envCAPath,
|
||||
ClientCert: envClientCert,
|
||||
ClientKey: envClientKey,
|
||||
@ -431,14 +457,14 @@ func (c *Config) ReadEnvironment() error {
|
||||
c.Timeout = envClientTimeout
|
||||
}
|
||||
|
||||
if envHTTPProxy != "" {
|
||||
url, err := url.Parse(envHTTPProxy)
|
||||
if envVaultProxy != "" {
|
||||
u, err := url.Parse(envVaultProxy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
transport := c.HttpClient.Transport.(*http.Transport)
|
||||
transport.Proxy = http.ProxyURL(url)
|
||||
transport.Proxy = http.ProxyURL(u)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -576,7 +602,6 @@ func (c *Client) CloneConfig() *Config {
|
||||
newConfig.CheckRetry = c.config.CheckRetry
|
||||
newConfig.Logger = c.config.Logger
|
||||
newConfig.Limiter = c.config.Limiter
|
||||
newConfig.OutputCurlString = c.config.OutputCurlString
|
||||
newConfig.SRVLookup = c.config.SRVLookup
|
||||
newConfig.CloneHeaders = c.config.CloneHeaders
|
||||
newConfig.CloneToken = c.config.CloneToken
|
||||
@ -589,7 +614,7 @@ func (c *Client) CloneConfig() *Config {
|
||||
return newConfig
|
||||
}
|
||||
|
||||
// Sets the address of Vault in the client. The format of address should be
|
||||
// SetAddress sets the address of Vault in the client. The format of address should be
|
||||
// "<Scheme>://<Host>:<Port>". Setting this on a client will override the
|
||||
// value of VAULT_ADDR environment variable.
|
||||
func (c *Client) SetAddress(addr string) error {
|
||||
@ -616,6 +641,16 @@ func (c *Client) Address() string {
|
||||
return c.addr.String()
|
||||
}
|
||||
|
||||
func (c *Client) SetCheckRedirect(f func(*http.Request, []*http.Request) error) {
|
||||
c.modifyLock.Lock()
|
||||
defer c.modifyLock.Unlock()
|
||||
|
||||
c.config.modifyLock.Lock()
|
||||
defer c.config.modifyLock.Unlock()
|
||||
|
||||
c.config.HttpClient.CheckRedirect = f
|
||||
}
|
||||
|
||||
// SetLimiter will set the rate limiter for this client.
|
||||
// This method is thread-safe.
|
||||
// rateLimit and burst are specified according to https://godoc.org/golang.org/x/time/rate#NewLimiter
|
||||
@ -768,6 +803,24 @@ func (c *Client) SetOutputCurlString(curl bool) {
|
||||
c.config.OutputCurlString = curl
|
||||
}
|
||||
|
||||
func (c *Client) OutputPolicy() bool {
|
||||
c.modifyLock.RLock()
|
||||
defer c.modifyLock.RUnlock()
|
||||
c.config.modifyLock.RLock()
|
||||
defer c.config.modifyLock.RUnlock()
|
||||
|
||||
return c.config.OutputPolicy
|
||||
}
|
||||
|
||||
func (c *Client) SetOutputPolicy(isSet bool) {
|
||||
c.modifyLock.RLock()
|
||||
defer c.modifyLock.RUnlock()
|
||||
c.config.modifyLock.Lock()
|
||||
defer c.config.modifyLock.Unlock()
|
||||
|
||||
c.config.OutputPolicy = isSet
|
||||
}
|
||||
|
||||
// CurrentWrappingLookupFunc sets a lookup function that returns desired wrap TTLs
|
||||
// for a given operation and path.
|
||||
func (c *Client) CurrentWrappingLookupFunc() WrappingLookupFunc {
|
||||
@ -808,10 +861,39 @@ func (c *Client) setNamespace(namespace string) {
|
||||
c.headers.Set(consts.NamespaceHeaderName, namespace)
|
||||
}
|
||||
|
||||
// ClearNamespace removes the namespace header if set.
|
||||
func (c *Client) ClearNamespace() {
|
||||
c.modifyLock.Lock()
|
||||
defer c.modifyLock.Unlock()
|
||||
c.headers.Del(consts.NamespaceHeaderName)
|
||||
if c.headers != nil {
|
||||
c.headers.Del(consts.NamespaceHeaderName)
|
||||
}
|
||||
}
|
||||
|
||||
// Namespace returns the namespace currently set in this client. It will
|
||||
// return an empty string if there is no namespace set.
|
||||
func (c *Client) Namespace() string {
|
||||
c.modifyLock.Lock()
|
||||
defer c.modifyLock.Unlock()
|
||||
if c.headers == nil {
|
||||
return ""
|
||||
}
|
||||
return c.headers.Get(consts.NamespaceHeaderName)
|
||||
}
|
||||
|
||||
// WithNamespace makes a shallow copy of Client, modifies it to use
|
||||
// the given namespace, and returns it. Passing an empty string will
|
||||
// temporarily unset the namespace.
|
||||
func (c *Client) WithNamespace(namespace string) *Client {
|
||||
c2 := *c
|
||||
c2.modifyLock = sync.RWMutex{}
|
||||
c2.headers = c.Headers()
|
||||
if namespace == "" {
|
||||
c2.ClearNamespace()
|
||||
} else {
|
||||
c2.SetNamespace(namespace)
|
||||
}
|
||||
return &c2
|
||||
}
|
||||
|
||||
// Token returns the access token being used by this client. It will
|
||||
@ -990,22 +1072,21 @@ func (c *Client) clone(cloneHeaders bool) (*Client, error) {
|
||||
defer config.modifyLock.RUnlock()
|
||||
|
||||
newConfig := &Config{
|
||||
Address: config.Address,
|
||||
HttpClient: config.HttpClient,
|
||||
MinRetryWait: config.MinRetryWait,
|
||||
MaxRetryWait: config.MaxRetryWait,
|
||||
MaxRetries: config.MaxRetries,
|
||||
Timeout: config.Timeout,
|
||||
Backoff: config.Backoff,
|
||||
CheckRetry: config.CheckRetry,
|
||||
Logger: config.Logger,
|
||||
Limiter: config.Limiter,
|
||||
OutputCurlString: config.OutputCurlString,
|
||||
AgentAddress: config.AgentAddress,
|
||||
SRVLookup: config.SRVLookup,
|
||||
CloneHeaders: config.CloneHeaders,
|
||||
CloneToken: config.CloneToken,
|
||||
ReadYourWrites: config.ReadYourWrites,
|
||||
Address: config.Address,
|
||||
HttpClient: config.HttpClient,
|
||||
MinRetryWait: config.MinRetryWait,
|
||||
MaxRetryWait: config.MaxRetryWait,
|
||||
MaxRetries: config.MaxRetries,
|
||||
Timeout: config.Timeout,
|
||||
Backoff: config.Backoff,
|
||||
CheckRetry: config.CheckRetry,
|
||||
Logger: config.Logger,
|
||||
Limiter: config.Limiter,
|
||||
AgentAddress: config.AgentAddress,
|
||||
SRVLookup: config.SRVLookup,
|
||||
CloneHeaders: config.CloneHeaders,
|
||||
CloneToken: config.CloneToken,
|
||||
ReadYourWrites: config.ReadYourWrites,
|
||||
}
|
||||
client, err := NewClient(newConfig)
|
||||
if err != nil {
|
||||
@ -1131,12 +1212,23 @@ func (c *Client) rawRequestWithContext(ctx context.Context, r *Request) (*Respon
|
||||
checkRetry := c.config.CheckRetry
|
||||
backoff := c.config.Backoff
|
||||
httpClient := c.config.HttpClient
|
||||
ns := c.headers.Get(consts.NamespaceHeaderName)
|
||||
outputCurlString := c.config.OutputCurlString
|
||||
outputPolicy := c.config.OutputPolicy
|
||||
logger := c.config.Logger
|
||||
c.config.modifyLock.RUnlock()
|
||||
|
||||
c.modifyLock.RUnlock()
|
||||
|
||||
// ensure that the most current namespace setting is used at the time of the call
|
||||
// e.g. calls using (*Client).WithNamespace
|
||||
switch ns {
|
||||
case "":
|
||||
r.Headers.Del(consts.NamespaceHeaderName)
|
||||
default:
|
||||
r.Headers.Set(consts.NamespaceHeaderName, ns)
|
||||
}
|
||||
|
||||
for _, cb := range c.requestCallbacks {
|
||||
cb(r)
|
||||
}
|
||||
@ -1176,6 +1268,14 @@ START:
|
||||
return nil, LastOutputStringError
|
||||
}
|
||||
|
||||
if outputPolicy {
|
||||
LastOutputPolicyError = &OutputPolicyError{
|
||||
method: req.Method,
|
||||
path: strings.TrimPrefix(req.URL.Path, "/v1"),
|
||||
}
|
||||
return nil, LastOutputPolicyError
|
||||
}
|
||||
|
||||
req.Request = req.Request.WithContext(ctx)
|
||||
|
||||
if backoff == nil {
|
||||
@ -1268,20 +1368,31 @@ func (c *Client) httpRequestWithContext(ctx context.Context, r *Request) (*Respo
|
||||
limiter := c.config.Limiter
|
||||
httpClient := c.config.HttpClient
|
||||
outputCurlString := c.config.OutputCurlString
|
||||
outputPolicy := c.config.OutputPolicy
|
||||
|
||||
// add headers
|
||||
if c.headers != nil {
|
||||
for header, vals := range c.headers {
|
||||
for _, val := range vals {
|
||||
req.Header.Add(header, val)
|
||||
}
|
||||
}
|
||||
// explicitly set the namespace header to current client
|
||||
if ns := c.headers.Get(consts.NamespaceHeaderName); ns != "" {
|
||||
r.Headers.Set(consts.NamespaceHeaderName, ns)
|
||||
}
|
||||
}
|
||||
|
||||
c.config.modifyLock.RUnlock()
|
||||
c.modifyLock.RUnlock()
|
||||
|
||||
// OutputCurlString logic relies on the request type to be retryable.Request as
|
||||
// OutputCurlString and OutputPolicy logic rely on the request type to be retryable.Request
|
||||
if outputCurlString {
|
||||
return nil, fmt.Errorf("output-curl-string is not implemented for this request")
|
||||
}
|
||||
if outputPolicy {
|
||||
return nil, fmt.Errorf("output-policy is not implemented for this request")
|
||||
}
|
||||
|
||||
req.URL.User = r.URL.User
|
||||
req.URL.Scheme = r.URL.Scheme
|
||||
|
25
vendor/github.com/hashicorp/vault/api/lifetime_watcher.go
generated
vendored
25
vendor/github.com/hashicorp/vault/api/lifetime_watcher.go
generated
vendored
@ -113,7 +113,9 @@ type LifetimeWatcherInput struct {
|
||||
|
||||
// The new TTL, in seconds, that should be set on the lease. The TTL set
|
||||
// here may or may not be honored by the vault server, based on Vault
|
||||
// configuration or any associated max TTL values.
|
||||
// configuration or any associated max TTL values. If specified, the
|
||||
// minimum of this value and the remaining lease duration will be used
|
||||
// for grace period calculations.
|
||||
Increment int
|
||||
|
||||
// RenewBehavior controls what happens when a renewal errors or the
|
||||
@ -257,7 +259,7 @@ func (r *LifetimeWatcher) doRenewWithOptions(tokenMode bool, nonRenewable bool,
|
||||
|
||||
initialTime := time.Now()
|
||||
priorDuration := time.Duration(initLeaseDuration) * time.Second
|
||||
r.calculateGrace(priorDuration)
|
||||
r.calculateGrace(priorDuration, time.Duration(r.increment)*time.Second)
|
||||
var errorBackoff backoff.BackOff
|
||||
|
||||
for {
|
||||
@ -345,7 +347,7 @@ func (r *LifetimeWatcher) doRenewWithOptions(tokenMode bool, nonRenewable bool,
|
||||
// extending. Once it stops extending, we've hit the max and need to
|
||||
// rely on the grace duration.
|
||||
if remainingLeaseDuration > priorDuration {
|
||||
r.calculateGrace(remainingLeaseDuration)
|
||||
r.calculateGrace(remainingLeaseDuration, time.Duration(r.increment)*time.Second)
|
||||
}
|
||||
priorDuration = remainingLeaseDuration
|
||||
|
||||
@ -373,16 +375,21 @@ func (r *LifetimeWatcher) doRenewWithOptions(tokenMode bool, nonRenewable bool,
|
||||
}
|
||||
}
|
||||
|
||||
// calculateGrace calculates the grace period based on a reasonable set of
|
||||
// assumptions given the total lease time; it also adds some jitter to not have
|
||||
// clients be in sync.
|
||||
func (r *LifetimeWatcher) calculateGrace(leaseDuration time.Duration) {
|
||||
if leaseDuration <= 0 {
|
||||
// calculateGrace calculates the grace period based on the minimum of the
|
||||
// remaining lease duration and the token increment value; it also adds some
|
||||
// jitter to not have clients be in sync.
|
||||
func (r *LifetimeWatcher) calculateGrace(leaseDuration, increment time.Duration) {
|
||||
minDuration := leaseDuration
|
||||
if minDuration > increment && increment > 0 {
|
||||
minDuration = increment
|
||||
}
|
||||
|
||||
if minDuration <= 0 {
|
||||
r.grace = 0
|
||||
return
|
||||
}
|
||||
|
||||
leaseNanos := float64(leaseDuration.Nanoseconds())
|
||||
leaseNanos := float64(minDuration.Nanoseconds())
|
||||
jitterMax := 0.1 * leaseNanos
|
||||
|
||||
// For a given lease duration, we want to allow 80-90% of that to elapse,
|
||||
|
2
vendor/github.com/hashicorp/vault/api/logical.go
generated
vendored
2
vendor/github.com/hashicorp/vault/api/logical.go
generated
vendored
@ -323,7 +323,7 @@ func (c *Logical) UnwrapWithContext(ctx context.Context, wrappingToken string) (
|
||||
c.c.SetToken(wrappingToken)
|
||||
}
|
||||
|
||||
secret, err = c.Read(wrappedResponseLocation)
|
||||
secret, err = c.ReadWithContext(ctx, wrappedResponseLocation)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrapf(fmt.Sprintf("error reading %q: {{err}}", wrappedResponseLocation), err)
|
||||
}
|
||||
|
82
vendor/github.com/hashicorp/vault/api/output_policy.go
generated
vendored
Normal file
82
vendor/github.com/hashicorp/vault/api/output_policy.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ErrOutputPolicyRequest = "output a policy, please"
|
||||
)
|
||||
|
||||
var LastOutputPolicyError *OutputPolicyError
|
||||
|
||||
type OutputPolicyError struct {
|
||||
method string
|
||||
path string
|
||||
finalHCLString string
|
||||
}
|
||||
|
||||
func (d *OutputPolicyError) Error() string {
|
||||
if d.finalHCLString == "" {
|
||||
p, err := d.buildSamplePolicy()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
d.finalHCLString = p
|
||||
}
|
||||
|
||||
return ErrOutputPolicyRequest
|
||||
}
|
||||
|
||||
func (d *OutputPolicyError) HCLString() (string, error) {
|
||||
if d.finalHCLString == "" {
|
||||
p, err := d.buildSamplePolicy()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
d.finalHCLString = p
|
||||
}
|
||||
return d.finalHCLString, nil
|
||||
}
|
||||
|
||||
// Builds a sample policy document from the request
|
||||
func (d *OutputPolicyError) buildSamplePolicy() (string, error) {
|
||||
var capabilities []string
|
||||
switch d.method {
|
||||
case http.MethodGet, "":
|
||||
capabilities = append(capabilities, "read")
|
||||
case http.MethodPost, http.MethodPut:
|
||||
capabilities = append(capabilities, "create")
|
||||
capabilities = append(capabilities, "update")
|
||||
case http.MethodPatch:
|
||||
capabilities = append(capabilities, "patch")
|
||||
case http.MethodDelete:
|
||||
capabilities = append(capabilities, "delete")
|
||||
case "LIST":
|
||||
capabilities = append(capabilities, "list")
|
||||
}
|
||||
|
||||
// sanitize, then trim the Vault address and v1 from the front of the path
|
||||
path, err := url.PathUnescape(d.path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to unescape request URL characters: %v", err)
|
||||
}
|
||||
|
||||
// determine whether to add sudo capability
|
||||
if IsSudoPath(path) {
|
||||
capabilities = append(capabilities, "sudo")
|
||||
}
|
||||
|
||||
// the OpenAPI response has a / in front of each path,
|
||||
// but policies need the path without that leading slash
|
||||
path = strings.TrimLeft(path, "/")
|
||||
|
||||
capStr := strings.Join(capabilities, `", "`)
|
||||
return fmt.Sprintf(
|
||||
`path "%s" {
|
||||
capabilities = ["%s"]
|
||||
}`, path, capStr), nil
|
||||
}
|
55
vendor/github.com/hashicorp/vault/api/output_string.go
generated
vendored
55
vendor/github.com/hashicorp/vault/api/output_string.go
generated
vendored
@ -19,58 +19,68 @@ type OutputStringError struct {
|
||||
TLSSkipVerify bool
|
||||
ClientCACert, ClientCAPath string
|
||||
ClientCert, ClientKey string
|
||||
parsingError error
|
||||
parsedCurlString string
|
||||
finalCurlString string
|
||||
}
|
||||
|
||||
func (d *OutputStringError) Error() string {
|
||||
if d.parsedCurlString == "" {
|
||||
d.parseRequest()
|
||||
if d.parsingError != nil {
|
||||
return d.parsingError.Error()
|
||||
if d.finalCurlString == "" {
|
||||
cs, err := d.buildCurlString()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
d.finalCurlString = cs
|
||||
}
|
||||
|
||||
return ErrOutputStringRequest
|
||||
}
|
||||
|
||||
func (d *OutputStringError) parseRequest() {
|
||||
func (d *OutputStringError) CurlString() (string, error) {
|
||||
if d.finalCurlString == "" {
|
||||
cs, err := d.buildCurlString()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
d.finalCurlString = cs
|
||||
}
|
||||
return d.finalCurlString, nil
|
||||
}
|
||||
|
||||
func (d *OutputStringError) buildCurlString() (string, error) {
|
||||
body, err := d.Request.BodyBytes()
|
||||
if err != nil {
|
||||
d.parsingError = err
|
||||
return
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Build cURL string
|
||||
d.parsedCurlString = "curl "
|
||||
finalCurlString := "curl "
|
||||
if d.TLSSkipVerify {
|
||||
d.parsedCurlString += "--insecure "
|
||||
finalCurlString += "--insecure "
|
||||
}
|
||||
if d.Request.Method != http.MethodGet {
|
||||
d.parsedCurlString = fmt.Sprintf("%s-X %s ", d.parsedCurlString, d.Request.Method)
|
||||
finalCurlString = fmt.Sprintf("%s-X %s ", finalCurlString, d.Request.Method)
|
||||
}
|
||||
if d.ClientCACert != "" {
|
||||
clientCACert := strings.Replace(d.ClientCACert, "'", "'\"'\"'", -1)
|
||||
d.parsedCurlString = fmt.Sprintf("%s--cacert '%s' ", d.parsedCurlString, clientCACert)
|
||||
finalCurlString = fmt.Sprintf("%s--cacert '%s' ", finalCurlString, clientCACert)
|
||||
}
|
||||
if d.ClientCAPath != "" {
|
||||
clientCAPath := strings.Replace(d.ClientCAPath, "'", "'\"'\"'", -1)
|
||||
d.parsedCurlString = fmt.Sprintf("%s--capath '%s' ", d.parsedCurlString, clientCAPath)
|
||||
finalCurlString = fmt.Sprintf("%s--capath '%s' ", finalCurlString, clientCAPath)
|
||||
}
|
||||
if d.ClientCert != "" {
|
||||
clientCert := strings.Replace(d.ClientCert, "'", "'\"'\"'", -1)
|
||||
d.parsedCurlString = fmt.Sprintf("%s--cert '%s' ", d.parsedCurlString, clientCert)
|
||||
finalCurlString = fmt.Sprintf("%s--cert '%s' ", finalCurlString, clientCert)
|
||||
}
|
||||
if d.ClientKey != "" {
|
||||
clientKey := strings.Replace(d.ClientKey, "'", "'\"'\"'", -1)
|
||||
d.parsedCurlString = fmt.Sprintf("%s--key '%s' ", d.parsedCurlString, clientKey)
|
||||
finalCurlString = fmt.Sprintf("%s--key '%s' ", finalCurlString, clientKey)
|
||||
}
|
||||
for k, v := range d.Request.Header {
|
||||
for _, h := range v {
|
||||
if strings.ToLower(k) == "x-vault-token" {
|
||||
h = `$(vault print token)`
|
||||
}
|
||||
d.parsedCurlString = fmt.Sprintf("%s-H \"%s: %s\" ", d.parsedCurlString, k, h)
|
||||
finalCurlString = fmt.Sprintf("%s-H \"%s: %s\" ", finalCurlString, k, h)
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,15 +88,8 @@ func (d *OutputStringError) parseRequest() {
|
||||
// We need to escape single quotes since that's what we're using to
|
||||
// quote the body
|
||||
escapedBody := strings.Replace(string(body), "'", "'\"'\"'", -1)
|
||||
d.parsedCurlString = fmt.Sprintf("%s-d '%s' ", d.parsedCurlString, escapedBody)
|
||||
finalCurlString = fmt.Sprintf("%s-d '%s' ", finalCurlString, escapedBody)
|
||||
}
|
||||
|
||||
d.parsedCurlString = fmt.Sprintf("%s%s", d.parsedCurlString, d.Request.URL.String())
|
||||
}
|
||||
|
||||
func (d *OutputStringError) CurlString() string {
|
||||
if d.parsedCurlString == "" {
|
||||
d.parseRequest()
|
||||
}
|
||||
return d.parsedCurlString
|
||||
return fmt.Sprintf("%s%s", finalCurlString, d.Request.URL.String()), nil
|
||||
}
|
||||
|
69
vendor/github.com/hashicorp/vault/api/plugin_helpers.go
generated
vendored
69
vendor/github.com/hashicorp/vault/api/plugin_helpers.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
||||
"flag"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
|
||||
squarejwt "gopkg.in/square/go-jose.v2/jwt"
|
||||
|
||||
@ -23,6 +24,49 @@ var (
|
||||
// PluginUnwrapTokenEnv is the ENV name used to pass unwrap tokens to the
|
||||
// plugin.
|
||||
PluginUnwrapTokenEnv = "VAULT_UNWRAP_TOKEN"
|
||||
|
||||
// sudoPaths is a map containing the paths that require a token's policy
|
||||
// to have the "sudo" capability. The keys are the paths as strings, in
|
||||
// the same format as they are returned by the OpenAPI spec. The values
|
||||
// are the regular expressions that can be used to test whether a given
|
||||
// path matches that path or not (useful specifically for the paths that
|
||||
// contain templated fields.)
|
||||
sudoPaths = map[string]*regexp.Regexp{
|
||||
"/auth/token/accessors/": regexp.MustCompile(`^/auth/token/accessors/$`),
|
||||
"/pki/root": regexp.MustCompile(`^/pki/root$`),
|
||||
"/pki/root/sign-self-issued": regexp.MustCompile(`^/pki/root/sign-self-issued$`),
|
||||
"/sys/audit": regexp.MustCompile(`^/sys/audit$`),
|
||||
"/sys/audit/{path}": regexp.MustCompile(`^/sys/audit/.+$`),
|
||||
"/sys/auth/{path}": regexp.MustCompile(`^/sys/auth/.+$`),
|
||||
"/sys/auth/{path}/tune": regexp.MustCompile(`^/sys/auth/.+/tune$`),
|
||||
"/sys/config/auditing/request-headers": regexp.MustCompile(`^/sys/config/auditing/request-headers$`),
|
||||
"/sys/config/auditing/request-headers/{header}": regexp.MustCompile(`^/sys/config/auditing/request-headers/.+$`),
|
||||
"/sys/config/cors": regexp.MustCompile(`^/sys/config/cors$`),
|
||||
"/sys/config/ui/headers/": regexp.MustCompile(`^/sys/config/ui/headers/$`),
|
||||
"/sys/config/ui/headers/{header}": regexp.MustCompile(`^/sys/config/ui/headers/.+$`),
|
||||
"/sys/leases": regexp.MustCompile(`^/sys/leases$`),
|
||||
"/sys/leases/lookup/": regexp.MustCompile(`^/sys/leases/lookup/$`),
|
||||
"/sys/leases/lookup/{prefix}": regexp.MustCompile(`^/sys/leases/lookup/.+$`),
|
||||
"/sys/leases/revoke-force/{prefix}": regexp.MustCompile(`^/sys/leases/revoke-force/.+$`),
|
||||
"/sys/leases/revoke-prefix/{prefix}": regexp.MustCompile(`^/sys/leases/revoke-prefix/.+$`),
|
||||
"/sys/plugins/catalog/{name}": regexp.MustCompile(`^/sys/plugins/catalog/[^/]+$`),
|
||||
"/sys/plugins/catalog/{type}": regexp.MustCompile(`^/sys/plugins/catalog/[\w-]+$`),
|
||||
"/sys/plugins/catalog/{type}/{name}": regexp.MustCompile(`^/sys/plugins/catalog/[\w-]+/[^/]+$`),
|
||||
"/sys/raw": regexp.MustCompile(`^/sys/raw$`),
|
||||
"/sys/raw/{path}": regexp.MustCompile(`^/sys/raw/.+$`),
|
||||
"/sys/remount": regexp.MustCompile(`^/sys/remount$`),
|
||||
"/sys/revoke-force/{prefix}": regexp.MustCompile(`^/sys/revoke-force/.+$`),
|
||||
"/sys/revoke-prefix/{prefix}": regexp.MustCompile(`^/sys/revoke-prefix/.+$`),
|
||||
"/sys/rotate": regexp.MustCompile(`^/sys/rotate$`),
|
||||
|
||||
// enterprise-only paths
|
||||
"/sys/replication/dr/primary/secondary-token": regexp.MustCompile(`^/sys/replication/dr/primary/secondary-token$`),
|
||||
"/sys/replication/performance/primary/secondary-token": regexp.MustCompile(`^/sys/replication/performance/primary/secondary-token$`),
|
||||
"/sys/replication/primary/secondary-token": regexp.MustCompile(`^/sys/replication/primary/secondary-token$`),
|
||||
"/sys/replication/reindex": regexp.MustCompile(`^/sys/replication/reindex$`),
|
||||
"/sys/storage/raft/snapshot-auto/config/": regexp.MustCompile(`^/sys/storage/raft/snapshot-auto/config/$`),
|
||||
"/sys/storage/raft/snapshot-auto/config/{name}": regexp.MustCompile(`^/sys/storage/raft/snapshot-auto/config/[^/]+$`),
|
||||
}
|
||||
)
|
||||
|
||||
// PluginAPIClientMeta is a helper that plugins can use to configure TLS connections
|
||||
@ -192,3 +236,28 @@ func VaultPluginTLSProviderContext(ctx context.Context, apiTLSConfig *TLSConfig)
|
||||
return tlsConfig, nil
|
||||
}
|
||||
}
|
||||
|
||||
func SudoPaths() map[string]*regexp.Regexp {
|
||||
return sudoPaths
|
||||
}
|
||||
|
||||
// Determine whether the given path requires the sudo capability
|
||||
func IsSudoPath(path string) bool {
|
||||
// Return early if the path is any of the non-templated sudo paths.
|
||||
if _, ok := sudoPaths[path]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
// Some sudo paths have templated fields in them.
|
||||
// (e.g. /sys/revoke-prefix/{prefix})
|
||||
// The values in the sudoPaths map are actually regular expressions,
|
||||
// so we can check if our path matches against them.
|
||||
for _, sudoPathRegexp := range sudoPaths {
|
||||
match := sudoPathRegexp.MatchString(path)
|
||||
if match {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
7
vendor/github.com/hashicorp/vault/api/secret.go
generated
vendored
7
vendor/github.com/hashicorp/vault/api/secret.go
generated
vendored
@ -94,12 +94,7 @@ func (s *Secret) TokenRemainingUses() (int, error) {
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
uses, err := parseutil.ParseInt(s.Data["num_uses"])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return int(uses), nil
|
||||
return parseutil.SafeParseInt(s.Data["num_uses"])
|
||||
}
|
||||
|
||||
// TokenPolicies returns the standardized list of policies for the given secret.
|
||||
|
3
vendor/github.com/hashicorp/vault/api/sys_hastatus.go
generated
vendored
3
vendor/github.com/hashicorp/vault/api/sys_hastatus.go
generated
vendored
@ -37,4 +37,7 @@ type HANode struct {
|
||||
ClusterAddress string `json:"cluster_address"`
|
||||
ActiveNode bool `json:"active_node"`
|
||||
LastEcho *time.Time `json:"last_echo"`
|
||||
Version string `json:"version"`
|
||||
UpgradeVersion string `json:"upgrade_version,omitempty"`
|
||||
RedundancyZone string `json:"redundancy_zone,omitempty"`
|
||||
}
|
||||
|
45
vendor/github.com/hashicorp/vault/api/sys_mfa.go
generated
vendored
Normal file
45
vendor/github.com/hashicorp/vault/api/sys_mfa.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (c *Sys) MFAValidate(requestID string, payload map[string]interface{}) (*Secret, error) {
|
||||
return c.MFAValidateWithContext(context.Background(), requestID, payload)
|
||||
}
|
||||
|
||||
func (c *Sys) MFAValidateWithContext(ctx context.Context, requestID string, payload map[string]interface{}) (*Secret, error) {
|
||||
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
|
||||
defer cancelFunc()
|
||||
|
||||
body := map[string]interface{}{
|
||||
"mfa_request_id": requestID,
|
||||
"mfa_payload": payload,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest(http.MethodPost, fmt.Sprintf("/v1/sys/mfa/validate"))
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return nil, fmt.Errorf("failed to set request body: %w", err)
|
||||
}
|
||||
|
||||
resp, err := c.c.rawRequestWithContext(ctx, r)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse secret from response: %w", err)
|
||||
}
|
||||
|
||||
if secret == nil {
|
||||
return nil, fmt.Errorf("data from server response is empty")
|
||||
}
|
||||
|
||||
return secret, nil
|
||||
}
|
10
vendor/github.com/hashicorp/vault/api/sys_monitor.go
generated
vendored
10
vendor/github.com/hashicorp/vault/api/sys_monitor.go
generated
vendored
@ -5,11 +5,13 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/logging"
|
||||
)
|
||||
|
||||
// Monitor returns a channel that outputs strings containing the log messages
|
||||
// coming from the server.
|
||||
func (c *Sys) Monitor(ctx context.Context, logLevel string) (chan string, error) {
|
||||
func (c *Sys) Monitor(ctx context.Context, logLevel string, logFormat string) (chan string, error) {
|
||||
r := c.c.NewRequest(http.MethodGet, "/v1/sys/monitor")
|
||||
|
||||
if logLevel == "" {
|
||||
@ -18,6 +20,12 @@ func (c *Sys) Monitor(ctx context.Context, logLevel string) (chan string, error)
|
||||
r.Params.Add("log_level", logLevel)
|
||||
}
|
||||
|
||||
if logFormat == "" || logFormat == logging.UnspecifiedFormat.String() {
|
||||
r.Params.Add("log_format", "standard")
|
||||
} else {
|
||||
r.Params.Add("log_format", logFormat)
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequestWithContext(ctx, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
17
vendor/github.com/hashicorp/vault/api/sys_plugins.go
generated
vendored
17
vendor/github.com/hashicorp/vault/api/sys_plugins.go
generated
vendored
@ -100,23 +100,24 @@ func (c *Sys) ListPluginsWithContext(ctx context.Context, i *ListPluginsInput) (
|
||||
PluginsByType: make(map[consts.PluginType][]string),
|
||||
}
|
||||
if i.Type == consts.PluginTypeUnknown {
|
||||
for pluginTypeStr, pluginsRaw := range secret.Data {
|
||||
pluginType, err := consts.ParsePluginType(pluginTypeStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
for _, pluginType := range consts.PluginTypes {
|
||||
pluginsRaw, ok := secret.Data[pluginType.String()]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
pluginsIfc, ok := pluginsRaw.([]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unable to parse plugins for %q type", pluginTypeStr)
|
||||
return nil, fmt.Errorf("unable to parse plugins for %q type", pluginType.String())
|
||||
}
|
||||
|
||||
plugins := make([]string, len(pluginsIfc))
|
||||
for i, nameIfc := range pluginsIfc {
|
||||
plugins := make([]string, 0, len(pluginsIfc))
|
||||
for _, nameIfc := range pluginsIfc {
|
||||
name, ok := nameIfc.(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
plugins[i] = name
|
||||
plugins = append(plugins, name)
|
||||
}
|
||||
result.PluginsByType[pluginType] = plugins
|
||||
}
|
||||
|
67
vendor/github.com/hashicorp/vault/api/sys_raft.go
generated
vendored
67
vendor/github.com/hashicorp/vault/api/sys_raft.go
generated
vendored
@ -44,6 +44,7 @@ type AutopilotConfig struct {
|
||||
MaxTrailingLogs uint64 `json:"max_trailing_logs" mapstructure:"max_trailing_logs"`
|
||||
MinQuorum uint `json:"min_quorum" mapstructure:"min_quorum"`
|
||||
ServerStabilizationTime time.Duration `json:"server_stabilization_time" mapstructure:"-"`
|
||||
DisableUpgradeMigration bool `json:"disable_upgrade_migration" mapstructure:"disable_upgrade_migration"`
|
||||
}
|
||||
|
||||
// MarshalJSON makes the autopilot config fields JSON compatible
|
||||
@ -55,6 +56,7 @@ func (ac *AutopilotConfig) MarshalJSON() ([]byte, error) {
|
||||
"max_trailing_logs": ac.MaxTrailingLogs,
|
||||
"min_quorum": ac.MinQuorum,
|
||||
"server_stabilization_time": ac.ServerStabilizationTime.String(),
|
||||
"disable_upgrade_migration": ac.DisableUpgradeMigration,
|
||||
})
|
||||
}
|
||||
|
||||
@ -84,28 +86,59 @@ func (ac *AutopilotConfig) UnmarshalJSON(b []byte) error {
|
||||
|
||||
// AutopilotState represents the response of the raft autopilot state API
|
||||
type AutopilotState struct {
|
||||
Healthy bool `mapstructure:"healthy"`
|
||||
FailureTolerance int `mapstructure:"failure_tolerance"`
|
||||
Servers map[string]*AutopilotServer `mapstructure:"servers"`
|
||||
Leader string `mapstructure:"leader"`
|
||||
Voters []string `mapstructure:"voters"`
|
||||
NonVoters []string `mapstructure:"non_voters"`
|
||||
Healthy bool `mapstructure:"healthy"`
|
||||
FailureTolerance int `mapstructure:"failure_tolerance"`
|
||||
Servers map[string]*AutopilotServer `mapstructure:"servers"`
|
||||
Leader string `mapstructure:"leader"`
|
||||
Voters []string `mapstructure:"voters"`
|
||||
NonVoters []string `mapstructure:"non_voters"`
|
||||
RedundancyZones map[string]AutopilotZone `mapstructure:"redundancy_zones,omitempty"`
|
||||
Upgrade *AutopilotUpgrade `mapstructure:"upgrade_info,omitempty"`
|
||||
OptimisticFailureTolerance int `mapstructure:"optimistic_failure_tolerance,omitempty"`
|
||||
}
|
||||
|
||||
// AutopilotServer represents the server blocks in the response of the raft
|
||||
// autopilot state API.
|
||||
type AutopilotServer struct {
|
||||
ID string `mapstructure:"id"`
|
||||
Name string `mapstructure:"name"`
|
||||
Address string `mapstructure:"address"`
|
||||
NodeStatus string `mapstructure:"node_status"`
|
||||
LastContact string `mapstructure:"last_contact"`
|
||||
LastTerm uint64 `mapstructure:"last_term"`
|
||||
LastIndex uint64 `mapstructure:"last_index"`
|
||||
Healthy bool `mapstructure:"healthy"`
|
||||
StableSince string `mapstructure:"stable_since"`
|
||||
Status string `mapstructure:"status"`
|
||||
Meta map[string]string `mapstructure:"meta"`
|
||||
ID string `mapstructure:"id"`
|
||||
Name string `mapstructure:"name"`
|
||||
Address string `mapstructure:"address"`
|
||||
NodeStatus string `mapstructure:"node_status"`
|
||||
LastContact string `mapstructure:"last_contact"`
|
||||
LastTerm uint64 `mapstructure:"last_term"`
|
||||
LastIndex uint64 `mapstructure:"last_index"`
|
||||
Healthy bool `mapstructure:"healthy"`
|
||||
StableSince string `mapstructure:"stable_since"`
|
||||
Status string `mapstructure:"status"`
|
||||
Version string `mapstructure:"version"`
|
||||
UpgradeVersion string `mapstructure:"upgrade_version,omitempty"`
|
||||
RedundancyZone string `mapstructure:"redundancy_zone,omitempty"`
|
||||
NodeType string `mapstructure:"node_type,omitempty"`
|
||||
}
|
||||
|
||||
type AutopilotZone struct {
|
||||
Servers []string `mapstructure:"servers,omitempty"`
|
||||
Voters []string `mapstructure:"voters,omitempty"`
|
||||
FailureTolerance int `mapstructure:"failure_tolerance,omitempty"`
|
||||
}
|
||||
|
||||
type AutopilotUpgrade struct {
|
||||
Status string `mapstructure:"status"`
|
||||
TargetVersion string `mapstructure:"target_version,omitempty"`
|
||||
TargetVersionVoters []string `mapstructure:"target_version_voters,omitempty"`
|
||||
TargetVersionNonVoters []string `mapstructure:"target_version_non_voters,omitempty"`
|
||||
TargetVersionReadReplicas []string `mapstructure:"target_version_read_replicas,omitempty"`
|
||||
OtherVersionVoters []string `mapstructure:"other_version_voters,omitempty"`
|
||||
OtherVersionNonVoters []string `mapstructure:"other_version_non_voters,omitempty"`
|
||||
OtherVersionReadReplicas []string `mapstructure:"other_version_read_replicas,omitempty"`
|
||||
RedundancyZones map[string]AutopilotZoneUpgradeVersions `mapstructure:"redundancy_zones,omitempty"`
|
||||
}
|
||||
|
||||
type AutopilotZoneUpgradeVersions struct {
|
||||
TargetVersionVoters []string `mapstructure:"target_version_voters,omitempty"`
|
||||
TargetVersionNonVoters []string `mapstructure:"target_version_non_voters,omitempty"`
|
||||
OtherVersionVoters []string `mapstructure:"other_version_voters,omitempty"`
|
||||
OtherVersionNonVoters []string `mapstructure:"other_version_non_voters,omitempty"`
|
||||
}
|
||||
|
||||
// RaftJoin wraps RaftJoinWithContext using context.Background.
|
||||
|
1
vendor/github.com/hashicorp/vault/api/sys_seal.go
generated
vendored
1
vendor/github.com/hashicorp/vault/api/sys_seal.go
generated
vendored
@ -101,6 +101,7 @@ type SealStatusResponse struct {
|
||||
Progress int `json:"progress"`
|
||||
Nonce string `json:"nonce"`
|
||||
Version string `json:"version"`
|
||||
BuildDate string `json:"build_date"`
|
||||
Migration bool `json:"migration"`
|
||||
ClusterName string `json:"cluster_name,omitempty"`
|
||||
ClusterID string `json:"cluster_id,omitempty"`
|
||||
|
192
vendor/github.com/hashicorp/vault/sdk/helper/certutil/helpers.go
generated
vendored
192
vendor/github.com/hashicorp/vault/sdk/helper/certutil/helpers.go
generated
vendored
@ -150,6 +150,46 @@ func ParsePKIJSON(input []byte) (*ParsedCertBundle, error) {
|
||||
return nil, errutil.UserError{Err: "unable to parse out of either secret data or a secret object"}
|
||||
}
|
||||
|
||||
func ParseDERKey(privateKeyBytes []byte) (signer crypto.Signer, format BlockType, err error) {
|
||||
if signer, err = x509.ParseECPrivateKey(privateKeyBytes); err == nil {
|
||||
format = ECBlock
|
||||
return
|
||||
}
|
||||
|
||||
if signer, err = x509.ParsePKCS1PrivateKey(privateKeyBytes); err == nil {
|
||||
format = PKCS1Block
|
||||
return
|
||||
}
|
||||
|
||||
var rawKey interface{}
|
||||
if rawKey, err = x509.ParsePKCS8PrivateKey(privateKeyBytes); err == nil {
|
||||
switch rawSigner := rawKey.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
signer = rawSigner
|
||||
case *ecdsa.PrivateKey:
|
||||
signer = rawSigner
|
||||
case ed25519.PrivateKey:
|
||||
signer = rawSigner
|
||||
default:
|
||||
return nil, UnknownBlock, errutil.InternalError{Err: "unknown type for parsed PKCS8 Private Key"}
|
||||
}
|
||||
|
||||
format = PKCS8Block
|
||||
return
|
||||
}
|
||||
|
||||
return nil, UnknownBlock, err
|
||||
}
|
||||
|
||||
func ParsePEMKey(keyPem string) (crypto.Signer, BlockType, error) {
|
||||
pemBlock, _ := pem.Decode([]byte(keyPem))
|
||||
if pemBlock == nil {
|
||||
return nil, UnknownBlock, errutil.UserError{Err: "no data found in PEM block"}
|
||||
}
|
||||
|
||||
return ParseDERKey(pemBlock.Bytes)
|
||||
}
|
||||
|
||||
// ParsePEMBundle takes a string of concatenated PEM-format certificate
|
||||
// and private key values and decodes/parses them, checking validity along
|
||||
// the way. The first certificate must be the subject certificate and issuing
|
||||
@ -170,43 +210,19 @@ func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
|
||||
return nil, errutil.UserError{Err: "no data found in PEM block"}
|
||||
}
|
||||
|
||||
if signer, err := x509.ParseECPrivateKey(pemBlock.Bytes); err == nil {
|
||||
if signer, format, err := ParseDERKey(pemBlock.Bytes); err == nil {
|
||||
if parsedBundle.PrivateKeyType != UnknownPrivateKey {
|
||||
return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"}
|
||||
}
|
||||
parsedBundle.PrivateKeyFormat = ECBlock
|
||||
parsedBundle.PrivateKeyType = ECPrivateKey
|
||||
|
||||
parsedBundle.PrivateKeyFormat = format
|
||||
parsedBundle.PrivateKeyType = GetPrivateKeyTypeFromSigner(signer)
|
||||
if parsedBundle.PrivateKeyType == UnknownPrivateKey {
|
||||
return nil, errutil.UserError{Err: "Unknown type of private key included in the bundle: %v"}
|
||||
}
|
||||
|
||||
parsedBundle.PrivateKeyBytes = pemBlock.Bytes
|
||||
parsedBundle.PrivateKey = signer
|
||||
|
||||
} else if signer, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil {
|
||||
if parsedBundle.PrivateKeyType != UnknownPrivateKey {
|
||||
return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"}
|
||||
}
|
||||
parsedBundle.PrivateKeyType = RSAPrivateKey
|
||||
parsedBundle.PrivateKeyFormat = PKCS1Block
|
||||
parsedBundle.PrivateKeyBytes = pemBlock.Bytes
|
||||
parsedBundle.PrivateKey = signer
|
||||
} else if signer, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err == nil {
|
||||
parsedBundle.PrivateKeyFormat = PKCS8Block
|
||||
|
||||
if parsedBundle.PrivateKeyType != UnknownPrivateKey {
|
||||
return nil, errutil.UserError{Err: "More than one private key given; provide only one private key in the bundle"}
|
||||
}
|
||||
switch signer := signer.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
parsedBundle.PrivateKey = signer
|
||||
parsedBundle.PrivateKeyType = RSAPrivateKey
|
||||
parsedBundle.PrivateKeyBytes = pemBlock.Bytes
|
||||
case *ecdsa.PrivateKey:
|
||||
parsedBundle.PrivateKey = signer
|
||||
parsedBundle.PrivateKeyType = ECPrivateKey
|
||||
parsedBundle.PrivateKeyBytes = pemBlock.Bytes
|
||||
case ed25519.PrivateKey:
|
||||
parsedBundle.PrivateKey = signer
|
||||
parsedBundle.PrivateKeyType = Ed25519PrivateKey
|
||||
parsedBundle.PrivateKeyBytes = pemBlock.Bytes
|
||||
}
|
||||
} else if certificates, err := x509.ParseCertificates(pemBlock.Bytes); err == nil {
|
||||
certPath = append(certPath, &CertBlock{
|
||||
Certificate: certificates[0],
|
||||
@ -336,7 +352,21 @@ func generateSerialNumber(randReader io.Reader) (*big.Int, error) {
|
||||
return serial, nil
|
||||
}
|
||||
|
||||
// ComparePublicKeys compares two public keys and returns true if they match
|
||||
// ComparePublicKeysAndType compares two public keys and returns true if they match,
|
||||
// false if their types or contents differ, and an error on unsupported key types.
|
||||
func ComparePublicKeysAndType(key1Iface, key2Iface crypto.PublicKey) (bool, error) {
|
||||
equal, err := ComparePublicKeys(key1Iface, key2Iface)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "key types do not match:") {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return equal, err
|
||||
}
|
||||
|
||||
// ComparePublicKeys compares two public keys and returns true if they match,
|
||||
// returns an error if public key types are mismatched, or they are an unsupported key type.
|
||||
func ComparePublicKeys(key1Iface, key2Iface crypto.PublicKey) (bool, error) {
|
||||
switch key1Iface.(type) {
|
||||
case *rsa.PublicKey:
|
||||
@ -585,25 +615,17 @@ func DefaultOrValueKeyBits(keyType string, keyBits int) (int, error) {
|
||||
// certain internal circumstances.
|
||||
func DefaultOrValueHashBits(keyType string, keyBits int, hashBits int) (int, error) {
|
||||
if keyType == "ec" {
|
||||
// To comply with BSI recommendations Section 4.2 and Mozilla root
|
||||
// store policy section 5.1.2, enforce that NIST P-curves use a hash
|
||||
// length corresponding to curve length. Note that ed25519 does not
|
||||
// the "ec" key type.
|
||||
expectedHashBits := expectedNISTPCurveHashBits[keyBits]
|
||||
|
||||
if expectedHashBits != hashBits && hashBits != 0 {
|
||||
return hashBits, fmt.Errorf("unsupported signature hash algorithm length (%d) for NIST P-%d", hashBits, keyBits)
|
||||
} else if hashBits == 0 {
|
||||
hashBits = expectedHashBits
|
||||
}
|
||||
// Enforcement of curve moved to selectSignatureAlgorithmForECDSA. See
|
||||
// note there about why.
|
||||
} else if keyType == "rsa" && hashBits == 0 {
|
||||
// To match previous behavior (and ignoring NIST's recommendations for
|
||||
// hash size to align with RSA key sizes), default to SHA-2-256.
|
||||
hashBits = 256
|
||||
} else if keyType == "ed25519" || keyType == "ed448" {
|
||||
} else if keyType == "ed25519" || keyType == "ed448" || keyType == "any" {
|
||||
// No-op; ed25519 and ed448 internally specify their own hash and
|
||||
// we do not need to select one. Double hashing isn't supported in
|
||||
// certificate signing and we must
|
||||
// certificate signing. Additionally, the any key type can't know
|
||||
// what hash algorithm to use yet, so default to zero.
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@ -642,7 +664,7 @@ func ValidateDefaultOrValueKeyTypeSignatureLength(keyType string, keyBits int, h
|
||||
// Validates that the length of the hash (in bits) used in the signature
|
||||
// calculation is a known, approved value.
|
||||
func ValidateSignatureLength(keyType string, hashBits int) error {
|
||||
if keyType == "ed25519" || keyType == "ed448" {
|
||||
if keyType == "any" || keyType == "ec" || keyType == "ed25519" || keyType == "ed448" {
|
||||
// ed25519 and ed448 include built-in hashing and is not externally
|
||||
// configurable. There are three modes for each of these schemes:
|
||||
//
|
||||
@ -654,6 +676,13 @@ func ValidateSignatureLength(keyType string, hashBits int) error {
|
||||
//
|
||||
// In all cases, we won't have a hash algorithm to validate here, so
|
||||
// return nil.
|
||||
//
|
||||
// Additionally, when KeyType is any, we can't yet validate the
|
||||
// signature algorithm size, so it takes the default zero value.
|
||||
//
|
||||
// When KeyType is ec, we also can't validate this value as we're
|
||||
// forcefully ignoring the users' choice and specifying a value based
|
||||
// on issuer type.
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -842,16 +871,25 @@ func createCertificate(data *CreationBundle, randReader io.Reader, privateKeyGen
|
||||
}
|
||||
|
||||
if data.SigningBundle != nil {
|
||||
if len(data.SigningBundle.Certificate.AuthorityKeyId) > 0 &&
|
||||
!bytes.Equal(data.SigningBundle.Certificate.AuthorityKeyId, data.SigningBundle.Certificate.SubjectKeyId) {
|
||||
if (len(data.SigningBundle.Certificate.AuthorityKeyId) > 0 &&
|
||||
!bytes.Equal(data.SigningBundle.Certificate.AuthorityKeyId, data.SigningBundle.Certificate.SubjectKeyId)) ||
|
||||
data.Params.ForceAppendCaChain {
|
||||
var chain []*CertBlock
|
||||
|
||||
result.CAChain = []*CertBlock{
|
||||
{
|
||||
signingChain := data.SigningBundle.CAChain
|
||||
// Some bundles already include the root included in the chain, so don't include it twice.
|
||||
if len(signingChain) == 0 || !bytes.Equal(signingChain[0].Bytes, data.SigningBundle.CertificateBytes) {
|
||||
chain = append(chain, &CertBlock{
|
||||
Certificate: data.SigningBundle.Certificate,
|
||||
Bytes: data.SigningBundle.CertificateBytes,
|
||||
},
|
||||
})
|
||||
}
|
||||
result.CAChain = append(result.CAChain, data.SigningBundle.CAChain...)
|
||||
|
||||
if len(signingChain) > 0 {
|
||||
chain = append(chain, signingChain...)
|
||||
}
|
||||
|
||||
result.CAChain = chain
|
||||
}
|
||||
}
|
||||
|
||||
@ -859,16 +897,25 @@ func createCertificate(data *CreationBundle, randReader io.Reader, privateKeyGen
|
||||
}
|
||||
|
||||
func selectSignatureAlgorithmForECDSA(pub crypto.PublicKey, signatureBits int) x509.SignatureAlgorithm {
|
||||
// If signature bits are configured, prefer them to the default choice.
|
||||
switch signatureBits {
|
||||
case 256:
|
||||
return x509.ECDSAWithSHA256
|
||||
case 384:
|
||||
return x509.ECDSAWithSHA384
|
||||
case 512:
|
||||
return x509.ECDSAWithSHA512
|
||||
}
|
||||
|
||||
// Previously we preferred the user-specified signature bits for ECDSA
|
||||
// keys. However, this could result in using a longer hash function than
|
||||
// the underlying NIST P-curve will encode (e.g., a SHA-512 hash with a
|
||||
// P-256 key). This isn't ideal: the hash is implicitly truncated
|
||||
// (effectively turning it into SHA-512/256) and we then need to rely
|
||||
// on the prefix security of the hash. Since both NIST and Mozilla guidance
|
||||
// suggest instead using the correct hash function, we should prefer that
|
||||
// over the operator-specified signatureBits.
|
||||
//
|
||||
// Lastly, note that pub above needs to be the _signer's_ public key;
|
||||
// the issue with DefaultOrValueHashBits is that it is called at role
|
||||
// configuration time, which might _precede_ issuer generation. Thus
|
||||
// it only has access to the desired key type and not the actual issuer.
|
||||
// The reference from that function is reproduced below:
|
||||
//
|
||||
// > To comply with BSI recommendations Section 4.2 and Mozilla root
|
||||
// > store policy section 5.1.2, enforce that NIST P-curves use a hash
|
||||
// > length corresponding to curve length. Note that ed25519 does not
|
||||
// > implement the "ec" key type.
|
||||
key, ok := pub.(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
return x509.ECDSAWithSHA256
|
||||
@ -1120,7 +1167,7 @@ func signCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertBun
|
||||
return nil, errutil.InternalError{Err: fmt.Sprintf("unable to parse created certificate: %s", err)}
|
||||
}
|
||||
|
||||
result.CAChain = data.SigningBundle.GetCAChain()
|
||||
result.CAChain = data.SigningBundle.GetFullChain()
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@ -1190,3 +1237,20 @@ func GetPublicKeySize(key crypto.PublicKey) int {
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
// CreateKeyBundle create a KeyBundle struct object which includes a generated key
|
||||
// of keyType with keyBits leveraging the randomness from randReader.
|
||||
func CreateKeyBundle(keyType string, keyBits int, randReader io.Reader) (KeyBundle, error) {
|
||||
return CreateKeyBundleWithKeyGenerator(keyType, keyBits, randReader, generatePrivateKey)
|
||||
}
|
||||
|
||||
// CreateKeyBundleWithKeyGenerator create a KeyBundle struct object which includes
|
||||
// a generated key of keyType with keyBits leveraging the randomness from randReader and
|
||||
// delegates the actual key generation to keyGenerator
|
||||
func CreateKeyBundleWithKeyGenerator(keyType string, keyBits int, randReader io.Reader, keyGenerator KeyGenerator) (KeyBundle, error) {
|
||||
result := KeyBundle{}
|
||||
if err := keyGenerator(keyType, keyBits, &result, randReader); err != nil {
|
||||
return result, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
99
vendor/github.com/hashicorp/vault/sdk/helper/certutil/types.go
generated
vendored
99
vendor/github.com/hashicorp/vault/sdk/helper/certutil/types.go
generated
vendored
@ -78,9 +78,10 @@ type BlockType string
|
||||
|
||||
// Well-known formats
|
||||
const (
|
||||
PKCS1Block BlockType = "RSA PRIVATE KEY"
|
||||
PKCS8Block BlockType = "PRIVATE KEY"
|
||||
ECBlock BlockType = "EC PRIVATE KEY"
|
||||
UnknownBlock BlockType = ""
|
||||
PKCS1Block BlockType = "RSA PRIVATE KEY"
|
||||
PKCS8Block BlockType = "PRIVATE KEY"
|
||||
ECBlock BlockType = "EC PRIVATE KEY"
|
||||
)
|
||||
|
||||
// ParsedPrivateKeyContainer allows common key setting for certs and CSRs
|
||||
@ -137,6 +138,25 @@ type ParsedCSRBundle struct {
|
||||
CSR *x509.CertificateRequest
|
||||
}
|
||||
|
||||
type KeyBundle struct {
|
||||
PrivateKeyType PrivateKeyType
|
||||
PrivateKeyBytes []byte
|
||||
PrivateKey crypto.Signer
|
||||
}
|
||||
|
||||
func GetPrivateKeyTypeFromSigner(signer crypto.Signer) PrivateKeyType {
|
||||
switch signer.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return RSAPrivateKey
|
||||
case *ecdsa.PrivateKey:
|
||||
return ECPrivateKey
|
||||
case ed25519.PrivateKey:
|
||||
return Ed25519PrivateKey
|
||||
default:
|
||||
return UnknownPrivateKey
|
||||
}
|
||||
}
|
||||
|
||||
// ToPEMBundle converts a string-based certificate bundle
|
||||
// to a PEM-based string certificate bundle in trust path
|
||||
// order, leaf certificate first
|
||||
@ -661,9 +681,32 @@ type URLEntries struct {
|
||||
OCSPServers []string `json:"ocsp_servers" structs:"ocsp_servers" mapstructure:"ocsp_servers"`
|
||||
}
|
||||
|
||||
type NotAfterBehavior int
|
||||
|
||||
const (
|
||||
ErrNotAfterBehavior NotAfterBehavior = iota
|
||||
TruncateNotAfterBehavior
|
||||
PermitNotAfterBehavior
|
||||
)
|
||||
|
||||
var notAfterBehaviorNames = map[NotAfterBehavior]string{
|
||||
ErrNotAfterBehavior: "err",
|
||||
TruncateNotAfterBehavior: "truncate",
|
||||
PermitNotAfterBehavior: "permit",
|
||||
}
|
||||
|
||||
func (n NotAfterBehavior) String() string {
|
||||
if name, ok := notAfterBehaviorNames[n]; ok && len(name) > 0 {
|
||||
return name
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
type CAInfoBundle struct {
|
||||
ParsedCertBundle
|
||||
URLs *URLEntries
|
||||
URLs *URLEntries
|
||||
LeafNotAfterBehavior NotAfterBehavior
|
||||
}
|
||||
|
||||
func (b *CAInfoBundle) GetCAChain() []*CertBlock {
|
||||
@ -675,13 +718,7 @@ func (b *CAInfoBundle) GetCAChain() []*CertBlock {
|
||||
(len(b.Certificate.AuthorityKeyId) == 0 &&
|
||||
!bytes.Equal(b.Certificate.RawIssuer, b.Certificate.RawSubject)) {
|
||||
|
||||
chain = append(chain, &CertBlock{
|
||||
Certificate: b.Certificate,
|
||||
Bytes: b.CertificateBytes,
|
||||
})
|
||||
if b.CAChain != nil && len(b.CAChain) > 0 {
|
||||
chain = append(chain, b.CAChain...)
|
||||
}
|
||||
chain = b.GetFullChain()
|
||||
}
|
||||
|
||||
return chain
|
||||
@ -690,10 +727,14 @@ func (b *CAInfoBundle) GetCAChain() []*CertBlock {
|
||||
func (b *CAInfoBundle) GetFullChain() []*CertBlock {
|
||||
var chain []*CertBlock
|
||||
|
||||
chain = append(chain, &CertBlock{
|
||||
Certificate: b.Certificate,
|
||||
Bytes: b.CertificateBytes,
|
||||
})
|
||||
// Some bundles already include the root included in the chain,
|
||||
// so don't include it twice.
|
||||
if len(b.CAChain) == 0 || !bytes.Equal(b.CAChain[0].Bytes, b.CertificateBytes) {
|
||||
chain = append(chain, &CertBlock{
|
||||
Certificate: b.Certificate,
|
||||
Bytes: b.CertificateBytes,
|
||||
})
|
||||
}
|
||||
|
||||
if len(b.CAChain) > 0 {
|
||||
chain = append(chain, b.CAChain...)
|
||||
@ -738,6 +779,7 @@ type CreationParameters struct {
|
||||
PolicyIdentifiers []string
|
||||
BasicConstraintsValidForNonCA bool
|
||||
SignatureBits int
|
||||
ForceAppendCaChain bool
|
||||
|
||||
// Only used when signing a CA cert
|
||||
UseCSRValues bool
|
||||
@ -825,3 +867,30 @@ func AddKeyUsages(data *CreationBundle, certTemplate *x509.Certificate) {
|
||||
certTemplate.ExtKeyUsage = append(certTemplate.ExtKeyUsage, x509.ExtKeyUsageMicrosoftKernelCodeSigning)
|
||||
}
|
||||
}
|
||||
|
||||
// SetParsedPrivateKey sets the private key parameters on the bundle
|
||||
func (p *KeyBundle) SetParsedPrivateKey(privateKey crypto.Signer, privateKeyType PrivateKeyType, privateKeyBytes []byte) {
|
||||
p.PrivateKey = privateKey
|
||||
p.PrivateKeyType = privateKeyType
|
||||
p.PrivateKeyBytes = privateKeyBytes
|
||||
}
|
||||
|
||||
func (p *KeyBundle) ToPrivateKeyPemString() (string, error) {
|
||||
block := pem.Block{}
|
||||
|
||||
if p.PrivateKeyBytes != nil && len(p.PrivateKeyBytes) > 0 {
|
||||
block.Bytes = p.PrivateKeyBytes
|
||||
switch p.PrivateKeyType {
|
||||
case RSAPrivateKey:
|
||||
block.Type = "RSA PRIVATE KEY"
|
||||
case ECPrivateKey:
|
||||
block.Type = "EC PRIVATE KEY"
|
||||
default:
|
||||
block.Type = "PRIVATE KEY"
|
||||
}
|
||||
privateKeyPemString := strings.TrimSpace(string(pem.EncodeToMemory(&block)))
|
||||
return privateKeyPemString, nil
|
||||
}
|
||||
|
||||
return "", errutil.InternalError{Err: "No Private Key Bytes to Wrap"}
|
||||
}
|
||||
|
2
vendor/github.com/hashicorp/vault/sdk/helper/consts/consts.go
generated
vendored
2
vendor/github.com/hashicorp/vault/sdk/helper/consts/consts.go
generated
vendored
@ -32,4 +32,6 @@ const (
|
||||
// ReplicationResolverALPN is the negotiated protocol used for
|
||||
// resolving replicaiton addresses
|
||||
ReplicationResolverALPN = "replication_resolver_v1"
|
||||
|
||||
VaultEnableFilePermissionsCheckEnv = "VAULT_ENABLE_FILE_PERMISSIONS_CHECK"
|
||||
)
|
||||
|
2
vendor/github.com/hashicorp/vault/sdk/helper/pluginutil/multiplexing.pb.go
generated
vendored
2
vendor/github.com/hashicorp/vault/sdk/helper/pluginutil/multiplexing.pb.go
generated
vendored
@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.19.3
|
||||
// protoc v3.19.4
|
||||
// source: sdk/helper/pluginutil/multiplexing.proto
|
||||
|
||||
package pluginutil
|
||||
|
21
vendor/github.com/hashicorp/vault/sdk/logical/auth.go
generated
vendored
21
vendor/github.com/hashicorp/vault/sdk/logical/auth.go
generated
vendored
@ -8,7 +8,8 @@ import (
|
||||
)
|
||||
|
||||
// Auth is the resulting authentication information that is part of
|
||||
// Response for credential backends.
|
||||
// Response for credential backends. It's also attached to Request objects and
|
||||
// defines the authentication used for the request. This value is audit logged.
|
||||
type Auth struct {
|
||||
LeaseOptions
|
||||
|
||||
@ -101,10 +102,28 @@ type Auth struct {
|
||||
// Orphan is set if the token does not have a parent
|
||||
Orphan bool `json:"orphan"`
|
||||
|
||||
// PolicyResults is the set of policies that grant the token access to the
|
||||
// requesting path.
|
||||
PolicyResults *PolicyResults `json:"policy_results"`
|
||||
|
||||
// MFARequirement
|
||||
MFARequirement *MFARequirement `json:"mfa_requirement"`
|
||||
|
||||
// EntityCreated is set to true if an entity is created as part of a login request
|
||||
EntityCreated bool `json:"entity_created"`
|
||||
}
|
||||
|
||||
func (a *Auth) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *a)
|
||||
}
|
||||
|
||||
type PolicyResults struct {
|
||||
Allowed bool `json:"allowed"`
|
||||
GrantingPolicies []PolicyInfo `json:"granting_policies"`
|
||||
}
|
||||
|
||||
type PolicyInfo struct {
|
||||
Name string `json:"name"`
|
||||
NamespaceId string `json:"namespace_id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
2
vendor/github.com/hashicorp/vault/sdk/logical/identity.pb.go
generated
vendored
2
vendor/github.com/hashicorp/vault/sdk/logical/identity.pb.go
generated
vendored
@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.19.3
|
||||
// protoc v3.19.4
|
||||
// source: sdk/logical/identity.proto
|
||||
|
||||
package logical
|
||||
|
8
vendor/github.com/hashicorp/vault/sdk/logical/managed_key.go
generated
vendored
8
vendor/github.com/hashicorp/vault/sdk/logical/managed_key.go
generated
vendored
@ -40,17 +40,17 @@ type (
|
||||
type ManagedKeySystemView interface {
|
||||
// WithManagedKeyByName retrieves an instantiated managed key for consumption by the given function. The
|
||||
// provided key can only be used within the scope of that function call
|
||||
WithManagedKeyByName(ctx context.Context, keyName, mountPoint string, f ManagedKeyConsumer) error
|
||||
WithManagedKeyByName(ctx context.Context, keyName, backendUUID string, f ManagedKeyConsumer) error
|
||||
// WithManagedKeyByUUID retrieves an instantiated managed key for consumption by the given function. The
|
||||
// provided key can only be used within the scope of that function call
|
||||
WithManagedKeyByUUID(ctx context.Context, keyUuid, mountPoint string, f ManagedKeyConsumer) error
|
||||
WithManagedKeyByUUID(ctx context.Context, keyUuid, backendUUID string, f ManagedKeyConsumer) error
|
||||
|
||||
// WithManagedSigningKeyByName retrieves an instantiated managed signing key for consumption by the given function,
|
||||
// with the same semantics as WithManagedKeyByName
|
||||
WithManagedSigningKeyByName(ctx context.Context, keyName, mountPoint string, f ManagedSigningKeyConsumer) error
|
||||
WithManagedSigningKeyByName(ctx context.Context, keyName, backendUUID string, f ManagedSigningKeyConsumer) error
|
||||
// WithManagedSigningKeyByUUID retrieves an instantiated managed signing key for consumption by the given function,
|
||||
// with the same semantics as WithManagedKeyByUUID
|
||||
WithManagedSigningKeyByUUID(ctx context.Context, keyUuid, mountPoint string, f ManagedSigningKeyConsumer) error
|
||||
WithManagedSigningKeyByUUID(ctx context.Context, keyUuid, backendUUID string, f ManagedSigningKeyConsumer) error
|
||||
}
|
||||
|
||||
type ManagedAsymmetricKey interface {
|
||||
|
41
vendor/github.com/hashicorp/vault/sdk/logical/plugin.pb.go
generated
vendored
41
vendor/github.com/hashicorp/vault/sdk/logical/plugin.pb.go
generated
vendored
@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.19.3
|
||||
// protoc v3.19.4
|
||||
// source: sdk/logical/plugin.proto
|
||||
|
||||
package logical
|
||||
@ -27,6 +27,10 @@ type PluginEnvironment struct {
|
||||
|
||||
// VaultVersion is the version of the Vault server
|
||||
VaultVersion string `protobuf:"bytes,1,opt,name=vault_version,json=vaultVersion,proto3" json:"vault_version,omitempty"`
|
||||
// VaultVersionPrerelease is the prerelease information of the Vault server
|
||||
VaultVersionPrerelease string `protobuf:"bytes,2,opt,name=vault_version_prerelease,json=vaultVersionPrerelease,proto3" json:"vault_version_prerelease,omitempty"`
|
||||
// VaultVersionMetadata is the version metadata of the Vault server
|
||||
VaultVersionMetadata string `protobuf:"bytes,3,opt,name=vault_version_metadata,json=vaultVersionMetadata,proto3" json:"vault_version_metadata,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PluginEnvironment) Reset() {
|
||||
@ -68,18 +72,39 @@ func (x *PluginEnvironment) GetVaultVersion() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PluginEnvironment) GetVaultVersionPrerelease() string {
|
||||
if x != nil {
|
||||
return x.VaultVersionPrerelease
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PluginEnvironment) GetVaultVersionMetadata() string {
|
||||
if x != nil {
|
||||
return x.VaultVersionMetadata
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_sdk_logical_plugin_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_sdk_logical_plugin_proto_rawDesc = []byte{
|
||||
0x0a, 0x18, 0x73, 0x64, 0x6b, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x2f, 0x70, 0x6c,
|
||||
0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6c, 0x6f, 0x67, 0x69,
|
||||
0x63, 0x61, 0x6c, 0x22, 0x38, 0x0a, 0x11, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x45, 0x6e, 0x76,
|
||||
0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x75, 0x6c,
|
||||
0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x28, 0x5a,
|
||||
0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f,
|
||||
0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x63, 0x61, 0x6c, 0x22, 0xa8, 0x01, 0x0a, 0x11, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x45, 0x6e,
|
||||
0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x75,
|
||||
0x6c, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38,
|
||||
0x0a, 0x18, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
|
||||
0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x16, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72,
|
||||
0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x76, 0x61, 0x75, 0x6c,
|
||||
0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x56,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x28,
|
||||
0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b,
|
||||
0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
6
vendor/github.com/hashicorp/vault/sdk/logical/plugin.proto
generated
vendored
6
vendor/github.com/hashicorp/vault/sdk/logical/plugin.proto
generated
vendored
@ -7,4 +7,10 @@ package logical;
|
||||
message PluginEnvironment {
|
||||
// VaultVersion is the version of the Vault server
|
||||
string vault_version = 1;
|
||||
|
||||
// VaultVersionPrerelease is the prerelease information of the Vault server
|
||||
string vault_version_prerelease = 2;
|
||||
|
||||
// VaultVersionMetadata is the version metadata of the Vault server
|
||||
string vault_version_metadata = 3;
|
||||
}
|
||||
|
2
vendor/github.com/hashicorp/vault/sdk/logical/response_util.go
generated
vendored
2
vendor/github.com/hashicorp/vault/sdk/logical/response_util.go
generated
vendored
@ -120,6 +120,8 @@ func RespondErrorCommon(req *Request, resp *Response, err error) (int, error) {
|
||||
statusCode = http.StatusPreconditionFailed
|
||||
case errwrap.Contains(err, ErrPathFunctionalityRemoved.Error()):
|
||||
statusCode = http.StatusNotFound
|
||||
case errwrap.Contains(err, ErrRelativePath.Error()):
|
||||
statusCode = http.StatusBadRequest
|
||||
}
|
||||
}
|
||||
|
||||
|
6
vendor/github.com/hashicorp/vault/sdk/version/version.go
generated
vendored
6
vendor/github.com/hashicorp/vault/sdk/version/version.go
generated
vendored
@ -11,6 +11,7 @@ type VersionInfo struct {
|
||||
Version string `json:"version,omitempty"`
|
||||
VersionPrerelease string `json:"version_prerelease,omitempty"`
|
||||
VersionMetadata string `json:"version_metadata,omitempty"`
|
||||
BuildDate string `json:"build_date,omitempty"`
|
||||
}
|
||||
|
||||
func GetVersion() *VersionInfo {
|
||||
@ -29,6 +30,7 @@ func GetVersion() *VersionInfo {
|
||||
Version: ver,
|
||||
VersionPrerelease: rel,
|
||||
VersionMetadata: md,
|
||||
BuildDate: BuildDate,
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,5 +72,9 @@ func (c *VersionInfo) FullVersionNumber(rev bool) string {
|
||||
fmt.Fprintf(&versionString, " (%s)", c.Revision)
|
||||
}
|
||||
|
||||
if c.BuildDate != "" {
|
||||
fmt.Fprintf(&versionString, ", built %s", c.BuildDate)
|
||||
}
|
||||
|
||||
return versionString.String()
|
||||
}
|
||||
|
5
vendor/github.com/hashicorp/vault/sdk/version/version_base.go
generated
vendored
5
vendor/github.com/hashicorp/vault/sdk/version/version_base.go
generated
vendored
@ -5,10 +5,13 @@ var (
|
||||
GitCommit string
|
||||
GitDescribe string
|
||||
|
||||
// The compilation date. This will be filled in by the compiler.
|
||||
BuildDate string
|
||||
|
||||
// Whether cgo is enabled or not; set at build time
|
||||
CgoEnabled bool
|
||||
|
||||
Version = "1.10.0"
|
||||
Version = "1.11.0"
|
||||
VersionPrerelease = "dev1"
|
||||
VersionMetadata = ""
|
||||
)
|
||||
|
17
vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
generated
vendored
17
vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
generated
vendored
@ -1,3 +1,20 @@
|
||||
## 1.5.0
|
||||
|
||||
* New option `IgnoreUntaggedFields` to ignore decoding to any fields
|
||||
without `mapstructure` (or the configured tag name) set [GH-277]
|
||||
* New option `ErrorUnset` which makes it an error if any fields
|
||||
in a target struct are not set by the decoding process. [GH-225]
|
||||
* New function `OrComposeDecodeHookFunc` to help compose decode hooks. [GH-240]
|
||||
* Decoding to slice from array no longer crashes [GH-265]
|
||||
* Decode nested struct pointers to map [GH-271]
|
||||
* Fix issue where `,squash` was ignored if `Squash` option was set. [GH-280]
|
||||
* Fix issue where fields with `,omitempty` would sometimes decode
|
||||
into a map with an empty string key [GH-281]
|
||||
|
||||
## 1.4.3
|
||||
|
||||
* Fix cases where `json.Number` didn't decode properly [GH-261]
|
||||
|
||||
## 1.4.2
|
||||
|
||||
* Custom name matchers to support any sort of casing, formatting, etc. for
|
||||
|
22
vendor/github.com/mitchellh/mapstructure/decode_hooks.go
generated
vendored
22
vendor/github.com/mitchellh/mapstructure/decode_hooks.go
generated
vendored
@ -77,6 +77,28 @@ func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// OrComposeDecodeHookFunc executes all input hook functions until one of them returns no error. In that case its value is returned.
|
||||
// If all hooks return an error, OrComposeDecodeHookFunc returns an error concatenating all error messages.
|
||||
func OrComposeDecodeHookFunc(ff ...DecodeHookFunc) DecodeHookFunc {
|
||||
return func(a, b reflect.Value) (interface{}, error) {
|
||||
var allErrs string
|
||||
var out interface{}
|
||||
var err error
|
||||
|
||||
for _, f := range ff {
|
||||
out, err = DecodeHookExec(f, a, b)
|
||||
if err != nil {
|
||||
allErrs += err.Error() + "\n"
|
||||
continue
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
return nil, errors.New(allErrs)
|
||||
}
|
||||
}
|
||||
|
||||
// StringToSliceHookFunc returns a DecodeHookFunc that converts
|
||||
// string to []string by splitting on the given sep.
|
||||
func StringToSliceHookFunc(sep string) DecodeHookFunc {
|
||||
|
91
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
91
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
@ -122,7 +122,7 @@
|
||||
// field value is zero and a numeric type, the field is empty, and it won't
|
||||
// be encoded into the destination type.
|
||||
//
|
||||
// type Source {
|
||||
// type Source struct {
|
||||
// Age int `mapstructure:",omitempty"`
|
||||
// }
|
||||
//
|
||||
@ -215,6 +215,12 @@ type DecoderConfig struct {
|
||||
// (extra keys).
|
||||
ErrorUnused bool
|
||||
|
||||
// If ErrorUnset is true, then it is an error for there to exist
|
||||
// fields in the result that were not set in the decoding process
|
||||
// (extra fields). This only applies to decoding to a struct. This
|
||||
// will affect all nested structs as well.
|
||||
ErrorUnset bool
|
||||
|
||||
// ZeroFields, if set to true, will zero fields before writing them.
|
||||
// For example, a map will be emptied before decoded values are put in
|
||||
// it. If this is false, a map will be merged.
|
||||
@ -259,6 +265,10 @@ type DecoderConfig struct {
|
||||
// defaults to "mapstructure"
|
||||
TagName string
|
||||
|
||||
// IgnoreUntaggedFields ignores all struct fields without explicit
|
||||
// TagName, comparable to `mapstructure:"-"` as default behaviour.
|
||||
IgnoreUntaggedFields bool
|
||||
|
||||
// MatchName is the function used to match the map key to the struct
|
||||
// field name or tag. Defaults to `strings.EqualFold`. This can be used
|
||||
// to implement case-sensitive tag values, support snake casing, etc.
|
||||
@ -284,6 +294,11 @@ type Metadata struct {
|
||||
// Unused is a slice of keys that were found in the raw value but
|
||||
// weren't decoded since there was no matching field in the result interface
|
||||
Unused []string
|
||||
|
||||
// Unset is a slice of field names that were found in the result interface
|
||||
// but weren't set in the decoding process since there was no matching value
|
||||
// in the input
|
||||
Unset []string
|
||||
}
|
||||
|
||||
// Decode takes an input structure and uses reflection to translate it to
|
||||
@ -375,6 +390,10 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) {
|
||||
if config.Metadata.Unused == nil {
|
||||
config.Metadata.Unused = make([]string, 0)
|
||||
}
|
||||
|
||||
if config.Metadata.Unset == nil {
|
||||
config.Metadata.Unset = make([]string, 0)
|
||||
}
|
||||
}
|
||||
|
||||
if config.TagName == "" {
|
||||
@ -684,16 +703,12 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e
|
||||
}
|
||||
case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
|
||||
jn := data.(json.Number)
|
||||
i, err := jn.Int64()
|
||||
i, err := strconv.ParseUint(string(jn), 0, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"error decoding json.Number into %s: %s", name, err)
|
||||
}
|
||||
if i < 0 && !d.config.WeaklyTypedInput {
|
||||
return fmt.Errorf("cannot parse '%s', %d overflows uint",
|
||||
name, i)
|
||||
}
|
||||
val.SetUint(uint64(i))
|
||||
val.SetUint(i)
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
|
||||
@ -910,9 +925,15 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||
tagValue := f.Tag.Get(d.config.TagName)
|
||||
keyName := f.Name
|
||||
|
||||
if tagValue == "" && d.config.IgnoreUntaggedFields {
|
||||
continue
|
||||
}
|
||||
|
||||
// If Squash is set in the config, we squash the field down.
|
||||
squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous
|
||||
|
||||
v = dereferencePtrToStructIfNeeded(v, d.config.TagName)
|
||||
|
||||
// Determine the name of the key in the map
|
||||
if index := strings.Index(tagValue, ","); index != -1 {
|
||||
if tagValue[:index] == "-" {
|
||||
@ -924,7 +945,7 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||
}
|
||||
|
||||
// If "squash" is specified in the tag, we squash the field down.
|
||||
squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1
|
||||
squash = squash || strings.Index(tagValue[index+1:], "squash") != -1
|
||||
if squash {
|
||||
// When squashing, the embedded type can be a pointer to a struct.
|
||||
if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
|
||||
@ -936,7 +957,9 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
|
||||
return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
|
||||
}
|
||||
}
|
||||
keyName = tagValue[:index]
|
||||
if keyNameTagValue := tagValue[:index]; keyNameTagValue != "" {
|
||||
keyName = keyNameTagValue
|
||||
}
|
||||
} else if len(tagValue) > 0 {
|
||||
if tagValue == "-" {
|
||||
continue
|
||||
@ -1092,7 +1115,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
|
||||
}
|
||||
|
||||
// If the input value is nil, then don't allocate since empty != nil
|
||||
if dataVal.IsNil() {
|
||||
if dataValKind != reflect.Array && dataVal.IsNil() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1254,6 +1277,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
dataValKeysUnused[dataValKey.Interface()] = struct{}{}
|
||||
}
|
||||
|
||||
targetValKeysUnused := make(map[interface{}]struct{})
|
||||
errors := make([]string, 0)
|
||||
|
||||
// This slice will keep track of all the structs we'll be decoding.
|
||||
@ -1358,7 +1382,8 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
|
||||
if !rawMapVal.IsValid() {
|
||||
// There was no matching key in the map for the value in
|
||||
// the struct. Just ignore.
|
||||
// the struct. Remember it for potential errors and metadata.
|
||||
targetValKeysUnused[fieldName] = struct{}{}
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -1418,6 +1443,17 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
errors = appendErrors(errors, err)
|
||||
}
|
||||
|
||||
if d.config.ErrorUnset && len(targetValKeysUnused) > 0 {
|
||||
keys := make([]string, 0, len(targetValKeysUnused))
|
||||
for rawKey := range targetValKeysUnused {
|
||||
keys = append(keys, rawKey.(string))
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
err := fmt.Errorf("'%s' has unset fields: %s", name, strings.Join(keys, ", "))
|
||||
errors = appendErrors(errors, err)
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
return &Error{errors}
|
||||
}
|
||||
@ -1432,6 +1468,14 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
|
||||
|
||||
d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
|
||||
}
|
||||
for rawKey := range targetValKeysUnused {
|
||||
key := rawKey.(string)
|
||||
if name != "" {
|
||||
key = name + "." + key
|
||||
}
|
||||
|
||||
d.config.Metadata.Unset = append(d.config.Metadata.Unset, key)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -1469,3 +1513,28 @@ func getKind(val reflect.Value) reflect.Kind {
|
||||
return kind
|
||||
}
|
||||
}
|
||||
|
||||
func isStructTypeConvertibleToMap(typ reflect.Type, checkMapstructureTags bool, tagName string) bool {
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
f := typ.Field(i)
|
||||
if f.PkgPath == "" && !checkMapstructureTags { // check for unexported fields
|
||||
return true
|
||||
}
|
||||
if checkMapstructureTags && f.Tag.Get(tagName) != "" { // check for mapstructure tags inside
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func dereferencePtrToStructIfNeeded(v reflect.Value, tagName string) reflect.Value {
|
||||
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
|
||||
return v
|
||||
}
|
||||
deref := v.Elem()
|
||||
derefT := deref.Type()
|
||||
if isStructTypeConvertibleToMap(derefT, true, tagName) {
|
||||
return deref
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
@ -271,10 +271,10 @@ github.com/hashicorp/go-rootcerts
|
||||
# github.com/hashicorp/go-secure-stdlib/mlock v0.1.1
|
||||
## explicit; go 1.16
|
||||
github.com/hashicorp/go-secure-stdlib/mlock
|
||||
# github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1
|
||||
# github.com/hashicorp/go-secure-stdlib/parseutil v0.1.5
|
||||
## explicit; go 1.16
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil
|
||||
# github.com/hashicorp/go-secure-stdlib/strutil v0.1.1
|
||||
# github.com/hashicorp/go-secure-stdlib/strutil v0.1.2
|
||||
## explicit; go 1.16
|
||||
github.com/hashicorp/go-secure-stdlib/strutil
|
||||
# github.com/hashicorp/go-sockaddr v1.0.2
|
||||
@ -305,10 +305,10 @@ github.com/hashicorp/hcl/json/token
|
||||
## explicit; go 1.13
|
||||
github.com/hashicorp/vault/command/agent/auth
|
||||
github.com/hashicorp/vault/command/agent/auth/kubernetes
|
||||
# github.com/hashicorp/vault/api v1.5.0
|
||||
# github.com/hashicorp/vault/api v1.6.0
|
||||
## explicit; go 1.13
|
||||
github.com/hashicorp/vault/api
|
||||
# github.com/hashicorp/vault/sdk v0.4.1
|
||||
# github.com/hashicorp/vault/sdk v0.5.0
|
||||
## explicit; go 1.16
|
||||
github.com/hashicorp/vault/sdk/helper/certutil
|
||||
github.com/hashicorp/vault/sdk/helper/compressutil
|
||||
@ -386,7 +386,7 @@ github.com/mitchellh/go-homedir
|
||||
# github.com/mitchellh/go-testing-interface v1.0.0
|
||||
## explicit
|
||||
github.com/mitchellh/go-testing-interface
|
||||
# github.com/mitchellh/mapstructure v1.4.2
|
||||
# github.com/mitchellh/mapstructure v1.5.0
|
||||
## explicit; go 1.14
|
||||
github.com/mitchellh/mapstructure
|
||||
# github.com/mitchellh/reflectwalk v1.0.1
|
||||
|
Loading…
Reference in New Issue
Block a user