-
Notifications
You must be signed in to change notification settings - Fork 178
/
storage.go
113 lines (98 loc) · 3.19 KB
/
storage.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
package storage
import (
"context"
"fmt"
)
// Option wrapper for relevant Options for the client
type Option struct {
Prefix string // storage prefix
ProjectID string // GCP project ID
LocationID string // location of the key rings
ServiceAccount string // filename of the serviceaccount to use
}
//go:generate mockery -name=API -output=automock -outpkg=automock -case=underscore
// Client wrapper for GCS storage API
type Client struct {
Option
api API
}
// Struct that defines each bucket to create
type Bucket struct {
Name string `yaml:"name"`
Location string `yaml:"location,omitempty"`
}
// API provides a mockable interface for the GCP api. Find the implementation of the GCP wrapped API in wrapped.go
type API interface {
CreateBucket(ctx context.Context, name string, location string) error
DeleteBucket(ctx context.Context, name string) error
Read(ctx context.Context, bucket, storageObject string) ([]byte, error)
Write(ctx context.Context, data []byte, bucket, storageObject string) error
}
// New returns a new Client, wrapping gcs for storage management on GCP
func New(opts Option, api API) (*Client, error) {
if opts.ProjectID == "" {
return nil, fmt.Errorf("ProjectID is required to initialize a client")
}
if opts.ServiceAccount == "" {
return nil, fmt.Errorf("ServiceAccount is required to initialize a client")
}
if api == nil {
return nil, fmt.Errorf("api is required to initialize a client")
}
return &Client{Option: opts, api: api}, nil
}
// CreateBucket attempts to create a storage bucket
func (sc *Client) CreateBucket(ctx context.Context, name string, location string) error {
if name == "" {
return fmt.Errorf("name cannot be empty")
}
if sc.Prefix != "" {
name = fmt.Sprintf("%s-%s", sc.Prefix, name)
}
return sc.api.CreateBucket(ctx, name, location)
}
// DeleteBucket attempts to delete a storage bucket
func (sc *Client) DeleteBucket(ctx context.Context, name string) error {
if name == "" {
return fmt.Errorf("name cannot be empty")
}
return sc.api.DeleteBucket(ctx, name)
}
// Read attempts to read from a storage bucket
func (sc *Client) Read(ctx context.Context, bucket, storageObject string) ([]byte, error) {
if bucket == "" {
return nil, fmt.Errorf("bucket cannot be empty")
}
if storageObject == "" {
return nil, fmt.Errorf("storageObject cannot be empty")
}
return sc.api.Read(ctx, bucket, storageObject)
}
// Write attempts to write to a storage bucket
func (sc *Client) Write(ctx context.Context, data []byte, bucket, storageObject string) error {
if len(data) == 0 {
return fmt.Errorf("cannot write zero data")
}
if bucket == "" {
return fmt.Errorf("bucket cannot be empty")
}
if storageObject == "" {
return fmt.Errorf("storageObject cannot be empty")
}
return sc.api.Write(ctx, data, bucket, storageObject)
}
// WithPrefix modifies option to have a prefix
func (o Option) WithPrefix(pre string) Option {
o.Prefix = pre
return o
}
// WithProjectID modifies option to have a project id
func (o Option) WithProjectID(pid string) Option {
o.ProjectID = pid
return o
}
// WithServiceAccount modifies option to have a service account
func (o Option) WithServiceAccount(sa string) Option {
o.ServiceAccount = sa
return o
}