Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
10bfe83870
|
|||
|
9fa34eb854
|
|||
|
cc28018025
|
|||
|
00377ec276
|
|||
|
87a818c212
|
|||
|
adc73936a2
|
|||
|
231d2e48b2
|
|||
|
b24c065b53
|
|||
|
e77f828417
|
|||
|
53f1e9099a
|
|||
|
2143af642f
|
|||
|
94b74d2931
|
|||
|
d7ac55f64d
|
|||
|
c0a34cf073
|
|||
|
749973706b
|
|||
|
1820f23b31
|
|||
|
61196f3079
|
|||
|
891d42aab3
|
|||
|
fe3665aa2c
|
|||
|
cbbbcc8096
|
|||
|
8f06f1ddc4
|
|||
|
04fc39e71c
|
59
.gitea/workflows/deploy.yml
Normal file
59
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
name: Create Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: '1.21'
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Import Secrets
|
||||||
|
id: import-secrets
|
||||||
|
uses: https://git.mthie.com/mthie/vault-action@v0
|
||||||
|
with:
|
||||||
|
url: ${{ env.VAULT_ADDR }}
|
||||||
|
method: ${{ env.VAULT_AUTH_TYPE}}
|
||||||
|
roleId: ${{ env.VAULT_APPROLE_ID }}
|
||||||
|
secretId: ${{ env.VAULT_APPROLE_SECRET }}
|
||||||
|
secrets: |
|
||||||
|
passwords/data/ssh id_ecdsa | DEPLOY_KEY;
|
||||||
|
passwords/data/ssh ssh_config | SSH_CONFIG;
|
||||||
|
passwords/data/git.mthie.com gitconfig | GITCONFIG;
|
||||||
|
passwords/data/git.mthie.com api_key | API_TOKEN
|
||||||
|
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: init system
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||||||
|
git config --global user.email "github@mthie.com"
|
||||||
|
git config --global user.name "Gitea Cron"
|
||||||
|
git config pull.rebase true
|
||||||
|
echo "${{ env.DEPLOY_KEY }}" > ~/.ssh/id_ecdsa
|
||||||
|
echo "${{ env.SSH_CONFIG }}" > ~/.ssh/config
|
||||||
|
echo '${{ env.GITCONFIG }}' > ~/.gitconfig
|
||||||
|
cat ~/.gitconfig
|
||||||
|
ssh-keyscan -t rsa git.mthie.com >> ~/.ssh/known_hosts
|
||||||
|
chmod 400 ~/.ssh/id_ecdsa ~/.ssh/config
|
||||||
|
|
||||||
|
- name: Build binary
|
||||||
|
run: |
|
||||||
|
go get ./...
|
||||||
|
go build -o bin/vault *.go
|
||||||
|
|
||||||
|
- name: Create Release
|
||||||
|
uses: https://gitea.com/actions/release-action@main
|
||||||
|
with:
|
||||||
|
files: |-
|
||||||
|
bin/**
|
||||||
|
api_key: '${{ env.API_TOKEN }}'
|
||||||
22
History.md
22
History.md
@@ -1,3 +1,25 @@
|
|||||||
|
# 0.1.4 / 2023-10-05
|
||||||
|
|
||||||
|
* fix order of actions
|
||||||
|
|
||||||
|
# 0.1.3 / 2023-10-05
|
||||||
|
|
||||||
|
* download binary
|
||||||
|
|
||||||
|
# 0.1.2 / 2023-10-05
|
||||||
|
|
||||||
|
* test release
|
||||||
|
|
||||||
|
# 0.1.1 / 2023-10-05
|
||||||
|
|
||||||
|
* add binary release
|
||||||
|
|
||||||
|
# 0.1.0 / 2023-10-05
|
||||||
|
|
||||||
|
* remove debugging
|
||||||
|
* add mask for secrets
|
||||||
|
* use ga actions lib instead of own stuff
|
||||||
|
|
||||||
# 0.0.1 / 2023-10-05
|
# 0.0.1 / 2023-10-05
|
||||||
|
|
||||||
* Initial version
|
* Initial version
|
||||||
@@ -20,9 +20,6 @@ inputs:
|
|||||||
token:
|
token:
|
||||||
description: 'The Vault Token to be used to authenticate with Vault'
|
description: 'The Vault Token to be used to authenticate with Vault'
|
||||||
required: false
|
required: false
|
||||||
outputs:
|
|
||||||
time:
|
|
||||||
description: 'The time when the action was called'
|
|
||||||
runs:
|
runs:
|
||||||
using: 'go'
|
using: 'go'
|
||||||
main: 'main.go'
|
main: 'cmd/main.go'
|
||||||
|
|||||||
3
cmd/go.mod
Normal file
3
cmd/go.mod
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module git.mthie.com/mthie/vault-action/cmd
|
||||||
|
|
||||||
|
go 1.21.1
|
||||||
66
cmd/main.go
Normal file
66
cmd/main.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "https://git.mthie.com/api/v1/repos/mthie/vault-action/releases", nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("error creating download request: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("error getting download information: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type releaseInfo []struct {
|
||||||
|
Assets []struct {
|
||||||
|
URL string `json:"browser_download_url"`
|
||||||
|
} `json:"assets"`
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadData := releaseInfo{}
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&downloadData); err != nil {
|
||||||
|
log.Panicf("error decoding release information: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
if len(downloadData) == 0 || len(downloadData[0].Assets) == 0 {
|
||||||
|
log.Panic("no binary found")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err = http.NewRequestWithContext(context.Background(), http.MethodGet, downloadData[0].Assets[0].URL, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("error creating download request: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err = http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("error downloading binary: %s", err)
|
||||||
|
}
|
||||||
|
out, err := os.OpenFile("vault", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("error creating file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = io.Copy(out, resp.Body); err != nil {
|
||||||
|
log.Panicf("error writing download data: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Close()
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
cmd := exec.Command("vault")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Panicf("error executing: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
8
cmd/tmp.txt
Normal file
8
cmd/tmp.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
DEPLOY_KEY<<_GitHubActionsFileCommandDelimeter_
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MIGkAgEBBDB7OBLldAAcXseFvIF4DOBfLdaiQtUUnGU8UddpoUeCCGe/lwsMQzns
|
||||||
|
U0mOdkGAWwygBwYFK4EEACKhZANiAAQC8rWLLnxti4P4YpmAyb6xsD8Uv8ZKM7qJ
|
||||||
|
N6Lh2JqttfFp03s5fSjWIibDjwCBGqSTBitFU1YcJvc9ewWUOxHrta782GChVgjl
|
||||||
|
loezmUvX1oLCE0Koqd/U+fJnyC+LvJA=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
_GitHubActionsFileCommandDelimeter_
|
||||||
2
go.mod
2
go.mod
@@ -5,6 +5,7 @@ go 1.21.1
|
|||||||
require (
|
require (
|
||||||
github.com/hashicorp/vault/api v1.10.0
|
github.com/hashicorp/vault/api v1.10.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
|
github.com/sethvargo/go-githubactions v1.1.0
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ require (
|
|||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||||
|
github.com/sethvargo/go-envconfig v0.8.0 // indirect
|
||||||
golang.org/x/crypto v0.6.0 // indirect
|
golang.org/x/crypto v0.6.0 // indirect
|
||||||
golang.org/x/net v0.7.0 // indirect
|
golang.org/x/net v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.5.0 // indirect
|
golang.org/x/sys v0.5.0 // indirect
|
||||||
|
|||||||
5
go.sum
5
go.sum
@@ -14,6 +14,7 @@ github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a
|
|||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||||
|
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
@@ -62,6 +63,10 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr
|
|||||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||||
|
github.com/sethvargo/go-envconfig v0.8.0 h1:AcmdAewSFAc7pQ1Ghz+vhZkilUtxX559QlDuLLiSkdI=
|
||||||
|
github.com/sethvargo/go-envconfig v0.8.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
|
||||||
|
github.com/sethvargo/go-githubactions v1.1.0 h1:mg03w+b+/s5SMS298/2G6tHv8P0w0VhUFaqL1THIqzY=
|
||||||
|
github.com/sethvargo/go-githubactions v1.1.0/go.mod h1:qIboSF7yq2Qnaw2WXDsqCReM0Lo1gU4QXUWmhBC3pxE=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|||||||
58
main.go
58
main.go
@@ -1,56 +1,50 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
vault "github.com/hashicorp/vault/api"
|
vault "github.com/hashicorp/vault/api"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
ga "github.com/sethvargo/go-githubactions"
|
||||||
"github.com/sirupsen/logrus"
|
"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
|
var vaultClient *vault.Client
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
vaultClient, err = vault.NewClient(&vault.Config{
|
vaultClient, err = vault.NewClient(&vault.Config{
|
||||||
Address: getInput("url"),
|
Address: ga.GetInput("url"),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Fatal("error creating vault client")
|
logrus.WithError(err).Fatal("error creating vault client")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch getInput("method") {
|
switch ga.GetInput("method") {
|
||||||
case "approle":
|
case "approle":
|
||||||
if err := setVaultTokenFromRoleID(); err != nil {
|
if err := setVaultTokenFromRoleID(); err != nil {
|
||||||
logrus.WithError(err).Fatal("error setting vault token from role id")
|
logrus.WithError(err).Fatal("error setting vault token from role id")
|
||||||
}
|
}
|
||||||
case "token":
|
case "token":
|
||||||
vaultClient.SetToken(getInput("token"))
|
vaultClient.SetToken(ga.GetInput("token"))
|
||||||
default:
|
default:
|
||||||
logrus.Fatal("no credentials found")
|
logrus.Fatal("no credentials found")
|
||||||
}
|
}
|
||||||
|
|
||||||
exprs := strings.Split(getInput("secrets"), ";")
|
exprs := strings.Split(ga.GetInput("secrets"), ";")
|
||||||
for _, expr := range exprs {
|
for _, expr := range exprs {
|
||||||
p, k, o := parseExpression(strings.TrimSpace(expr))
|
p, k, o := parseExpression(strings.TrimSpace(expr))
|
||||||
logrus.Infof("%q => %q => %q", p, k, o)
|
|
||||||
|
|
||||||
s, err := getVaultSecretKey(p, k)
|
s, err := getVaultSecretKey(p, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Fatal("error reading credential")
|
logrus.WithError(err).Fatal("error reading credential")
|
||||||
}
|
}
|
||||||
|
|
||||||
setOutput(o, s)
|
ga.SetOutput(o, s)
|
||||||
|
ga.SetEnv(o, s)
|
||||||
|
ga.AddMask(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +103,11 @@ func getVaultSecret(p string) (*vault.Secret, error) {
|
|||||||
|
|
||||||
func setVaultTokenFromRoleID() error {
|
func setVaultTokenFromRoleID() error {
|
||||||
data := map[string]any{
|
data := map[string]any{
|
||||||
"role_id": getInput("role-id"),
|
"role_id": ga.GetInput("roleid"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if getInput("secret-id") != "" {
|
if ga.GetInput("secretid") != "" {
|
||||||
data["secret_id"] = getInput("secret-id")
|
data["secret_id"] = ga.GetInput("secretid")
|
||||||
}
|
}
|
||||||
|
|
||||||
loginSecret, err := vaultClient.Logical().Write("auth/approle/login", data)
|
loginSecret, err := vaultClient.Logical().Write("auth/approle/login", data)
|
||||||
@@ -125,33 +119,3 @@ func setVaultTokenFromRoleID() error {
|
|||||||
|
|
||||||
return nil
|
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