Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(392)

Side by Side Diff: appengine/gaesecrets/gaesecrets.go

Issue 2951393002: [errors] de-specialize Transient in favor of Tags. (Closed)
Patch Set: more refactor Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 // Package gaesecrets implements storage of secret blobs on top of datastore. 5 // Package gaesecrets implements storage of secret blobs on top of datastore.
6 // 6 //
7 // It is not super secure, but we have what we have: there's no other better 7 // It is not super secure, but we have what we have: there's no other better
8 // mechanism to persistently store non-static secrets on GAE. 8 // mechanism to persistently store non-static secrets on GAE.
9 // 9 //
10 // All secrets are global (live in default GAE namespace). 10 // All secrets are global (live in default GAE namespace).
11 package gaesecrets 11 package gaesecrets
12 12
13 import ( 13 import (
14 "crypto/rand" 14 "crypto/rand"
15 "fmt" 15 "fmt"
16 "io" 16 "io"
17 "strings" 17 "strings"
18 "time" 18 "time"
19 19
20 "golang.org/x/net/context" 20 "golang.org/x/net/context"
21 21
22 ds "github.com/luci/gae/service/datastore" 22 ds "github.com/luci/gae/service/datastore"
23 "github.com/luci/gae/service/info" 23 "github.com/luci/gae/service/info"
24 "github.com/luci/luci-go/common/clock" 24 "github.com/luci/luci-go/common/clock"
25 "github.com/luci/luci-go/common/data/caching/proccache" 25 "github.com/luci/luci-go/common/data/caching/proccache"
26 » "github.com/luci/luci-go/common/errors" 26 » "github.com/luci/luci-go/common/retry/transient"
27 "github.com/luci/luci-go/server/secrets" 27 "github.com/luci/luci-go/server/secrets"
28 ) 28 )
29 29
30 // TODO(vadimsh): Add secrets rotation. 30 // TODO(vadimsh): Add secrets rotation.
31 31
32 // procCacheExp is how long to cache secrets in the process memory. 32 // procCacheExp is how long to cache secrets in the process memory.
33 const procCacheExp = time.Minute * 5 33 const procCacheExp = time.Minute * 5
34 34
35 // Config can be used to tweak parameters of the store. It is fine to use 35 // Config can be used to tweak parameters of the store. It is fine to use
36 // default values. 36 // default values.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 c, err := info.Namespace(s.ctx, "") 91 c, err := info.Namespace(s.ctx, "")
92 if err != nil { 92 if err != nil {
93 panic(err) // should not happen, Namespace errors only on bad na mespace name 93 panic(err) // should not happen, Namespace errors only on bad na mespace name
94 } 94 }
95 c = ds.WithoutTransaction(c) 95 c = ds.WithoutTransaction(c)
96 96
97 // Grab existing. 97 // Grab existing.
98 ent := secretEntity{ID: s.cfg.Prefix + ":" + string(k)} 98 ent := secretEntity{ID: s.cfg.Prefix + ":" + string(k)}
99 err = ds.Get(c, &ent) 99 err = ds.Get(c, &ent)
100 if err != nil && err != ds.ErrNoSuchEntity { 100 if err != nil && err != ds.ErrNoSuchEntity {
101 » » return secrets.Secret{}, errors.WrapTransient(err) 101 » » return secrets.Secret{}, transient.Tag.Apply(err)
102 } 102 }
103 103
104 // Autogenerate and put into the datastore. 104 // Autogenerate and put into the datastore.
105 if err == ds.ErrNoSuchEntity { 105 if err == ds.ErrNoSuchEntity {
106 if s.cfg.NoAutogenerate { 106 if s.cfg.NoAutogenerate {
107 return secrets.Secret{}, secrets.ErrNoSuchSecret 107 return secrets.Secret{}, secrets.ErrNoSuchSecret
108 } 108 }
109 ent.Created = clock.Now(s.ctx).UTC() 109 ent.Created = clock.Now(s.ctx).UTC()
110 if ent.Secret, err = s.generateSecret(); err != nil { 110 if ent.Secret, err = s.generateSecret(); err != nil {
111 » » » return secrets.Secret{}, errors.WrapTransient(err) 111 » » » return secrets.Secret{}, transient.Tag.Apply(err)
112 } 112 }
113 if ent.SecretID, err = s.generateSecretID(ent.Created); err != n il { 113 if ent.SecretID, err = s.generateSecretID(ent.Created); err != n il {
114 » » » return secrets.Secret{}, errors.WrapTransient(err) 114 » » » return secrets.Secret{}, transient.Tag.Apply(err)
115 } 115 }
116 err = ds.RunInTransaction(c, func(c context.Context) error { 116 err = ds.RunInTransaction(c, func(c context.Context) error {
117 newOne := secretEntity{ID: ent.ID} 117 newOne := secretEntity{ID: ent.ID}
118 switch err := ds.Get(c, &newOne); err { 118 switch err := ds.Get(c, &newOne); err {
119 case nil: 119 case nil:
120 ent = newOne 120 ent = newOne
121 return nil 121 return nil
122 case ds.ErrNoSuchEntity: 122 case ds.ErrNoSuchEntity:
123 return ds.Put(c, &ent) 123 return ds.Put(c, &ent)
124 default: 124 default:
125 return err 125 return err
126 } 126 }
127 }, nil) 127 }, nil)
128 if err != nil { 128 if err != nil {
129 » » » return secrets.Secret{}, errors.WrapTransient(err) 129 » » » return secrets.Secret{}, transient.Tag.Apply(err)
130 } 130 }
131 } 131 }
132 132
133 return secrets.Secret{ 133 return secrets.Secret{
134 Current: secrets.NamedBlob{ 134 Current: secrets.NamedBlob{
135 ID: ent.SecretID, 135 ID: ent.SecretID,
136 Blob: ent.Secret, 136 Blob: ent.Secret,
137 }, 137 },
138 }, nil 138 }, nil
139 } 139 }
(...skipping 21 matching lines...) Expand all
161 161
162 type secretEntity struct { 162 type secretEntity struct {
163 _kind string `gae:"$kind,gaesecrets.Secret"` 163 _kind string `gae:"$kind,gaesecrets.Secret"`
164 164
165 ID string `gae:"$id"` 165 ID string `gae:"$id"`
166 166
167 Secret []byte `gae:",noindex"` // blob with the secret 167 Secret []byte `gae:",noindex"` // blob with the secret
168 SecretID string `gae:",noindex"` // ID of the Secret blob 168 SecretID string `gae:",noindex"` // ID of the Secret blob
169 Created time.Time 169 Created time.Time
170 } 170 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698