Compare commits

...

6 commits

Author SHA1 Message Date
Marcel S. Henselin
3c562f3d63 feat: directly put values into pipeline
All checks were successful
Release Secrets Manager Action / build (push) Successful in 1m16s
2026-05-13 11:38:42 +02:00
Marcel S. Henselin
3f383ff085 feat: directly put values into pipeline
Some checks are pending
Release Secrets Manager Action / build (push) Waiting to run
2026-05-13 11:25:53 +02:00
Marcel S. Henselin
c26db1d567 feat: directly put values into pipeline 2026-05-13 11:22:30 +02:00
Marcel S. Henselin
a76a1220de feat: env file loading support
fix: typo
2026-05-13 09:51:04 +02:00
Marcel S. Henselin
fdbef9d95e fix: some errorhandling corrections 2026-05-13 09:30:55 +02:00
Marcel S. Henselin
aa77ad77e2 fix: some errorhandling corrections
chore: updated versions
2026-05-13 08:37:55 +02:00
11 changed files with 2102 additions and 72 deletions

View file

@ -10,15 +10,15 @@ env:
jobs:
build:
runs-on: docker
runs-on: stackit-docker
steps:
- name: 📤 Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: ⚙️ Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: 1.25
go-version: 1.26
- name: ⚙️ Install dependencies
run: |
@ -26,19 +26,19 @@ jobs:
- name: 👨🏻‍🔧 Build app
run: |
go build -o ${{ env.build_name }}
CGO_ENABLED=0 go build -o "${{ env.build_name }}" -ldflags="-s -w"
- name: 🤠 Create release
run: |
set -e
echo "Creating release for ${{ env.GITHUB_REPOSITORY}} with tag ${{ env.GITHUB_REF_NAME }}"
echo "Creating release for ${{ github.repository }} with tag ${{ github.ref_name }}"
REQUEST=$(curl --fail --request POST \
--url ${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases \
--url ${{ env.GITHUB_API_URL }}/repos/${{ github.repository }}/releases \
--header 'Authorization: token ${{ secrets.GIT_TOKEN }}' \
--header 'content-type: application/json' \
--data '{ "tag_name": "${{ env.GITHUB_REF_NAME }}" }')
--data '{ "tag_name": "${{ github.ref_name }}" }')
ls -lh ${{ env.build_name }}
@ -47,6 +47,6 @@ jobs:
echo "Uploading release asset for Release ID ${RELEASE_ID}"
curl --fail --request POST \
--url ${{ env.GITHUB_API_URL }}/repos/${{ env.GITHUB_REPOSITORY }}/releases/${RELEASE_ID}/assets?name=${{ env.build_name }} \
--url ${{ env.GITHUB_API_URL }}/repos/${{ github.repository }}/releases/${RELEASE_ID}/assets?name=${{ env.build_name }} \
--header 'Authorization: token ${{ secrets.GIT_TOKEN }}' \
-F 'attachment=@${{ env.build_name}}'

28
.gitignore vendored Normal file
View file

@ -0,0 +1,28 @@
### Go template
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum
# env file
.env
action-secretsmanager

View file

@ -15,7 +15,7 @@
## usage
In this example we assume that there is a Secret on Path "${{ secrets.VAULT_PATH}}" and there is a KVSecret named "test".
In the "Output secret" step we output above mentioned KVSecret "test". We access the outputs of the secrets step.
In the "Output secret" step we output KVSecret "test" mentioned above. We access the outputs of the secrets step.
Keep in mind to set an id on the actions step and use that to reference the outputted secrets.

View file

@ -2,10 +2,6 @@ name: STACKIT Secrets Manager Secret Fetcher
description: Connects to Secrets Manager using a Go app, gets all secrets under a path, and outputs them.
inputs:
go_version:
description: The version of Go to use for building the application.
required: false
default: 1.24.x
vault_addr:
description: You could optionally override the address.
required: false
@ -23,7 +19,7 @@ inputs:
debug:
description: Turn on debugging logs.
required: false
default: false
default: 'false'
version:
description: The version of the action.
required: false
@ -32,6 +28,7 @@ inputs:
outputs:
secrets:
description: A JSON object string containing all the fetched secrets.
value: ${{ steps.secrets.outputs.stdout }}
runs:
using: composite
@ -41,7 +38,7 @@ runs:
run: |
wget ${{ env.ACTION_URL }}/releases/download/${{ inputs.version }}/action-secretsmanager
chmod +x action-secretsmanager
./action-secretsmanager >> $GITHUB_OUTPUT
./action-secretsmanager
shell: bash
env:
VAULT_ADDR: ${{ inputs.vault_addr }}

