This repository has been archived by the owner on May 18, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
key_check.go
149 lines (120 loc) · 3.31 KB
/
key_check.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
149
package auth
import (
"context"
"net/http"
"strings"
"github.com/jackc/pgx"
triton "github.com/joyent/triton-go"
"github.com/joyent/triton-go/account"
"github.com/joyent/triton-go/authentication"
terrors "github.com/joyent/triton-go/errors"
"github.com/joyent/triton-service-groups/accounts"
"github.com/joyent/triton-service-groups/keys"
"github.com/pkg/errors"
)
type KeyCheck struct {
*ParsedRequest
Key *keys.Key
TritonKey *account.Key
config *triton.ClientConfig
store *keys.Store
account *accounts.Account
keyName string
}
func NewKeyCheck(req *ParsedRequest, acct *accounts.Account, store *keys.Store, cfg Config) *KeyCheck {
signer := &authentication.TestSigner{}
config := &triton.ClientConfig{
TritonURL: cfg.AuthURL,
AccountName: req.AccountName,
Signers: []authentication.Signer{signer},
}
keyName := strings.Join([]string{cfg.KeyNamePrefix, cfg.Datacenter}, "_")
return &KeyCheck{
ParsedRequest: req,
account: acct,
config: config,
store: store,
keyName: keyName,
}
}
// newClient constructs our Triton AccountClient
func (k *KeyCheck) newClient() (*account.AccountClient, error) {
return account.NewClient(k.config)
}
// CheckTriton checks Triton account keys for our TSG key
func (k *KeyCheck) OnTriton(ctx context.Context) error {
a, err := k.newClient()
if err != nil {
return errors.Wrap(err, "failed to create account key client")
}
a.SetHeader(k.ParsedRequest.Header())
input := &account.GetKeyInput{
KeyName: k.keyName,
}
key, err := a.Keys().Get(ctx, input)
if err != nil {
if terrors.IsSpecificStatusCode(err, http.StatusNotFound) {
return nil
}
return errors.Wrap(err, "failed to get triton key")
}
k.TritonKey = key
return nil
}
// InDatabase checks for and sets an account's key within the TSG database.
func (k *KeyCheck) InDatabase(ctx context.Context) error {
if k.account.KeyID == "" {
return nil
}
curKey, err := k.store.FindByID(ctx, k.account.KeyID)
switch err {
case nil:
k.Key = curKey
return nil
case pgx.ErrNoRows:
return nil
default:
return err
}
}
// AddKey adds an account key into Triton, converting the passed in KeyPair into
// a Triton-Go account.Key for use by external consumers.
func (k *KeyCheck) AddTritonKey(ctx context.Context, keypair *KeyPair) error {
a, err := k.newClient()
if err != nil {
return errors.Wrap(err, "failed to create new key client")
}
a.SetHeader(k.ParsedRequest.Header())
createInput := &account.CreateKeyInput{
Name: k.keyName,
Key: keypair.PublicKeyBase64(),
}
key, err := a.Keys().Create(ctx, createInput)
if err != nil {
return errors.Wrap(err, "failed to create new account key")
}
k.TritonKey = key
return nil
}
func (k *KeyCheck) InsertKey(ctx context.Context, keypair *KeyPair) error {
key := keys.New(k.store)
key.Name = k.keyName
key.Fingerprint = keypair.FingerprintMD5
key.Material = keypair.PrivateKeyPEM()
key.AccountID = k.account.ID
if err := key.Insert(ctx); err != nil {
return errors.Wrap(err, "failed to store account key")
}
k.account.KeyID = key.ID
if err := k.account.Save(ctx); err != nil {
return errors.Wrap(err, "failed to store account key_id")
}
k.Key = key
return nil
}
func (k *KeyCheck) HasTritonKey() bool {
return k.TritonKey != nil
}
func (k *KeyCheck) HasKey() bool {
return k.Key != nil
}