first commit
This commit is contained in:
157
main.go
Normal file
157
main.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
vault "github.com/hashicorp/vault/api"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
eol = "\n"
|
||||
multiLineFileDelim = "_GitHubActionsFileCommandDelimeter_"
|
||||
multilineFileCmd = "%s<<" + multiLineFileDelim + eol + "%s" + eol + multiLineFileDelim // ${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}
|
||||
)
|
||||
|
||||
var vaultClient *vault.Client
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
vaultClient, err = vault.NewClient(&vault.Config{
|
||||
Address: getInput("url"),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatal("error creating vault client")
|
||||
}
|
||||
|
||||
switch getInput("method") {
|
||||
case "approle":
|
||||
if err := setVaultTokenFromRoleID(); err != nil {
|
||||
logrus.WithError(err).Fatal("error setting vault token from role id")
|
||||
}
|
||||
case "token":
|
||||
vaultClient.SetToken(getInput("token"))
|
||||
default:
|
||||
logrus.Fatal("no credentials found")
|
||||
}
|
||||
|
||||
exprs := strings.Split(getInput("secrets"), ";")
|
||||
for _, expr := range exprs {
|
||||
p, k, o := parseExpression(strings.TrimSpace(expr))
|
||||
logrus.Infof("%q => %q => %q", p, k, o)
|
||||
|
||||
s, err := getVaultSecretKey(p, k)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatal("error reading credential")
|
||||
}
|
||||
|
||||
setOutput(o, 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": getInput("role-id"),
|
||||
}
|
||||
|
||||
if getInput("secret-id") != "" {
|
||||
data["secret_id"] = getInput("secret-id")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func getInput(i string) string {
|
||||
e := strings.ReplaceAll(i, " ", "_")
|
||||
e = strings.ToUpper(e)
|
||||
e = "INPUT_" + e
|
||||
|
||||
return strings.ReplaceAll(strings.TrimSpace(os.Getenv(e)), "\\n", "\n")
|
||||
}
|
||||
|
||||
func setOutput(k, v string) (err error) {
|
||||
msg := fmt.Sprintf(multilineFileCmd, k, v)
|
||||
outputFilepath := os.Getenv("GITHUB_OUTPUT")
|
||||
|
||||
f, err := os.OpenFile(outputFilepath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "open output file")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if cErr := f.Close(); cErr != nil && err == nil {
|
||||
err = cErr
|
||||
}
|
||||
}()
|
||||
|
||||
if _, err := f.Write([]byte(msg)); err != nil {
|
||||
return errors.Wrap(err, "write to output")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user