forked from drone/drone-vault
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
143 lines (125 loc) · 3.46 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Polyform License
// that can be found in the LICENSE file.
package main
import (
"context"
"net/http"
"time"
"github.com/drone/drone-go/plugin/secret"
"github.com/drone/drone-vault/plugin"
"github.com/drone/drone-vault/plugin/token"
"github.com/drone/drone-vault/plugin/token/kubernetes"
"github.com/drone/drone-vault/plugin/token/approle"
"github.com/hashicorp/vault/api"
"github.com/kelseyhightower/envconfig"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
_ "github.com/joho/godotenv/autoload"
)
// additional vault environment variables that are
// used by the vault client.
var envs = []string{
"VAULT_ADDR",
"VAULT_CACERT",
"VAULT_CAPATH",
"VAULT_CLIENT_CERT",
"VAULT_SKIP_VERIFY",
"VAULT_MAX_RETRIES",
"VAULT_TOKEN",
"VAULT_TLS_SERVER_NAME",
}
type config struct {
Address string `envconfig:"DRONE_BIND"`
Debug bool `envconfig:"DRONE_DEBUG"`
Secret string `envconfig:"DRONE_SECRET"`
VaultAddr string `envconfig:"VAULT_ADDR"`
VaultRenew time.Duration `envconfig:"VAULT_TOKEN_RENEWAL"`
VaultTTL time.Duration `envconfig:"VAULT_TOKEN_TTL"`
VaultAuthType string `envconfig:"VAULT_AUTH_TYPE"`
VaultAuthMount string `envconfig:"VAULT_AUTH_MOUNT_POINT"`
VaultApproleID string `envconfig:"VAULT_APPROLE_ID"`
VaultApproleSecret string `envconfig:"VAULT_APPROLE_SECRET"`
VaultKubeRole string `envconfig:"VAULT_KUBERNETES_ROLE"`
}
func main() {
spec := new(config)
err := envconfig.Process("", spec)
if err != nil {
logrus.Fatal(err)
}
if spec.Debug {
logrus.SetLevel(logrus.DebugLevel)
}
if spec.Secret == "" {
logrus.Fatalln("missing secret key")
}
if spec.VaultAddr == "" {
logrus.Warnln("missing vault address")
}
if spec.Address == "" {
spec.Address = ":3000"
}
// creates the vault client from the VAULT_*
// environment variables.
client, err := api.NewClient(nil)
if err != nil {
logrus.Fatalln(err)
}
// global context
ctx := context.Background()
http.Handle("/", secret.Handler(
spec.Secret,
plugin.New(client),
logrus.StandardLogger(),
))
var g errgroup.Group
// the token can be fetched at runtime if an auth
// provider is configured. otherwise, the user must
// specify a VAULT_TOKEN.
if spec.VaultAuthType == kubernetes.Name {
renewer := kubernetes.NewRenewer(
client,
spec.VaultAddr,
spec.VaultKubeRole,
spec.VaultAuthMount,
)
err := renewer.Renew(ctx)
if err != nil {
logrus.Fatalln(err)
}
// the vault token needs to be periodically
// refreshed and the kubernetes token has a
// max age of 32 days.
g.Go(func() error {
return renewer.Run(ctx, spec.VaultRenew)
})
} else if spec.VaultAuthType == approle.Name {
renewer := approle.NewRenewer(
client,
spec.VaultApproleID,
spec.VaultApproleSecret,
spec.VaultTTL,
)
err := renewer.Renew(ctx)
if err != nil {
logrus.Fatalln(err)
}
// the vault token needs to be periodically refreshed
g.Go(func() error {
return renewer.Run(ctx, spec.VaultRenew)
})
} else {
g.Go(func() error {
return token.NewRenewer(
client, spec.VaultTTL, spec.VaultRenew).Run(ctx)
})
}
g.Go(func() error {
logrus.Infof("server listening on address %s", spec.Address)
return http.ListenAndServe(spec.Address, nil)
})
if err := g.Wait(); err != nil {
logrus.Fatal(err)
}
}