| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package config | |
| 6 | |
| 7 import ( | |
| 8 gaeauthClient "github.com/luci/luci-go/appengine/gaeauth/client" | |
| 9 "github.com/luci/luci-go/common/errors" | |
| 10 log "github.com/luci/luci-go/common/logging" | |
| 11 "github.com/luci/luci-go/server/logdog/storage" | |
| 12 "github.com/luci/luci-go/server/logdog/storage/bigtable" | |
| 13 "golang.org/x/net/context" | |
| 14 "google.golang.org/cloud" | |
| 15 "google.golang.org/grpc/metadata" | |
| 16 ) | |
| 17 | |
| 18 // GetStorage returns a configured BigTable Storage instance. | |
| 19 // | |
| 20 // The instance is configured from the configuration returned by Get. Upon | |
| 21 // success, the returned instance will need to be Close()'d when the caller has | |
| 22 // finished with it. | |
| 23 func GetStorage(c context.Context) (storage.Storage, error) { | |
| 24 gcfg, err := LoadGlobalConfig(c) | |
| 25 if err != nil { | |
| 26 log.WithError(err).Errorf(c, "Failed to load global configuratio
n.") | |
| 27 return nil, err | |
| 28 } | |
| 29 | |
| 30 cfg, err := gcfg.LoadConfig(c) | |
| 31 if err != nil { | |
| 32 log.WithError(err).Errorf(c, "Failed to load instance configurat
ion.") | |
| 33 return nil, err | |
| 34 } | |
| 35 | |
| 36 // Is BigTable configured? | |
| 37 if cfg.Storage == nil { | |
| 38 return nil, errors.New("no storage configuration") | |
| 39 } | |
| 40 | |
| 41 bt := cfg.Storage.GetBigtable() | |
| 42 if bt == nil { | |
| 43 return nil, errors.New("no BigTable configuration") | |
| 44 } | |
| 45 | |
| 46 // Validate the BigTable configuration. | |
| 47 log.Fields{ | |
| 48 "project": bt.Project, | |
| 49 "zone": bt.Zone, | |
| 50 "cluster": bt.Cluster, | |
| 51 "logTableName": bt.LogTableName, | |
| 52 }.Debugf(c, "Connecting to BigTable.") | |
| 53 var merr errors.MultiError | |
| 54 if bt.Project == "" { | |
| 55 merr = append(merr, errors.New("missing project")) | |
| 56 } | |
| 57 if bt.Zone == "" { | |
| 58 merr = append(merr, errors.New("missing zone")) | |
| 59 } | |
| 60 if bt.Cluster == "" { | |
| 61 merr = append(merr, errors.New("missing cluster")) | |
| 62 } | |
| 63 if bt.LogTableName == "" { | |
| 64 merr = append(merr, errors.New("missing log table name")) | |
| 65 } | |
| 66 if len(merr) > 0 { | |
| 67 return nil, merr | |
| 68 } | |
| 69 | |
| 70 // Get an Authenticator bound to the token scopes that we need for BigTa
ble. | |
| 71 a, err := gaeauthClient.Authenticator(c, bigtable.StorageScopes, gcfg.Bi
gTableServiceAccountJSON) | |
| 72 if err != nil { | |
| 73 log.WithError(err).Errorf(c, "Failed to create BigTable authenti
cator.") | |
| 74 return nil, errors.New("failed to create BigTable authenticator"
) | |
| 75 } | |
| 76 | |
| 77 // Explicitly clear gRPC metadata from the Context. It is forwarded to | |
| 78 // delegate calls by default, and standard request metadata can break Bi
gTable | |
| 79 // calls. | |
| 80 c = metadata.NewContext(c, nil) | |
| 81 | |
| 82 st, err := bigtable.New(c, bigtable.Options{ | |
| 83 Project: bt.Project, | |
| 84 Zone: bt.Zone, | |
| 85 Cluster: bt.Cluster, | |
| 86 LogTable: bt.LogTableName, | |
| 87 ClientOptions: []cloud.ClientOption{ | |
| 88 cloud.WithTokenSource(a.TokenSource()), | |
| 89 }, | |
| 90 }) | |
| 91 if err != nil { | |
| 92 log.WithError(err).Errorf(c, "Failed to create BigTable instance
.") | |
| 93 return nil, err | |
| 94 } | |
| 95 return st, nil | |
| 96 } | |
| OLD | NEW |