vault.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. /*
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License.
  11. */
  12. package vault
  13. import (
  14. "context"
  15. "crypto/tls"
  16. "crypto/x509"
  17. "errors"
  18. "fmt"
  19. "io/ioutil"
  20. "net/http"
  21. "os"
  22. "strings"
  23. "github.com/go-logr/logr"
  24. vault "github.com/hashicorp/vault/api"
  25. corev1 "k8s.io/api/core/v1"
  26. "k8s.io/apimachinery/pkg/types"
  27. ctrl "sigs.k8s.io/controller-runtime"
  28. kclient "sigs.k8s.io/controller-runtime/pkg/client"
  29. esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
  30. esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
  31. "github.com/external-secrets/external-secrets/pkg/provider"
  32. "github.com/external-secrets/external-secrets/pkg/provider/schema"
  33. )
  34. var (
  35. _ provider.Provider = &connector{}
  36. _ provider.SecretsClient = &client{}
  37. )
  38. const (
  39. serviceAccTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
  40. errVaultStore = "received invalid Vault SecretStore resource: %w"
  41. errVaultClient = "cannot setup new vault client: %w"
  42. errVaultCert = "cannot set Vault CA certificate: %w"
  43. errReadSecret = "cannot read secret data from Vault: %w"
  44. errAuthFormat = "cannot initialize Vault client: no valid auth method specified: %w"
  45. errDataField = "failed to find data field"
  46. errJSONUnmarshall = "failed to unmarshall JSON"
  47. errSecretFormat = "secret data not in expected format"
  48. errVaultToken = "cannot parse Vault authentication token: %w"
  49. errVaultReqParams = "cannot set Vault request parameters: %w"
  50. errVaultRequest = "error from Vault request: %w"
  51. errVaultResponse = "cannot parse Vault response: %w"
  52. errServiceAccount = "cannot read Kubernetes service account token from file system: %w"
  53. errGetKubeSA = "cannot get Kubernetes service account %q: %w"
  54. errGetKubeSASecrets = "cannot find secrets bound to service account: %q"
  55. errGetKubeSANoToken = "cannot find token in secrets bound to service account: %q"
  56. errGetKubeSecret = "cannot get Kubernetes secret %q: %w"
  57. errSecretKeyFmt = "cannot find secret data for key: %q"
  58. errConfigMapFmt = "cannot find config map data for key: %q"
  59. errClientTLSAuth = "error from Client TLS Auth: %q"
  60. errVaultRevokeToken = "error while revoking token: %w"
  61. errUnknownCAProvider = "unknown caProvider type given"
  62. errCANamespace = "cannot read secret for CAProvider due to missing namespace on kind ClusterSecretStore"
  63. )
  64. type Client interface {
  65. NewRequest(method, requestPath string) *vault.Request
  66. RawRequestWithContext(ctx context.Context, r *vault.Request) (*vault.Response, error)
  67. SetToken(v string)
  68. Token() string
  69. ClearToken()
  70. SetNamespace(namespace string)
  71. }
  72. type client struct {
  73. kube kclient.Client
  74. store *esv1alpha1.VaultProvider
  75. log logr.Logger
  76. client Client
  77. namespace string
  78. storeKind string
  79. }
  80. func init() {
  81. schema.Register(&connector{
  82. newVaultClient: newVaultClient,
  83. }, &esv1alpha1.SecretStoreProvider{
  84. Vault: &esv1alpha1.VaultProvider{},
  85. })
  86. }
  87. func newVaultClient(c *vault.Config) (Client, error) {
  88. return vault.NewClient(c)
  89. }
  90. type connector struct {
  91. newVaultClient func(c *vault.Config) (Client, error)
  92. }
  93. func (c *connector) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube kclient.Client, namespace string) (provider.SecretsClient, error) {
  94. storeSpec := store.GetSpec()
  95. if storeSpec == nil || storeSpec.Provider == nil || storeSpec.Provider.Vault == nil {
  96. return nil, errors.New(errVaultStore)
  97. }
  98. vaultSpec := storeSpec.Provider.Vault
  99. vStore := &client{
  100. kube: kube,
  101. store: vaultSpec,
  102. log: ctrl.Log.WithName("provider").WithName("vault"),
  103. namespace: namespace,
  104. storeKind: store.GetObjectKind().GroupVersionKind().Kind,
  105. }
  106. cfg, err := vStore.newConfig()
  107. if err != nil {
  108. return nil, err
  109. }
  110. client, err := c.newVaultClient(cfg)
  111. if err != nil {
  112. return nil, fmt.Errorf(errVaultClient, err)
  113. }
  114. if vaultSpec.Namespace != nil {
  115. client.SetNamespace(*vaultSpec.Namespace)
  116. }
  117. if err := vStore.setAuth(ctx, client, cfg); err != nil {
  118. return nil, err
  119. }
  120. vStore.client = client
  121. return vStore, nil
  122. }
  123. func (v *client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
  124. data, err := v.readSecret(ctx, ref.Key, ref.Version)
  125. if err != nil {
  126. return nil, err
  127. }
  128. value, exists := data[ref.Property]
  129. if !exists {
  130. return nil, fmt.Errorf(errSecretKeyFmt, ref.Property)
  131. }
  132. return value, nil
  133. }
  134. func (v *client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
  135. return v.readSecret(ctx, ref.Key, ref.Version)
  136. }
  137. func (v *client) Close(ctx context.Context) error {
  138. // Revoke the token if we have one set and it wasn't sourced from a TokenSecretRef
  139. if v.client.Token() != "" && v.store.Auth.TokenSecretRef == nil {
  140. req := v.client.NewRequest(http.MethodPost, "/v1/auth/token/revoke-self")
  141. _, err := v.client.RawRequestWithContext(ctx, req)
  142. if err != nil {
  143. return fmt.Errorf(errVaultRevokeToken, err)
  144. }
  145. v.client.ClearToken()
  146. }
  147. return nil
  148. }
  149. func (v *client) readSecret(ctx context.Context, path, version string) (map[string][]byte, error) {
  150. kvPath := v.store.Path
  151. if v.store.Version == esv1alpha1.VaultKVStoreV2 {
  152. if !strings.HasSuffix(kvPath, "/data") {
  153. kvPath = fmt.Sprintf("%s/data", kvPath)
  154. }
  155. }
  156. // path formated according to vault docs for v1 and v2 API
  157. // v1: https://www.vaultproject.io/api-docs/secret/kv/kv-v1#read-secret
  158. // v2: https://www.vaultproject.io/api/secret/kv/kv-v2#read-secret-version
  159. req := v.client.NewRequest(http.MethodGet, fmt.Sprintf("/v1/%s/%s", kvPath, path))
  160. if version != "" {
  161. req.Params.Set("version", version)
  162. }
  163. resp, err := v.client.RawRequestWithContext(ctx, req)
  164. if err != nil {
  165. return nil, fmt.Errorf(errReadSecret, err)
  166. }
  167. vaultSecret, err := vault.ParseSecret(resp.Body)
  168. if err != nil {
  169. return nil, err
  170. }
  171. secretData := vaultSecret.Data
  172. if v.store.Version == esv1alpha1.VaultKVStoreV2 {
  173. // Vault KV2 has data embedded within sub-field
  174. // reference - https://www.vaultproject.io/api/secret/kv/kv-v2#read-secret-version
  175. dataInt, ok := vaultSecret.Data["data"]
  176. if !ok {
  177. return nil, errors.New(errDataField)
  178. }
  179. secretData, ok = dataInt.(map[string]interface{})
  180. if !ok {
  181. return nil, errors.New(errJSONUnmarshall)
  182. }
  183. }
  184. byteMap := make(map[string][]byte, len(secretData))
  185. for k, v := range secretData {
  186. switch t := v.(type) {
  187. case string:
  188. byteMap[k] = []byte(t)
  189. case []byte:
  190. byteMap[k] = t
  191. case nil:
  192. byteMap[k] = []byte(nil)
  193. default:
  194. return nil, errors.New(errSecretFormat)
  195. }
  196. }
  197. return byteMap, nil
  198. }
  199. func (v *client) newConfig() (*vault.Config, error) {
  200. cfg := vault.DefaultConfig()
  201. cfg.Address = v.store.Server
  202. if len(v.store.CABundle) == 0 && v.store.CAProvider == nil {
  203. return cfg, nil
  204. }
  205. caCertPool := x509.NewCertPool()
  206. if len(v.store.CABundle) > 0 {
  207. ok := caCertPool.AppendCertsFromPEM(v.store.CABundle)
  208. if !ok {
  209. return nil, errors.New(errVaultCert)
  210. }
  211. }
  212. if v.store.CAProvider != nil && v.storeKind == esv1alpha1.ClusterSecretStoreKind && v.store.CAProvider.Namespace == nil {
  213. return nil, errors.New(errCANamespace)
  214. }
  215. if v.store.CAProvider != nil {
  216. var cert []byte
  217. var err error
  218. switch v.store.CAProvider.Type {
  219. case esv1alpha1.CAProviderTypeSecret:
  220. cert, err = getCertFromSecret(v)
  221. case esv1alpha1.CAProviderTypeConfigMap:
  222. cert, err = getCertFromConfigMap(v)
  223. default:
  224. return nil, errors.New(errUnknownCAProvider)
  225. }
  226. if err != nil {
  227. return nil, err
  228. }
  229. ok := caCertPool.AppendCertsFromPEM(cert)
  230. if !ok {
  231. return nil, errors.New(errVaultCert)
  232. }
  233. }
  234. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  235. transport.TLSClientConfig.RootCAs = caCertPool
  236. }
  237. return cfg, nil
  238. }
  239. func getCertFromSecret(v *client) ([]byte, error) {
  240. secretRef := esmeta.SecretKeySelector{
  241. Name: v.store.CAProvider.Name,
  242. Key: v.store.CAProvider.Key,
  243. }
  244. if v.store.CAProvider.Namespace != nil {
  245. secretRef.Namespace = v.store.CAProvider.Namespace
  246. }
  247. ctx := context.Background()
  248. res, err := v.secretKeyRef(ctx, &secretRef)
  249. if err != nil {
  250. return nil, fmt.Errorf(errVaultCert, err)
  251. }
  252. return []byte(res), nil
  253. }
  254. func getCertFromConfigMap(v *client) ([]byte, error) {
  255. objKey := types.NamespacedName{
  256. Name: v.store.CAProvider.Name,
  257. }
  258. if v.store.CAProvider.Namespace != nil {
  259. objKey.Namespace = *v.store.CAProvider.Namespace
  260. }
  261. configMapRef := &corev1.ConfigMap{}
  262. ctx := context.Background()
  263. err := v.kube.Get(ctx, objKey, configMapRef)
  264. if err != nil {
  265. return nil, fmt.Errorf(errVaultCert, err)
  266. }
  267. val, ok := configMapRef.Data[v.store.CAProvider.Key]
  268. if !ok {
  269. return nil, fmt.Errorf(errConfigMapFmt, v.store.CAProvider.Key)
  270. }
  271. return []byte(val), nil
  272. }
  273. func (v *client) setAuth(ctx context.Context, client Client, cfg *vault.Config) error {
  274. tokenExists, err := setSecretKeyToken(ctx, v, client)
  275. if tokenExists {
  276. return err
  277. }
  278. tokenExists, err = setAppRoleToken(ctx, v, client)
  279. if tokenExists {
  280. return err
  281. }
  282. tokenExists, err = setKubernetesAuthToken(ctx, v, client)
  283. if tokenExists {
  284. return err
  285. }
  286. tokenExists, err = setLdapAuthToken(ctx, v, client)
  287. if tokenExists {
  288. return err
  289. }
  290. tokenExists, err = setJwtAuthToken(ctx, v, client)
  291. if tokenExists {
  292. return err
  293. }
  294. tokenExists, err = setCertAuthToken(ctx, v, client, cfg)
  295. if tokenExists {
  296. return err
  297. }
  298. return errors.New(errAuthFormat)
  299. }
  300. func setAppRoleToken(ctx context.Context, v *client, client Client) (bool, error) {
  301. tokenRef := v.store.Auth.TokenSecretRef
  302. if tokenRef != nil {
  303. token, err := v.secretKeyRef(ctx, tokenRef)
  304. if err != nil {
  305. return true, err
  306. }
  307. client.SetToken(token)
  308. return true, nil
  309. }
  310. return false, nil
  311. }
  312. func setSecretKeyToken(ctx context.Context, v *client, client Client) (bool, error) {
  313. appRole := v.store.Auth.AppRole
  314. if appRole != nil {
  315. token, err := v.requestTokenWithAppRoleRef(ctx, client, appRole)
  316. if err != nil {
  317. return true, err
  318. }
  319. client.SetToken(token)
  320. return true, nil
  321. }
  322. return false, nil
  323. }
  324. func setKubernetesAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  325. kubernetesAuth := v.store.Auth.Kubernetes
  326. if kubernetesAuth != nil {
  327. token, err := v.requestTokenWithKubernetesAuth(ctx, client, kubernetesAuth)
  328. if err != nil {
  329. return true, err
  330. }
  331. client.SetToken(token)
  332. return true, nil
  333. }
  334. return false, nil
  335. }
  336. func setLdapAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  337. ldapAuth := v.store.Auth.Ldap
  338. if ldapAuth != nil {
  339. token, err := v.requestTokenWithLdapAuth(ctx, client, ldapAuth)
  340. if err != nil {
  341. return true, err
  342. }
  343. client.SetToken(token)
  344. return true, nil
  345. }
  346. return false, nil
  347. }
  348. func setJwtAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  349. jwtAuth := v.store.Auth.Jwt
  350. if jwtAuth != nil {
  351. token, err := v.requestTokenWithJwtAuth(ctx, client, jwtAuth)
  352. if err != nil {
  353. return true, err
  354. }
  355. client.SetToken(token)
  356. return true, nil
  357. }
  358. return false, nil
  359. }
  360. func setCertAuthToken(ctx context.Context, v *client, client Client, cfg *vault.Config) (bool, error) {
  361. certAuth := v.store.Auth.Cert
  362. if certAuth != nil {
  363. token, err := v.requestTokenWithCertAuth(ctx, client, certAuth, cfg)
  364. if err != nil {
  365. return true, err
  366. }
  367. client.SetToken(token)
  368. return true, nil
  369. }
  370. return false, nil
  371. }
  372. func (v *client) secretKeyRefForServiceAccount(ctx context.Context, serviceAccountRef *esmeta.ServiceAccountSelector) (string, error) {
  373. serviceAccount := &corev1.ServiceAccount{}
  374. ref := types.NamespacedName{
  375. Namespace: v.namespace,
  376. Name: serviceAccountRef.Name,
  377. }
  378. if (v.storeKind == esv1alpha1.ClusterSecretStoreKind) &&
  379. (serviceAccountRef.Namespace != nil) {
  380. ref.Namespace = *serviceAccountRef.Namespace
  381. }
  382. err := v.kube.Get(ctx, ref, serviceAccount)
  383. if err != nil {
  384. return "", fmt.Errorf(errGetKubeSA, ref.Name, err)
  385. }
  386. if len(serviceAccount.Secrets) == 0 {
  387. return "", fmt.Errorf(errGetKubeSASecrets, ref.Name)
  388. }
  389. for _, tokenRef := range serviceAccount.Secrets {
  390. retval, err := v.secretKeyRef(ctx, &esmeta.SecretKeySelector{
  391. Name: tokenRef.Name,
  392. Namespace: &ref.Namespace,
  393. Key: "token",
  394. })
  395. if err != nil {
  396. continue
  397. }
  398. return retval, nil
  399. }
  400. return "", fmt.Errorf(errGetKubeSANoToken, ref.Name)
  401. }
  402. func (v *client) secretKeyRef(ctx context.Context, secretRef *esmeta.SecretKeySelector) (string, error) {
  403. secret := &corev1.Secret{}
  404. ref := types.NamespacedName{
  405. Namespace: v.namespace,
  406. Name: secretRef.Name,
  407. }
  408. if (v.storeKind == esv1alpha1.ClusterSecretStoreKind) &&
  409. (secretRef.Namespace != nil) {
  410. ref.Namespace = *secretRef.Namespace
  411. }
  412. err := v.kube.Get(ctx, ref, secret)
  413. if err != nil {
  414. return "", fmt.Errorf(errGetKubeSecret, ref.Name, err)
  415. }
  416. keyBytes, ok := secret.Data[secretRef.Key]
  417. if !ok {
  418. return "", fmt.Errorf(errSecretKeyFmt, secretRef.Key)
  419. }
  420. value := string(keyBytes)
  421. valueStr := strings.TrimSpace(value)
  422. return valueStr, nil
  423. }
  424. // appRoleParameters creates the required body for Vault AppRole Auth.
  425. // Reference - https://www.vaultproject.io/api-docs/auth/approle#login-with-approle
  426. func appRoleParameters(role, secret string) map[string]string {
  427. return map[string]string{
  428. "role_id": role,
  429. "secret_id": secret,
  430. }
  431. }
  432. func (v *client) requestTokenWithAppRoleRef(ctx context.Context, client Client, appRole *esv1alpha1.VaultAppRole) (string, error) {
  433. roleID := strings.TrimSpace(appRole.RoleID)
  434. secretID, err := v.secretKeyRef(ctx, &appRole.SecretRef)
  435. if err != nil {
  436. return "", err
  437. }
  438. parameters := appRoleParameters(roleID, secretID)
  439. url := strings.Join([]string{"/v1", "auth", appRole.Path, "login"}, "/")
  440. request := client.NewRequest("POST", url)
  441. err = request.SetJSONBody(parameters)
  442. if err != nil {
  443. return "", fmt.Errorf(errVaultReqParams, err)
  444. }
  445. resp, err := client.RawRequestWithContext(ctx, request)
  446. if err != nil {
  447. return "", fmt.Errorf(errVaultRequest, err)
  448. }
  449. defer resp.Body.Close()
  450. vaultResult := vault.Secret{}
  451. if err = resp.DecodeJSON(&vaultResult); err != nil {
  452. return "", fmt.Errorf(errVaultResponse, err)
  453. }
  454. token, err := vaultResult.TokenID()
  455. if err != nil {
  456. return "", fmt.Errorf(errVaultToken, err)
  457. }
  458. return token, nil
  459. }
  460. // kubeParameters creates the required body for Vault Kubernetes auth.
  461. // Reference - https://www.vaultproject.io/api/auth/kubernetes#login
  462. func kubeParameters(role, jwt string) map[string]string {
  463. return map[string]string{
  464. "role": role,
  465. "jwt": jwt,
  466. }
  467. }
  468. func (v *client) requestTokenWithKubernetesAuth(ctx context.Context, client Client, kubernetesAuth *esv1alpha1.VaultKubernetesAuth) (string, error) {
  469. jwtString, err := getJwtString(ctx, v, kubernetesAuth)
  470. if err != nil {
  471. return "", err
  472. }
  473. parameters := kubeParameters(kubernetesAuth.Role, jwtString)
  474. url := strings.Join([]string{"/v1", "auth", kubernetesAuth.Path, "login"}, "/")
  475. request := client.NewRequest("POST", url)
  476. err = request.SetJSONBody(parameters)
  477. if err != nil {
  478. return "", fmt.Errorf(errVaultReqParams, err)
  479. }
  480. resp, err := client.RawRequestWithContext(ctx, request)
  481. if err != nil {
  482. return "", fmt.Errorf(errVaultRequest, err)
  483. }
  484. defer resp.Body.Close()
  485. vaultResult := vault.Secret{}
  486. err = resp.DecodeJSON(&vaultResult)
  487. if err != nil {
  488. return "", fmt.Errorf(errVaultResponse, err)
  489. }
  490. token, err := vaultResult.TokenID()
  491. if err != nil {
  492. return "", fmt.Errorf(errVaultToken, err)
  493. }
  494. return token, nil
  495. }
  496. func getJwtString(ctx context.Context, v *client, kubernetesAuth *esv1alpha1.VaultKubernetesAuth) (string, error) {
  497. if kubernetesAuth.ServiceAccountRef != nil {
  498. jwt, err := v.secretKeyRefForServiceAccount(ctx, kubernetesAuth.ServiceAccountRef)
  499. if err != nil {
  500. return "", err
  501. }
  502. return jwt, nil
  503. } else if kubernetesAuth.SecretRef != nil {
  504. tokenRef := kubernetesAuth.SecretRef
  505. if tokenRef.Key == "" {
  506. tokenRef = kubernetesAuth.SecretRef.DeepCopy()
  507. tokenRef.Key = "token"
  508. }
  509. jwt, err := v.secretKeyRef(ctx, tokenRef)
  510. if err != nil {
  511. return "", err
  512. }
  513. return jwt, nil
  514. } else {
  515. // Kubernetes authentication is specified, but without a referenced
  516. // Kubernetes secret. We check if the file path for in-cluster service account
  517. // exists and attempt to use the token for Vault Kubernetes auth.
  518. if _, err := os.Stat(serviceAccTokenPath); err != nil {
  519. return "", fmt.Errorf(errServiceAccount, err)
  520. }
  521. jwtByte, err := ioutil.ReadFile(serviceAccTokenPath)
  522. if err != nil {
  523. return "", fmt.Errorf(errServiceAccount, err)
  524. }
  525. return string(jwtByte), nil
  526. }
  527. }
  528. func (v *client) requestTokenWithLdapAuth(ctx context.Context, client Client, ldapAuth *esv1alpha1.VaultLdapAuth) (string, error) {
  529. username := strings.TrimSpace(ldapAuth.Username)
  530. password, err := v.secretKeyRef(ctx, &ldapAuth.SecretRef)
  531. if err != nil {
  532. return "", err
  533. }
  534. parameters := map[string]string{
  535. "password": password,
  536. }
  537. url := strings.Join([]string{"/v1", "auth", ldapAuth.Path, "login", username}, "/")
  538. request := client.NewRequest("POST", url)
  539. err = request.SetJSONBody(parameters)
  540. if err != nil {
  541. return "", fmt.Errorf(errVaultReqParams, err)
  542. }
  543. resp, err := client.RawRequestWithContext(ctx, request)
  544. if err != nil {
  545. return "", fmt.Errorf(errVaultRequest, err)
  546. }
  547. defer resp.Body.Close()
  548. vaultResult := vault.Secret{}
  549. if err = resp.DecodeJSON(&vaultResult); err != nil {
  550. return "", fmt.Errorf(errVaultResponse, err)
  551. }
  552. token, err := vaultResult.TokenID()
  553. if err != nil {
  554. return "", fmt.Errorf(errVaultToken, err)
  555. }
  556. return token, nil
  557. }
  558. func (v *client) requestTokenWithJwtAuth(ctx context.Context, client Client, jwtAuth *esv1alpha1.VaultJwtAuth) (string, error) {
  559. role := strings.TrimSpace(jwtAuth.Role)
  560. jwt, err := v.secretKeyRef(ctx, &jwtAuth.SecretRef)
  561. if err != nil {
  562. return "", err
  563. }
  564. parameters := map[string]string{
  565. "role": role,
  566. "jwt": jwt,
  567. }
  568. url := strings.Join([]string{"/v1", "auth", jwtAuth.Path, "login"}, "/")
  569. request := client.NewRequest("POST", url)
  570. err = request.SetJSONBody(parameters)
  571. if err != nil {
  572. return "", fmt.Errorf(errVaultReqParams, err)
  573. }
  574. resp, err := client.RawRequestWithContext(ctx, request)
  575. if err != nil {
  576. return "", fmt.Errorf(errVaultRequest, err)
  577. }
  578. defer resp.Body.Close()
  579. vaultResult := vault.Secret{}
  580. if err = resp.DecodeJSON(&vaultResult); err != nil {
  581. return "", fmt.Errorf(errVaultResponse, err)
  582. }
  583. token, err := vaultResult.TokenID()
  584. if err != nil {
  585. return "", fmt.Errorf(errVaultToken, err)
  586. }
  587. return token, nil
  588. }
  589. func (v *client) requestTokenWithCertAuth(ctx context.Context, client Client, certAuth *esv1alpha1.VaultCertAuth, cfg *vault.Config) (string, error) {
  590. clientKey, err := v.secretKeyRef(ctx, &certAuth.SecretRef)
  591. if err != nil {
  592. return "", err
  593. }
  594. clientCert, err := v.secretKeyRef(ctx, &certAuth.ClientCert)
  595. if err != nil {
  596. return "", err
  597. }
  598. cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
  599. if err != nil {
  600. return "", fmt.Errorf(errClientTLSAuth, err)
  601. }
  602. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  603. transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
  604. }
  605. url := strings.Join([]string{"/v1", "auth", "cert", "login"}, "/")
  606. request := client.NewRequest("POST", url)
  607. resp, err := client.RawRequestWithContext(ctx, request)
  608. if err != nil {
  609. return "", fmt.Errorf(errVaultRequest, err)
  610. }
  611. defer resp.Body.Close()
  612. vaultResult := vault.Secret{}
  613. if err = resp.DecodeJSON(&vaultResult); err != nil {
  614. return "", fmt.Errorf(errVaultResponse, err)
  615. }
  616. token, err := vaultResult.TokenID()
  617. if err != nil {
  618. return "", fmt.Errorf(errVaultToken, err)
  619. }
  620. return token, nil
  621. }