-
Notifications
You must be signed in to change notification settings - Fork 18
/
object_storage_buckets.go
142 lines (112 loc) · 4.03 KB
/
object_storage_buckets.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package services
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/linode/linodego"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"github.com/linode/cluster-api-provider-linode/cloud/scope"
"github.com/linode/cluster-api-provider-linode/util"
)
func EnsureObjectStorageBucket(ctx context.Context, bScope *scope.ObjectStorageBucketScope) (*linodego.ObjectStorageBucket, error) {
bucket, err := bScope.LinodeClient.GetObjectStorageBucket(
ctx,
bScope.Bucket.Spec.Cluster,
bScope.Bucket.Name,
)
if util.IgnoreLinodeAPIError(err, http.StatusNotFound) != nil {
return nil, fmt.Errorf("failed to get bucket from cluster %s: %w", bScope.Bucket.Spec.Cluster, err)
}
if bucket != nil {
bScope.Logger.Info("Bucket exists")
return bucket, nil
}
opts := linodego.ObjectStorageBucketCreateOptions{
Cluster: bScope.Bucket.Spec.Cluster,
Label: bScope.Bucket.Name,
ACL: linodego.ACLPrivate,
}
if bucket, err = bScope.LinodeClient.CreateObjectStorageBucket(ctx, opts); err != nil {
return nil, fmt.Errorf("failed to create bucket: %w", err)
}
bScope.Logger.Info("Created bucket")
return bucket, nil
}
func RotateObjectStorageKeys(ctx context.Context, bScope *scope.ObjectStorageBucketScope) ([scope.NumAccessKeys]*linodego.ObjectStorageKey, error) {
var newKeys [scope.NumAccessKeys]*linodego.ObjectStorageKey
for idx, permission := range []struct {
name string
suffix string
}{
{"read_write", "rw"},
{"read_only", "ro"},
} {
keyLabel := fmt.Sprintf("%s-%s", bScope.Bucket.Name, permission.suffix)
key, err := createObjectStorageKey(ctx, bScope, keyLabel, permission.name)
if err != nil {
return newKeys, err
}
newKeys[idx] = key
}
// If key revocation fails here, just log the errors since new keys have been created
if !bScope.ShouldInitKeys() && bScope.ShouldRotateKeys() {
if err := RevokeObjectStorageKeys(ctx, bScope); err != nil {
bScope.Logger.Error(err, "Failed to revoke access keys; keys must be manually revoked")
}
}
return newKeys, nil
}
func createObjectStorageKey(ctx context.Context, bScope *scope.ObjectStorageBucketScope, label, permission string) (*linodego.ObjectStorageKey, error) {
opts := linodego.ObjectStorageKeyCreateOptions{
Label: label,
BucketAccess: &[]linodego.ObjectStorageKeyBucketAccess{
{
BucketName: bScope.Bucket.Name,
Cluster: bScope.Bucket.Spec.Cluster,
Permissions: permission,
},
},
}
key, err := bScope.LinodeClient.CreateObjectStorageKey(ctx, opts)
if err != nil {
bScope.Logger.Error(err, "Failed to create access key", "label", label)
return nil, fmt.Errorf("failed to create access key: %w", err)
}
bScope.Logger.Info("Created access key", "id", key.ID)
return key, nil
}
func RevokeObjectStorageKeys(ctx context.Context, bScope *scope.ObjectStorageBucketScope) error {
var errs []error
for _, keyID := range bScope.Bucket.Status.AccessKeyRefs {
if err := revokeObjectStorageKey(ctx, bScope, keyID); err != nil {
errs = append(errs, err)
}
}
return utilerrors.NewAggregate(errs)
}
func revokeObjectStorageKey(ctx context.Context, bScope *scope.ObjectStorageBucketScope, keyID int) error {
err := bScope.LinodeClient.DeleteObjectStorageKey(ctx, keyID)
if util.IgnoreLinodeAPIError(err, http.StatusNotFound) != nil {
bScope.Logger.Error(err, "Failed to revoke access key", "id", keyID)
return fmt.Errorf("failed to revoke access key: %w", err)
}
bScope.Logger.Info("Revoked access key", "id", keyID)
return nil
}
func GetObjectStorageKeys(ctx context.Context, bScope *scope.ObjectStorageBucketScope) ([2]*linodego.ObjectStorageKey, error) {
var keys [2]*linodego.ObjectStorageKey
if len(bScope.Bucket.Status.AccessKeyRefs) != scope.NumAccessKeys {
return keys, errors.New("expected two object storage key IDs in .status.accessKeyRefs")
}
var errs []error
for idx, keyID := range bScope.Bucket.Status.AccessKeyRefs {
key, err := bScope.LinodeClient.GetObjectStorageKey(ctx, keyID)
if err != nil {
errs = append(errs, err)
continue
}
keys[idx] = key
}
return keys, utilerrors.NewAggregate(errs)
}