/
client.go
111 lines (97 loc) · 2.99 KB
/
client.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
package remoteks
import (
"crypto/tls"
"fmt"
"time"
google_protobuf "github.com/golang/protobuf/ptypes/empty"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"github.com/theupdateframework/notary/trustmanager"
)
// DefaultTimeout is the time a request will block waiting for a response
// from the server if no other timeout is configured.
const DefaultTimeout = time.Second * 30
// RemoteStore is a wrapper around the GRPC storage client, translating between
// the Go and GRPC APIs.
type RemoteStore struct {
client StoreClient
location string
timeout time.Duration
}
var _ trustmanager.Storage = &RemoteStore{}
// NewRemoteStore instantiates a RemoteStore.
func NewRemoteStore(server string, tlsConfig *tls.Config, timeout time.Duration) (*RemoteStore, error) {
cc, err := grpc.Dial(
server,
grpc.WithTransportCredentials(
credentials.NewTLS(tlsConfig),
),
grpc.WithBlock(),
)
if err != nil {
return nil, err
}
if timeout == 0 {
timeout = DefaultTimeout
}
return &RemoteStore{
client: NewStoreClient(cc),
location: server,
timeout: timeout,
}, nil
}
// getContext returns a context with the timeout configured at initialization
// time of the RemoteStore. We currently throw away the cancel function as we
// have no current use cases to cancel sooner than the timeout.
func (s *RemoteStore) getContext() context.Context {
ctx, _ := context.WithTimeout(context.Background(), s.timeout)
return ctx
}
// Set stores the data using the provided fileName
func (s *RemoteStore) Set(fileName string, data []byte) error {
sm := &SetMsg{
FileName: fileName,
Data: data,
}
_, err := s.client.Set(s.getContext(), sm)
return err
}
// Remove deletes a file from the store relative to the store's base directory.
// Paths are expected to be cleaned server side.
func (s *RemoteStore) Remove(fileName string) error {
fm := &FileNameMsg{
FileName: fileName,
}
_, err := s.client.Remove(s.getContext(), fm)
return err
}
// Get returns the file content found at fileName relative to the base directory
// of the file store. Paths are expected to be cleaned server side.
func (s *RemoteStore) Get(fileName string) ([]byte, error) {
fm := &FileNameMsg{
FileName: fileName,
}
bm, err := s.client.Get(s.getContext(), fm)
if err != nil {
return nil, err
}
return bm.Data, nil
}
// ListFiles returns a list of paths relative to the base directory of the
// filestore. Any of these paths must be retrievable via the
// Storage.Get method.
func (s *RemoteStore) ListFiles() []string {
logrus.Infof("listing files from %s", s.location)
fl, err := s.client.ListFiles(s.getContext(), &google_protobuf.Empty{})
if err != nil {
logrus.Errorf("error listing files from %s: %s", s.location, err.Error())
return nil
}
return fl.FileNames
}
// Location returns a human readable indication of where the storage is located.
func (s *RemoteStore) Location() string {
return fmt.Sprintf("Remote Key Store @ %s", s.location)
}