Skip to content

Commit 2c90111

Browse files
committed
Refactor utils to common, added metadata service
1 parent bf52c2b commit 2c90111

File tree

7 files changed

+695
-0
lines changed

7 files changed

+695
-0
lines changed

pkg/common/constants.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package common
18+
19+
const (
20+
// Keys for Storage Class Parameters
21+
ParameterKeyZone = "zone"
22+
ParameterKeyType = "type"
23+
24+
// Keys for Topology
25+
TopologyKeyZone = "com.google.gcp-compute-persistent-disk-csi-driver.topology/zone"
26+
)

pkg/common/utils.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package common
18+
19+
import (
20+
"fmt"
21+
"strings"
22+
)
23+
24+
func BytesToGb(bytes int64) int64 {
25+
// TODO: Throw an error when div to 0
26+
return bytes / (1024 * 1024 * 1024)
27+
}
28+
29+
func GbToBytes(Gb int64) int64 {
30+
// TODO: Check for overflow
31+
return Gb * 1024 * 1024 * 1024
32+
}
33+
34+
func SplitZoneNameId(id string) (string, string, error) {
35+
splitId := strings.Split(id, "/")
36+
if len(splitId) != 2 {
37+
return "", "", fmt.Errorf("Failed to get id components. Expected {zone}/{name}. Got: %s", id)
38+
}
39+
return splitId[0], splitId[1], nil
40+
}
41+
42+
func CombineVolumeId(zone, name string) string {
43+
return fmt.Sprintf("%s/%s", zone, name)
44+
}
+193
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
*/
14+
15+
package gcecloudprovider
16+
17+
import (
18+
"fmt"
19+
"strings"
20+
21+
"github.com/golang/glog"
22+
"golang.org/x/net/context"
23+
compute "google.golang.org/api/compute/v1"
24+
"google.golang.org/api/googleapi"
25+
"google.golang.org/grpc/codes"
26+
"google.golang.org/grpc/status"
27+
"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/common"
28+
)
29+
30+
type FakeCloudProvider struct {
31+
project string
32+
zone string
33+
34+
disks map[string]*compute.Disk
35+
instances map[string]*compute.Instance
36+
}
37+
38+
var _ GCECompute = &FakeCloudProvider{}
39+
40+
func FakeCreateCloudProvider(project, zone string) (*FakeCloudProvider, error) {
41+
return &FakeCloudProvider{
42+
project: project,
43+
zone: zone,
44+
disks: map[string]*compute.Disk{},
45+
instances: map[string]*compute.Instance{},
46+
}, nil
47+
48+
}
49+
50+
// Getters
51+
func (cloud *FakeCloudProvider) GetProject() string {
52+
return cloud.project
53+
}
54+
func (cloud *FakeCloudProvider) GetZone() string {
55+
return cloud.zone
56+
}
57+
58+
// Disk Methods
59+
func (cloud *FakeCloudProvider) GetDiskOrError(ctx context.Context, volumeZone, volumeName string) (*compute.Disk, error) {
60+
disk, ok := cloud.disks[volumeName]
61+
if !ok {
62+
return nil, notFoundError()
63+
}
64+
return disk, nil
65+
}
66+
67+
func (cloud *FakeCloudProvider) GetAndValidateExistingDisk(ctx context.Context, configuredZone, name, diskType string, reqBytes, limBytes int64) (exists bool, err error) {
68+
disk, ok := cloud.disks[name]
69+
if !ok {
70+
// Disk doesn't exist
71+
return false, nil
72+
}
73+
if disk != nil {
74+
// Check that disk is the same
75+
requestValid := common.GbToBytes(disk.SizeGb) >= reqBytes || reqBytes == 0
76+
responseValid := common.GbToBytes(disk.SizeGb) <= limBytes || limBytes == 0
77+
if !requestValid || !responseValid {
78+
return true, status.Error(codes.AlreadyExists, fmt.Sprintf(
79+
"Disk already exists with incompatible capacity. Need %v (Required) < %v (Existing) < %v (Limit)",
80+
reqBytes, common.GbToBytes(disk.SizeGb), limBytes))
81+
}
82+
83+
respType := strings.Split(disk.Type, "/")
84+
typeMatch := respType[len(respType)-1] != diskType
85+
typeDefault := diskType == "" && respType[len(respType)-1] == "pd-standard"
86+
if !typeMatch && !typeDefault {
87+
return true, status.Error(codes.AlreadyExists, fmt.Sprintf(
88+
"Disk already exists with incompatible type. Need %v. Got %v",
89+
diskType, respType[len(respType)-1]))
90+
}
91+
92+
// Volume exists with matching name, capacity, type.
93+
glog.Infof("Compatible disk already exists. Reusing existing.")
94+
return true, nil
95+
}
96+
97+
return false, nil
98+
}
99+
100+
func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, zone string, diskToCreate *compute.Disk) (*compute.Operation, error) {
101+
cloud.disks[diskToCreate.Name] = diskToCreate
102+
return &compute.Operation{}, nil
103+
}
104+
105+
func (cloud *FakeCloudProvider) DeleteDisk(ctx context.Context, zone, name string) (*compute.Operation, error) {
106+
delete(cloud.disks, name)
107+
return &compute.Operation{}, nil
108+
}
109+
110+
func (cloud *FakeCloudProvider) AttachDisk(ctx context.Context, zone, instanceName string, attachedDisk *compute.AttachedDisk) (*compute.Operation, error) {
111+
instance, ok := cloud.instances[instanceName]
112+
if !ok {
113+
return nil, fmt.Errorf("Failed to get instance %v", instanceName)
114+
}
115+
instance.Disks = append(instance.Disks, attachedDisk)
116+
return nil, nil
117+
}
118+
119+
func (cloud *FakeCloudProvider) DetachDisk(ctx context.Context, volumeZone, instanceName, volumeName string) (*compute.Operation, error) {
120+
instance, ok := cloud.instances[instanceName]
121+
if !ok {
122+
return nil, fmt.Errorf("Failed to get instance %v", instanceName)
123+
}
124+
found := -1
125+
for i, disk := range instance.Disks {
126+
if disk.DeviceName == volumeName {
127+
found = i
128+
break
129+
}
130+
}
131+
instance.Disks[found] = instance.Disks[len(instance.Disks)-1]
132+
instance.Disks = instance.Disks[:len(instance.Disks)-1]
133+
return nil, nil
134+
}
135+
136+
/*
137+
func (cloud *CloudProvider) GetDiskSourceURI(disk *compute.Disk, zone string) string {
138+
projectsApiEndpoint := gceComputeAPIEndpoint + "projects/"
139+
if cloud.service != nil {
140+
projectsApiEndpoint = cloud.service.BasePath
141+
}
142+
143+
return projectsApiEndpoint + fmt.Sprintf(
144+
diskSourceURITemplateSingleZone,
145+
cloud.project,
146+
zone,
147+
disk.Name)
148+
}
149+
150+
func (cloud *CloudProvider) GetDiskTypeURI(zone, diskType string) string {
151+
return fmt.Sprintf(diskTypeURITemplateSingleZone, cloud.project, zone, diskType)
152+
}
153+
*/
154+
func (cloud *FakeCloudProvider) GetDiskSourceURI(disk *compute.Disk, zone string) string {
155+
return ""
156+
}
157+
158+
func (cloud *FakeCloudProvider) GetDiskTypeURI(zone, diskType string) string {
159+
return ""
160+
}
161+
162+
func (cloud *FakeCloudProvider) WaitForAttach(ctx context.Context, zone, diskName, instanceName string) error {
163+
return nil
164+
}
165+
166+
// Instance Methods
167+
func (cloud *FakeCloudProvider) InsertInstance(instance *compute.Instance, instanceName string) {
168+
cloud.instances[instanceName] = instance
169+
return
170+
}
171+
172+
func (cloud *FakeCloudProvider) GetInstanceOrError(ctx context.Context, instanceZone, instanceName string) (*compute.Instance, error) {
173+
instance, ok := cloud.instances[instanceName]
174+
if !ok {
175+
return nil, notFoundError()
176+
}
177+
return instance, nil
178+
}
179+
180+
// Operation Methods
181+
func (cloud *FakeCloudProvider) WaitForOp(ctx context.Context, op *compute.Operation, zone string) error {
182+
return nil
183+
}
184+
185+
func notFoundError() *googleapi.Error {
186+
return &googleapi.Error{
187+
Errors: []googleapi.ErrorItem{
188+
{
189+
Reason: "notFound",
190+
},
191+
},
192+
}
193+
}

0 commit comments

Comments
 (0)