View file

@ -45,7 +45,10 @@ func FatalLog(format string, args ...interface{}) {
func ValidateConfig(
cfg Config,
) Config {
defaults.Set(&cfg)
err := defaults.Set(&cfg)
if err != nil {
FatalLog("unable to set defaults")
}
if cfg.VaultAddr == "" {
FatalLog("VAULT_ADDR cannot be empty")
@ -64,7 +67,7 @@ func ValidateConfig(
}
if cfg.VaultPath == "" {
FatalLog("VAULT_SECRET cannot be empty, this is the key of your secret")
FatalLog("VAULT_PATH cannot be empty, this is the key of your secret")
}
InfoLog("Using Vault address: %s", cfg.VaultAddr)

325
go.mod
View file

@ -1,21 +1,334 @@
module secretsmanager
go 1.24.3
go 1.26.3
require (
github.com/caarlos0/env/v11 v11.3.1
github.com/caarlos0/env/v11 v11.4.1
github.com/creasty/defaults v1.8.0
github.com/hashicorp/vault v1.21.4
github.com/hashicorp/vault-client-go v0.4.3
github.com/hashicorp/vault-plugin-secrets-kv v0.25.0
github.com/hashicorp/vault/api v1.23.0
github.com/hashicorp/vault/sdk v0.21.0
github.com/joho/godotenv v1.5.1
)
require (
cloud.google.com/go v0.121.6 // indirect
cloud.google.com/go/auth v0.16.5 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/cloudsqlconn v1.4.3 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
cloud.google.com/go/iam v1.5.2 // indirect
cloud.google.com/go/kms v1.23.0 // indirect
cloud.google.com/go/longrunning v0.6.7 // indirect
cloud.google.com/go/monitoring v1.24.2 // indirect
dario.cat/mergo v1.0.2 // indirect
filippo.io/edwards25519 v1.1.1 // indirect
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.24 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect
github.com/DataDog/datadog-go v3.2.0+incompatible // indirect
github.com/Jeffail/gabs/v2 v2.1.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.3.0 // indirect
github.com/ProtonMail/gopenpgp/v3 v3.2.1 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go v1.55.8 // indirect
github.com/aws/aws-sdk-go-v2 v1.38.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.29.15 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.68 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ec2 v1.200.0 // indirect
github.com/aws/aws-sdk-go-v2/service/ecs v1.53.8 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.20 // indirect
github.com/aws/smithy-go v1.22.5 // indirect
github.com/benbjohnson/immutable v0.4.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.2.0 // indirect
github.com/boltdb/bolt v1.3.1 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect
github.com/circonus-labs/circonusllhist v0.1.3 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/coreos/etcd v3.3.27+incompatible // indirect
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba // indirect
github.com/digitalocean/godo v1.7.5 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/dnaeon/go-vcr v1.2.0 // indirect
github.com/docker/docker v28.4.0+incompatible // indirect
github.com/docker/go-connections v0.6.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/duosecurity/duo_api_golang v0.0.0-20250430191550-ac36954387e7 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/gammazero/deque v0.2.1 // indirect
github.com/gammazero/workerpool v1.1.3 // indirect
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/errors v0.22.1 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/loads v0.22.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/strfmt v0.23.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect
github.com/go-sql-driver/mysql v1.9.3 // indirect
github.com/go-test/deep v1.1.1 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/certificate-transparency-go v1.3.2 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-metrics-stackdriver v0.2.0 // indirect
github.com/google/go-querystring v1.2.0 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
github.com/gophercloud/gophercloud v0.1.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hashicorp/cli v1.1.7 // indirect
github.com/hashicorp/consul/sdk v0.16.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/eventlogger v0.2.10 // indirect
github.com/hashicorp/go-bexpr v0.1.12 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/go-discover v1.1.1-0.20250922102917-55e5010ad859 // indirect
github.com/hashicorp/go-discover/provider/gce v0.0.0-20241120163552-5eb1507d16b4 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-hmac-drbg v0.0.0-20210916214228-a6e5a68489f6 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.1 // indirect
github.com/hashicorp/go-kms-wrapping/v2 v2.0.18 // indirect
github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.10 // indirect
github.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms/v2 v2.0.4 // indirect
github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.11 // indirect
github.com/hashicorp/go-kms-wrapping/wrappers/azurekeyvault/v2 v2.0.14 // indirect
github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2 v2.0.13 // indirect
github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.9 // indirect
github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.13 // indirect
github.com/hashicorp/go-memdb v1.3.5 // indirect
github.com/hashicorp/go-metrics v0.5.4 // indirect
github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-plugin v1.6.3 // indirect
github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/awsutil v0.3.0 // indirect
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 // indirect
github.com/hashicorp/go-secure-stdlib/cryptoutil v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/mlock v0.1.3 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect
github.com/hashicorp/go-secure-stdlib/permitpool v1.0.0 // indirect
github.com/hashicorp/go-secure-stdlib/plugincontainer v0.4.2 // indirect
github.com/hashicorp/go-secure-stdlib/regexp v1.0.0 // indirect
github.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.3 // indirect
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
github.com/hashicorp/go-syslog v1.0.0 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.1-vault-7 // indirect
github.com/hashicorp/hcp-sdk-go v0.138.0 // indirect
github.com/hashicorp/mdns v1.0.4 // indirect
github.com/hashicorp/raft v1.7.3 // indirect
github.com/hashicorp/raft-autopilot v0.3.0 // indirect
github.com/hashicorp/raft-boltdb/v2 v2.3.0 // indirect
github.com/hashicorp/raft-snapshot v1.0.4 // indirect
github.com/hashicorp/raft-wal v0.4.0 // indirect
github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.3 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgtype v1.14.3 // indirect
github.com/jackc/pgx/v4 v4.18.3 // indirect
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f // indirect
github.com/jefferai/jsonx v1.0.1 // indirect
github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531 // indirect
github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/klauspost/compress v1.18.5 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/jwx v1.2.29 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/linode/linodego v0.7.1 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/miekg/dns v1.1.50 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect
github.com/mitchellh/pointerstructure v1.2.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/go-archive v0.2.0 // indirect
github.com/moby/patternmatcher v0.6.1 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/okta/okta-sdk-golang/v5 v5.0.2 // indirect
github.com/onsi/ginkgo/v2 v2.27.2 // indirect
github.com/onsi/gomega v1.38.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/oracle/oci-go-sdk/v60 v60.0.0 // indirect
github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e // indirect
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
github.com/pires/go-proxyproto v0.8.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rboyer/safeio v0.2.3 // indirect
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/stretchr/testify v1.10.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
github.com/sasha-s/go-deadlock v0.3.5 // indirect
github.com/segmentio/fasthash v1.0.3 // indirect
github.com/sethvargo/go-limiter v0.7.1 // indirect
github.com/shirou/gopsutil/v3 v3.22.6 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect
github.com/sony/gobreaker v0.5.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/stretchr/objx v0.5.3 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/tencentcloud/tencentcloud-sdk-go v1.0.162 // indirect
github.com/tink-crypto/tink-go/v2 v2.4.0 // indirect
github.com/tklauser/go-sysconf v0.3.16 // indirect
github.com/tklauser/numcpus v0.11.0 // indirect
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect
github.com/vmware/govmomi v0.18.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/bbolt v1.4.0 // indirect
go.mongodb.org/mongo-driver v1.17.4 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
go.opentelemetry.io/otel v1.41.0 // indirect
go.opentelemetry.io/otel/metric v1.41.0 // indirect
go.opentelemetry.io/otel/trace v1.41.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
golang.org/x/mod v0.32.0 // indirect
golang.org/x/net v0.49.0 // indirect
golang.org/x/oauth2 v0.31.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.44.0 // indirect
golang.org/x/term v0.40.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.41.0 // indirect
google.golang.org/api v0.251.0 // indirect
google.golang.org/genproto v0.0.0-20251002232023-7c0ddcbb5797 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250922171735-9219d122eba9 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect
google.golang.org/grpc v1.75.1 // indirect
google.golang.org/protobuf v1.36.9 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/resty.v1 v1.12.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.2 // indirect
k8s.io/api v0.34.1 // indirect
k8s.io/apimachinery v0.34.1 // indirect
k8s.io/client-go v0.34.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)

1582
go.sum

File diff suppressed because it is too large Load diff

60
main.go
View file

@ -1,27 +1,71 @@
package main
import (
"log"
"fmt"
"log"
"os"
"strings"
"secretsmanager/config"
"secretsmanager/secretsmanager"
"github.com/caarlos0/env/v11"
"github.com/joho/godotenv"
)
func main() {
err := godotenv.Load()
if err != nil {
log.Println(".env file not found, using regular environment variables")
}
var cfg config.Config
err := env.Parse(&cfg)
err = env.Parse(&cfg)
if err != nil {
log.Fatalf("Error parsing environment variables %s", err)
}
cfg = config.ValidateConfig(cfg)
s := secretsmanager.InitializeClient(cfg)
data, _ := secretsmanager.GetSecrets(&s, cfg)
for _, secret := range data {
fmt.Println(secret)
s, err := secretsmanager.New(cfg)
if err != nil {
log.Fatalf("Error initializing secrets manager client: %s", err)
}
}
data, err := s.GetSecrets(cfg)
if err != nil {
log.Fatalf("Error retrieving secrets: %s", err)
}
for key, value := range data {
err = exportToPipeline(key, value)
if err != nil {
log.Fatalf("error exporting secret to pipeline: %s", err)
}
}
}
func exportToPipeline(key string, value interface{}) error {
outputFile := os.Getenv("GITHUB_OUTPUT")
if outputFile == "" {
return fmt.Errorf("env var GITHUB_OUTPUT not found (are we running in a pipeline?)")
}
f, err := os.OpenFile(outputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("error opening GITHUB_OUTPUT: %w", err)
}
defer f.Close()
var outputString string
if s, ok := value.(string); ok {
outputString = fmt.Sprintf("%s=%s\n", key, value)
if strings.Contains(s, "\n") {
delimiter := "EOF"
outputString = fmt.Sprintf("%s=<<%s\n%s\n%s\n", key, delimiter, value, delimiter)
}
}
if _, err := f.WriteString(outputString); err != nil {
return fmt.Errorf("failed writing to GITHUB_OUTPUT: %w", err)
}
return nil
}

97
main_test.go Normal file
View file

@ -0,0 +1,97 @@
package main
import (
"secretsmanager/config"
"testing"
"time"
"secretsmanager/secretsmanager"
kv "github.com/hashicorp/vault-plugin-secrets-kv"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/vault"
)
// CreateTestVault spins up a Vault server and tests against
// an actual Vault instance. Currently, this is only set up for kv v2
func createTestVault(t testing.TB) *vault.TestCluster {
t.Helper()
// CoreConfig parameterizes the Vault core config
coreConfig := &vault.CoreConfig{
LogicalBackends: map[string]logical.Factory{
"kv": kv.Factory,
},
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
// Handler returns an http.Handler for the API. This can be used on
// its own to mount the Vault API within another web server.
HandlerFunc: http.Handler,
})
cluster.Start()
// Create KV V2 mount on the path /test
// It starts in cluster mode, so you just pick one of the three clients
// In this case, Cores[0] is just always picking the first one
if err := cluster.Cores[0].Client.Sys().Mount("test", &api.MountInput{
Type: "kv",
Options: map[string]string{
"version": "2",
},
}); err != nil {
t.Fatal(err)
}
return cluster
}
func Test_exportToPipeline(t *testing.T) {
type args struct {
key string
value interface{}
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "happy path",
args: args{
key: "TEST_KEY",
value: "TEST_VALUE",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cluster := createTestVault(t)
defer cluster.Cleanup()
vaultClient := cluster.Cores[0].Client // only need a client from 1 of 3 clusters
_, err := secretsmanager.New(config.Config{
VaultAddr: vaultClient.Address(),
VaultUsername: "",
VaultPassword: "",
VaultSecretsManagerID: "",
VaultPath: "",
Debug: false,
})
if err != nil {
t.Fatal(err)
}
// time buffer required after new mount
// https://github.com/hashicorp/terraform-provider-vault/issues/677#issuecomment-609116328
// Code 400: Errors: Upgrading from non-versioned to versioned data. This backend will be unavailable for a brief period and will resume service shortly.
time.Sleep(2 * time.Second)
if err := exportToPipeline(tt.args.key, tt.args.value); (err != nil) != tt.wantErr {
t.Errorf("exportToPipeline() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

View file

@ -2,6 +2,7 @@ package secretsmanager
import (
"context"
"fmt"
"time"
"secretsmanager/config"
@ -15,27 +16,31 @@ type SecretsManager struct {
Client *vault.Client
}
func InitializeClient(
cfg config.Config,
) SecretsManager {
func New(cfg config.Config) (*SecretsManager, error) {
s := SecretsManager{}
s.Ctx = context.Background()
s.Client, _ = vault.New(
client, err := vault.New(
vault.WithAddress(cfg.VaultAddr),
vault.WithRequestTimeout(30*time.Second),
vault.WithTLS(vault.TLSConfiguration{
InsecureSkipVerify: false,
}),
)
if err != nil {
return nil, err
}
s.Client = client
config.InfoLog("Attempting to login with user %s", cfg.VaultUsername)
loginResp, err := s.Client.Auth.UserpassLogin(s.Ctx, cfg.VaultUsername, schema.UserpassLoginRequest{Password: cfg.VaultPassword})
if err != nil {
config.FatalLog("Vault login request failed: %s", err)
return nil, fmt.Errorf("vault login request failed: %w", err)
}
config.InfoLog("Login successful. Token received.")
s.Client.SetToken(loginResp.Auth.ClientToken)
err = s.Client.SetToken(loginResp.Auth.ClientToken)
if err != nil {
return nil, fmt.Errorf("vault login could not set token: %w", err)
}
return s
return &s, nil
}

View file

@ -3,35 +3,28 @@ package secretsmanager
import (
"fmt"
"secretsmanager/config"
"log"
"github.com/hashicorp/vault-client-go"
)
func GetSecrets(
s *SecretsManager,
cfg config.Config,
) ([]string, error) {
func (s *SecretsManager) GetSecrets(cfg config.Config) (map[string]interface{}, error) {
config.InfoLog("Attempting to read secret from mount '%s' at path '%s'", cfg.VaultSecretsManagerID, cfg.VaultPath)
secret, err := s.Client.Secrets.KvV2Read(s.Ctx, cfg.VaultPath, vault.WithMountPath(cfg.VaultSecretsManagerID))
if err != nil {
log.Fatalf("Failed to read secret from vault: %v", err)
return nil, fmt.Errorf("failed to read secret from vault: %w", err)
}
if secret == nil || secret.Data.Data == nil {
log.Fatal("No data found at the specified secret path.")
return []string{}, nil
return nil, fmt.Errorf("no data found at the specified secret path")
}
var secretsAsKeyValue []string
//var secretsAsKeyValue []string
//for key, value := range secret.Data.Data {
// secretsAsKeyValue = append(secretsAsKeyValue, fmt.Sprintf("%s=%v", key, value))
//}
//config.InfoLog("Successfully retrieved and formatted %d secrets.", len(secretsAsKeyValue))
for key, value := range secret.Data.Data {
secretsAsKeyValue = append(secretsAsKeyValue, fmt.Sprintf("%s=%v", key, value))
}
config.InfoLog("Successfully retrieved and formatted %d secrets.", len(secret.Data.Data))
config.InfoLog("Successfully retrieved and formatted %d secrets.", len(secretsAsKeyValue))
return secretsAsKeyValue, nil
return secret.Data.Data, nil
}