-
Notifications
You must be signed in to change notification settings - Fork 39
/
main.go
148 lines (129 loc) · 3.63 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
144
145
146
147
148
// 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/approle"
"github.com/drone/drone-vault/plugin/token/kubernetes"
"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"`
DisallowForks bool `envconfig:"DRONE_DISALLOW_FORKS"`
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()
if spec.DisallowForks {
logrus.Info("globally disallowing secrets in forks")
}
http.Handle("/", secret.Handler(
spec.Secret,
plugin.New(client, spec.DisallowForks),
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)
}
}