mirror of https://github.com/kubernetes/kops.git
94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
/*
|
|
Copyright 2020 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package vfs
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
|
|
"k8s.io/klog/v2"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
|
"github.com/aws/aws-sdk-go/service/sts"
|
|
vault "github.com/hashicorp/vault/api"
|
|
)
|
|
|
|
func newVaultClient(scheme string, host string, port string) (*vault.Client, error) {
|
|
addr := scheme + host
|
|
if port != "" {
|
|
addr = addr + ":" + port
|
|
}
|
|
config := &vault.Config{
|
|
Address: addr,
|
|
HttpClient: &http.Client{},
|
|
}
|
|
client, err := vault.NewClient(config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
token := os.Getenv("VAULT_TOKEN")
|
|
if token == "" {
|
|
token, err = awsAuth(client, host)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error authenticating vault to AWS: %v", err)
|
|
}
|
|
}
|
|
|
|
client.SetToken(token)
|
|
return client, nil
|
|
}
|
|
|
|
func awsAuth(client *vault.Client, host string) (string, error) {
|
|
klog.Infof("Using AWS IAM to authenticate to Vault at %q", host)
|
|
config := aws.NewConfig()
|
|
config = config.WithCredentialsChainVerboseErrors(true)
|
|
session, err := session.NewSession(config)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
svc := sts.New(session)
|
|
stsRequest, _ := svc.GetCallerIdentityRequest(nil)
|
|
stsRequest.HTTPRequest.Header.Add("X-Vault-AWS-IAM-Server-ID", host)
|
|
stsRequest.Sign()
|
|
headersJson, err := json.Marshal(stsRequest.HTTPRequest.Header)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
requestBody, err := io.ReadAll(stsRequest.HTTPRequest.Body)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
loginData := make(map[string]interface{})
|
|
loginData["iam_http_request_method"] = stsRequest.HTTPRequest.Method
|
|
loginData["iam_request_url"] = base64.StdEncoding.EncodeToString([]byte(stsRequest.HTTPRequest.URL.String()))
|
|
loginData["iam_request_headers"] = base64.StdEncoding.EncodeToString(headersJson)
|
|
loginData["iam_request_body"] = base64.StdEncoding.EncodeToString(requestBody)
|
|
loginData["role"] = ""
|
|
path := "auth/aws/login"
|
|
secret, err := client.Logical().Write(path, loginData)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return secret.Auth.ClientToken, err
|
|
}
|