122 lines
2.7 KiB
Go
122 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
|
|
vault "github.com/hashicorp/vault/api"
|
|
"github.com/pkg/errors"
|
|
ga "github.com/sethvargo/go-githubactions"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var vaultClient *vault.Client
|
|
|
|
func main() {
|
|
var err error
|
|
|
|
vaultClient, err = vault.NewClient(&vault.Config{
|
|
Address: ga.GetInput("url"),
|
|
})
|
|
|
|
if err != nil {
|
|
logrus.WithError(err).Fatal("error creating vault client")
|
|
}
|
|
|
|
switch ga.GetInput("method") {
|
|
case "approle":
|
|
if err := setVaultTokenFromRoleID(); err != nil {
|
|
logrus.WithError(err).Fatal("error setting vault token from role id")
|
|
}
|
|
case "token":
|
|
vaultClient.SetToken(ga.GetInput("token"))
|
|
default:
|
|
logrus.Fatal("no credentials found")
|
|
}
|
|
|
|
exprs := strings.Split(ga.GetInput("secrets"), ";")
|
|
for _, expr := range exprs {
|
|
p, k, o := parseExpression(strings.TrimSpace(expr))
|
|
|
|
s, err := getVaultSecretKey(p, k)
|
|
if err != nil {
|
|
logrus.WithError(err).Fatal("error reading credential")
|
|
}
|
|
|
|
ga.SetOutput(o, s)
|
|
ga.SetEnv(o, s)
|
|
ga.AddMask(s)
|
|
}
|
|
}
|
|
|
|
func parseExpression(i string) (path, key, outputName string) {
|
|
input := strings.TrimSpace(strings.Trim(i, "\""))
|
|
|
|
if strings.Contains(input, "|") {
|
|
oSplit := strings.Split(strings.TrimSpace(input), "|")
|
|
if len(oSplit) > 1 {
|
|
outputName = strings.TrimSpace(oSplit[1])
|
|
input = strings.TrimSpace(oSplit[0])
|
|
}
|
|
}
|
|
|
|
if strings.Contains(input, " ") {
|
|
iSplit := strings.Split(strings.TrimSpace(input), " ")
|
|
if len(iSplit) > 1 {
|
|
path = strings.TrimSpace(iSplit[0])
|
|
key = strings.TrimSpace(iSplit[1])
|
|
|
|
if outputName == "" {
|
|
outputName = strings.TrimSpace(iSplit[1])
|
|
}
|
|
}
|
|
}
|
|
|
|
outputName = strings.TrimSpace(outputName)
|
|
outputName = strings.ReplaceAll(outputName, " ", "_")
|
|
outputName = strings.ToUpper(outputName)
|
|
|
|
return path, key, outputName
|
|
}
|
|
|
|
func getVaultSecretKey(p, k string) (string, error) {
|
|
s, err := getVaultSecret(p)
|
|
if err != nil {
|
|
return "", errors.Wrap(err, "error getting path")
|
|
}
|
|
|
|
if s == nil || s.Data == nil || s.Data["data"] == nil {
|
|
return "", errors.New("nil secret or secret data")
|
|
}
|
|
|
|
v, ok := s.Data["data"].(map[string]any)[k].(string)
|
|
if !ok {
|
|
logrus.Infof("Data: %#v", s.Data["data"])
|
|
return "", errors.New("key in secret not found")
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func getVaultSecret(p string) (*vault.Secret, error) {
|
|
return vaultClient.Logical().Read(p)
|
|
}
|
|
|
|
func setVaultTokenFromRoleID() error {
|
|
data := map[string]any{
|
|
"role_id": ga.GetInput("roleid"),
|
|
}
|
|
|
|
if ga.GetInput("secretid") != "" {
|
|
data["secret_id"] = ga.GetInput("secretid")
|
|
}
|
|
|
|
loginSecret, err := vaultClient.Logical().Write("auth/approle/login", data)
|
|
if err != nil || loginSecret.Auth == nil {
|
|
return errors.Wrap(err, "fetching authentication token")
|
|
}
|
|
|
|
vaultClient.SetToken(loginSecret.Auth.ClientToken)
|
|
|
|
return nil
|
|
}
|