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

Side by Side Diff: tokenserver/appengine/certconfig/rpc_import_ca_configs.go

Issue 2575383002: Add server/cache support to gaeconfig. (Closed)
Patch Set: Un-collapse. Created 3 years, 11 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 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 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 certconfig 5 package certconfig
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "crypto/x509" 9 "crypto/x509"
10 "fmt" 10 "fmt"
11 "sync" 11 "sync"
12 "time" 12 "time"
13 13
14 "github.com/golang/protobuf/proto" 14 "github.com/golang/protobuf/proto"
15 "golang.org/x/net/context" 15 "golang.org/x/net/context"
16 "google.golang.org/grpc" 16 "google.golang.org/grpc"
17 "google.golang.org/grpc/codes" 17 "google.golang.org/grpc/codes"
18 18
19 ds "github.com/luci/gae/service/datastore" 19 ds "github.com/luci/gae/service/datastore"
20 "github.com/luci/gae/service/info"
21 "github.com/luci/luci-go/common/config"
22 "github.com/luci/luci-go/common/data/stringset" 20 "github.com/luci/luci-go/common/data/stringset"
23 "github.com/luci/luci-go/common/errors" 21 "github.com/luci/luci-go/common/errors"
24 "github.com/luci/luci-go/common/logging" 22 "github.com/luci/luci-go/common/logging"
25 "github.com/luci/luci-go/common/proto/google" 23 "github.com/luci/luci-go/common/proto/google"
24 "github.com/luci/luci-go/luci_config/server/cfgclient"
26 25
27 "github.com/luci/luci-go/tokenserver/api/admin/v1" 26 "github.com/luci/luci-go/tokenserver/api/admin/v1"
28 "github.com/luci/luci-go/tokenserver/appengine/utils" 27 "github.com/luci/luci-go/tokenserver/appengine/utils"
29 ) 28 )
30 29
31 // ImportCAConfigsRPC implements Admin.ImportCAConfigs RPC method. 30 // ImportCAConfigsRPC implements Admin.ImportCAConfigs RPC method.
32 type ImportCAConfigsRPC struct { 31 type ImportCAConfigsRPC struct {
33 } 32 }
34 33
35 // ImportCAConfigs fetches CA configs from from luci-config right now. 34 // ImportCAConfigs fetches CA configs from from luci-config right now.
36 func (r *ImportCAConfigsRPC) ImportCAConfigs(c context.Context, _ *google.Empty) (*admin.ImportedConfigs, error) { 35 func (r *ImportCAConfigsRPC) ImportCAConfigs(c context.Context, _ *google.Empty) (*admin.ImportedConfigs, error) {
37 » cfg, err := fetchConfigFile(c, "tokenserver.cfg") 36 » content, meta, err := fetchConfigFile(c, "tokenserver.cfg")
38 if err != nil { 37 if err != nil {
39 return nil, grpc.Errorf(codes.Internal, "can't read config file - %s", err) 38 return nil, grpc.Errorf(codes.Internal, "can't read config file - %s", err)
40 } 39 }
41 » logging.Infof(c, "Importing tokenserver.cfg at rev %s", cfg.Revision) 40 » logging.Infof(c, "Importing tokenserver.cfg at rev %s", meta.Revision)
42 41
43 // Read list of CAs. 42 // Read list of CAs.
44 msg := admin.TokenServerConfig{} 43 msg := admin.TokenServerConfig{}
45 » if err = proto.UnmarshalText(cfg.Content, &msg); err != nil { 44 » if err = proto.UnmarshalText(content, &msg); err != nil {
46 return nil, grpc.Errorf(codes.Internal, "can't parse config file - %s", err) 45 return nil, grpc.Errorf(codes.Internal, "can't parse config file - %s", err)
47 } 46 }
48 47
49 seenIDs, err := LoadCAUniqueIDToCNMap(c) 48 seenIDs, err := LoadCAUniqueIDToCNMap(c)
50 if err != nil { 49 if err != nil {
51 return nil, grpc.Errorf(codes.Internal, "can't load unique_id ma p - %s", err) 50 return nil, grpc.Errorf(codes.Internal, "can't load unique_id ma p - %s", err)
52 } 51 }
53 if seenIDs == nil { 52 if seenIDs == nil {
54 seenIDs = map[int64]string{} 53 seenIDs = map[int64]string{}
55 } 54 }
(...skipping 28 matching lines...) Expand all
84 } 83 }
85 } 84 }
86 85
87 // Add new CA datastore entries or update existing ones. 86 // Add new CA datastore entries or update existing ones.
88 wg := sync.WaitGroup{} 87 wg := sync.WaitGroup{}
89 me := errors.NewLazyMultiError(len(msg.GetCertificateAuthority())) 88 me := errors.NewLazyMultiError(len(msg.GetCertificateAuthority()))
90 for i, ca := range msg.GetCertificateAuthority() { 89 for i, ca := range msg.GetCertificateAuthority() {
91 wg.Add(1) 90 wg.Add(1)
92 go func(i int, ca *admin.CertificateAuthorityConfig) { 91 go func(i int, ca *admin.CertificateAuthorityConfig) {
93 defer wg.Done() 92 defer wg.Done()
94 » » » certFileCfg, err := fetchConfigFile(c, ca.CertPath) 93 » » » content, meta, err := fetchConfigFile(c, ca.CertPath)
95 if err != nil { 94 if err != nil {
96 logging.Errorf(c, "Failed to fetch %q: %s", ca.C ertPath, err) 95 logging.Errorf(c, "Failed to fetch %q: %s", ca.C ertPath, err)
97 me.Assign(i, err) 96 me.Assign(i, err)
98 » » » } else if err := importCA(c, ca, certFileCfg.Content, cf g.Revision); err != nil { 97 » » » } else if err := importCA(c, ca, content, meta.Revision) ; err != nil {
99 logging.Errorf(c, "Failed to import %q: %s", ca. Cn, err) 98 logging.Errorf(c, "Failed to import %q: %s", ca. Cn, err)
100 me.Assign(i, err) 99 me.Assign(i, err)
101 } 100 }
102 }(i, ca) 101 }(i, ca)
103 } 102 }
104 wg.Wait() 103 wg.Wait()
105 if err = me.Get(); err != nil { 104 if err = me.Get(); err != nil {
106 return nil, grpc.Errorf(codes.Internal, "can't import CA - %s", err) 105 return nil, grpc.Errorf(codes.Internal, "can't import CA - %s", err)
107 } 106 }
108 107
109 // Find CAs that were removed from the config. 108 // Find CAs that were removed from the config.
110 toRemove := []string{} 109 toRemove := []string{}
111 q := ds.NewQuery("CA").Eq("Removed", false).KeysOnly(true) 110 q := ds.NewQuery("CA").Eq("Removed", false).KeysOnly(true)
112 err = ds.Run(c, q, func(k *ds.Key) { 111 err = ds.Run(c, q, func(k *ds.Key) {
113 if !seenCAs.Has(k.StringID()) { 112 if !seenCAs.Has(k.StringID()) {
114 toRemove = append(toRemove, k.StringID()) 113 toRemove = append(toRemove, k.StringID())
115 } 114 }
116 }) 115 })
117 if err != nil { 116 if err != nil {
118 return nil, grpc.Errorf(codes.Internal, "datastore error - %s", err) 117 return nil, grpc.Errorf(codes.Internal, "datastore error - %s", err)
119 } 118 }
120 119
121 // Mark them as inactive in the datastore. 120 // Mark them as inactive in the datastore.
122 wg = sync.WaitGroup{} 121 wg = sync.WaitGroup{}
123 me = errors.NewLazyMultiError(len(toRemove)) 122 me = errors.NewLazyMultiError(len(toRemove))
124 for i, name := range toRemove { 123 for i, name := range toRemove {
125 wg.Add(1) 124 wg.Add(1)
126 go func(i int, name string) { 125 go func(i int, name string) {
127 defer wg.Done() 126 defer wg.Done()
128 » » » if err := removeCA(c, name, cfg.Revision); err != nil { 127 » » » if err := removeCA(c, name, meta.Revision); err != nil {
129 logging.Errorf(c, "Failed to remove %q: %s", nam e, err) 128 logging.Errorf(c, "Failed to remove %q: %s", nam e, err)
130 me.Assign(i, err) 129 me.Assign(i, err)
131 } 130 }
132 }(i, name) 131 }(i, name)
133 } 132 }
134 wg.Wait() 133 wg.Wait()
135 if err = me.Get(); err != nil { 134 if err = me.Get(); err != nil {
136 return nil, grpc.Errorf(codes.Internal, "datastore error - %s", err) 135 return nil, grpc.Errorf(codes.Internal, "datastore error - %s", err)
137 } 136 }
138 137
139 return &admin.ImportedConfigs{ 138 return &admin.ImportedConfigs{
140 ImportedConfigs: []*admin.ImportedConfigs_ConfigFile{ 139 ImportedConfigs: []*admin.ImportedConfigs_ConfigFile{
141 { 140 {
142 Name: "tokenserver.cfg", 141 Name: "tokenserver.cfg",
143 » » » » Revision: cfg.Revision, 142 » » » » Revision: meta.Revision,
144 }, 143 },
145 }, 144 },
146 }, nil 145 }, nil
147 } 146 }
148 147
149 // fetchConfigFile fetches a file from this services' config set. 148 // fetchConfigFile fetches a file from this services' config set.
150 func fetchConfigFile(c context.Context, path string) (*config.Config, error) { 149 func fetchConfigFile(c context.Context, path string) (string, *cfgclient.Meta, e rror) {
151 » configSet := "services/" + info.AppID(c) 150 » configSet := cfgclient.CurrentServiceConfigSet(c)
152 logging.Infof(c, "Reading %q from config set %q", path, configSet) 151 logging.Infof(c, "Reading %q from config set %q", path, configSet)
153 » c, _ = context.WithTimeout(c, 30*time.Second) // URL fetch deadline 152 » c, cancelFunc := context.WithTimeout(c, 29*time.Second) // URL fetch dea dline
154 » return config.GetConfig(c, configSet, path, false) 153 » defer cancelFunc()
154
155 » var (
156 » » content string
157 » » meta cfgclient.Meta
158 » )
159 » if err := cfgclient.Get(c, cfgclient.AsService, configSet, path, cfgclie nt.String(&content), &meta); err != nil {
160 » » return "", nil, err
161 » }
162 » return content, &meta, nil
155 } 163 }
156 164
157 // importCA imports CA definition from the config (or updates an existing one). 165 // importCA imports CA definition from the config (or updates an existing one).
158 func importCA(c context.Context, ca *admin.CertificateAuthorityConfig, certPem s tring, rev string) error { 166 func importCA(c context.Context, ca *admin.CertificateAuthorityConfig, certPem s tring, rev string) error {
159 // Read CA certificate file, convert it to der. 167 // Read CA certificate file, convert it to der.
160 certDer, err := utils.ParsePEM(certPem, "CERTIFICATE") 168 certDer, err := utils.ParsePEM(certPem, "CERTIFICATE")
161 if err != nil { 169 if err != nil {
162 return fmt.Errorf("bad PEM - %s", err) 170 return fmt.Errorf("bad PEM - %s", err)
163 } 171 }
164 172
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } 231 }
224 if existing.Removed { 232 if existing.Removed {
225 return nil 233 return nil
226 } 234 }
227 logging.Infof(c, "Removing CA %q", name) 235 logging.Infof(c, "Removing CA %q", name)
228 existing.Removed = true 236 existing.Removed = true
229 existing.RemovedRev = rev 237 existing.RemovedRev = rev
230 return ds.Put(c, &existing) 238 return ds.Put(c, &existing)
231 }, nil) 239 }, nil)
232 } 240 }
OLDNEW
« no previous file with comments | « scheduler/appengine/catalog/catalog_test.go ('k') | tokenserver/appengine/certconfig/rpc_import_ca_configs_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698