Skip to content
This repository was archived by the owner on Jun 23, 2020. It is now read-only.

Commit faf1247

Browse files
Added support for export deletion
-Retrieve pirvate ip for mount target and fixed system tests -Ignore linting mock_interfaces -Fix for config file for creating rc with volume claim
1 parent b85fd87 commit faf1247

File tree

9 files changed

+385
-199
lines changed

9 files changed

+385
-199
lines changed

examples/example-pod-fss.template

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: demooci-fss-pod-{{TEST_ID}}
5+
labels:
6+
name: demooci-fss-pod-{{TEST_ID}}
7+
spec:
8+
containers:
9+
- name: demooci-fss-pod-{{TEST_ID}}
10+
image: fedora/nginx
11+
ports:
12+
- name: web
13+
containerPort: 80
14+
volumeMounts:
15+
- name: nginx
16+
mountPath: /usr/share/nginx/html
17+
volumes:
18+
- name: nginx
19+
persistentVolumeClaim:
20+
claimName: demooci-fss-{{TEST_ID}}

hack/check-golint.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ set -o nounset
2121
set -o pipefail
2222

2323
TARGETS=$(for d in "$@"; do echo ./$d/...; done)
24-
2524
echo -n "Checking golint: "
26-
ERRS=$(golint ${TARGETS} 2>&1 || true)
25+
ERRS=$(golint ${TARGETS} | grep -v mock_interfaces.go 2>&1 || true)
2726
if [ -n "${ERRS}" ]; then
2827
echo "FAIL"
2928
echo "${ERRS}"

pkg/helpers/mock_interfaces.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ var (
2929
// VolumeBackupID of backup volume
3030
VolumeBackupID = "dummyVolumeBackupId"
3131
fileSystemID = "dummyFileSystemId"
32+
exportID = "dummyExportID"
33+
serverIPs = []string{"dummyServerIP"}
34+
privateIP = "127.0.0.1"
3235
)
3336

3437
// MockBlockStorageClient mocks BlockStorage client implementation
@@ -66,12 +69,17 @@ func (c *MockFileStorageClient) DeleteFileSystem(ctx context.Context, request fi
6669

6770
// CreateExport mocks the FileStorage CreateExport implementation
6871
func (c *MockFileStorageClient) CreateExport(ctx context.Context, request filestorage.CreateExportRequest) (response filestorage.CreateExportResponse, err error) {
69-
return filestorage.CreateExportResponse{}, nil
72+
return filestorage.CreateExportResponse{Export: filestorage.Export{Id: common.String(exportID)}}, nil
73+
}
74+
75+
// DeleteExport mocks the FileStorage DeleteExport implementation
76+
func (c *MockFileStorageClient) DeleteExport(ctx context.Context, request filestorage.DeleteExportRequest) (response filestorage.DeleteExportResponse, err error) {
77+
return filestorage.DeleteExportResponse{}, nil
7078
}
7179

7280
// CreateMountTarget mocks the FileStorage CreateMountTarget implementation
7381
func (c *MockFileStorageClient) CreateMountTarget(ctx context.Context, request filestorage.CreateMountTargetRequest) (response filestorage.CreateMountTargetResponse, err error) {
74-
return filestorage.CreateMountTargetResponse{}, nil
82+
return filestorage.CreateMountTargetResponse{MountTarget: filestorage.MountTarget{PrivateIpIds: serverIPs}}, nil
7583
}
7684

7785
// GetMountTarget mocks the FileStorage GetMountTarget implementation
@@ -84,6 +92,15 @@ func (c *MockFileStorageClient) ListMountTargets(ctx context.Context, request fi
8492
return filestorage.ListMountTargetsResponse{}, nil
8593
}
8694

95+
// MockVirtualNetworkClient mocks VirtualNetwork client implementation
96+
type MockVirtualNetworkClient struct {
97+
}
98+
99+
// GetPrivateIp mocks the VirtualNetwork GetPrivateIp implementation
100+
func (c *MockVirtualNetworkClient) GetPrivateIp(ctx context.Context, request core.GetPrivateIpRequest) (response core.GetPrivateIpResponse, err error) {
101+
return core.GetPrivateIpResponse{PrivateIp: core.PrivateIp{IpAddress: common.String(privateIP)}}, nil
102+
}
103+
87104
// MockIdentityClient mocks identity client structure
88105
type MockIdentityClient struct {
89106
common.BaseClient
@@ -108,6 +125,11 @@ func (p *MockProvisionerClient) FileStorage() client.FileStorage {
108125
return &MockFileStorageClient{}
109126
}
110127

128+
// VirtualNetwork mocks client VirtualNetwork implementation
129+
func (p *MockProvisionerClient) VirtualNetwork() client.VirtualNetwork {
130+
return &MockVirtualNetworkClient{}
131+
}
132+
111133
// Identity mocks client Identity implementation
112134
func (p *MockProvisionerClient) Identity() client.Identity {
113135
return &MockIdentityClient{}

pkg/oci/client/client.go

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,14 @@ import (
4040

4141
// ProvisionerClient wraps the OCI sub-clients required for volume provisioning.
4242
type provisionerClient struct {
43-
cfg *Config
44-
blockStorage *core.BlockstorageClient
45-
identity *identity.IdentityClient
46-
fileStorage *filestorage.FileStorageClient
47-
context context.Context
48-
timeout time.Duration
49-
metadata *instancemeta.InstanceMetadata
43+
cfg *Config
44+
blockStorage *core.BlockstorageClient
45+
identity *identity.IdentityClient
46+
fileStorage *filestorage.FileStorageClient
47+
virtualNetwork *core.VirtualNetworkClient
48+
context context.Context
49+
timeout time.Duration
50+
metadata *instancemeta.InstanceMetadata
5051
}
5152

5253
// BlockStorage specifies the subset of the OCI core API utilised by the provisioner.
@@ -67,15 +68,22 @@ type FileStorage interface {
6768
DeleteFileSystem(ctx context.Context, request filestorage.DeleteFileSystemRequest) (response filestorage.DeleteFileSystemResponse, err error)
6869
CreateMountTarget(ctx context.Context, request filestorage.CreateMountTargetRequest) (response filestorage.CreateMountTargetResponse, err error)
6970
CreateExport(ctx context.Context, request filestorage.CreateExportRequest) (response filestorage.CreateExportResponse, err error)
71+
DeleteExport(ctx context.Context, request filestorage.DeleteExportRequest) (response filestorage.DeleteExportResponse, err error)
7072
GetMountTarget(ctx context.Context, request filestorage.GetMountTargetRequest) (response filestorage.GetMountTargetResponse, err error)
7173
ListMountTargets(ctx context.Context, request filestorage.ListMountTargetsRequest) (response filestorage.ListMountTargetsResponse, err error)
7274
}
7375

76+
//VirtualNetwork specifies the subset of the OCI core API utilised by the provisioner.
77+
type VirtualNetwork interface {
78+
GetPrivateIp(ctx context.Context, request core.GetPrivateIpRequest) (response core.GetPrivateIpResponse, err error)
79+
}
80+
7481
// ProvisionerClient is passed to all sub clients to provision a volume
7582
type ProvisionerClient interface {
7683
BlockStorage() BlockStorage
7784
Identity() Identity
7885
FileStorage() FileStorage
86+
VirtualNetwork() VirtualNetwork
7987
Context() context.Context
8088
Timeout() time.Duration
8189
CompartmentOCID() string
@@ -94,6 +102,10 @@ func (p *provisionerClient) FileStorage() FileStorage {
94102
return p.fileStorage
95103
}
96104

105+
func (p *provisionerClient) VirtualNetwork() VirtualNetwork {
106+
return p.virtualNetwork
107+
}
108+
97109
func (p *provisionerClient) Context() context.Context {
98110
return p.context
99111
}
@@ -141,6 +153,11 @@ func FromConfig(cfg *Config) (ProvisionerClient, error) {
141153
return nil, err
142154
}
143155

156+
virtualNetwork, err := core.NewVirtualNetworkClientWithConfigurationProvider(config)
157+
if err != nil {
158+
return nil, err
159+
}
160+
144161
identity, err := identity.NewIdentityClientWithConfigurationProvider(config)
145162
if err != nil {
146163
return nil, err
@@ -156,13 +173,14 @@ func FromConfig(cfg *Config) (ProvisionerClient, error) {
156173
}
157174

158175
return &provisionerClient{
159-
cfg: cfg,
160-
blockStorage: &blockStorage,
161-
identity: &identity,
162-
fileStorage: &fileStorage,
163-
timeout: 3 * time.Minute,
164-
context: context.Background(),
165-
metadata: metadata,
176+
cfg: cfg,
177+
blockStorage: &blockStorage,
178+
identity: &identity,
179+
fileStorage: &fileStorage,
180+
virtualNetwork: &virtualNetwork,
181+
timeout: 3 * time.Minute,
182+
context: context.Background(),
183+
metadata: metadata,
166184
}, nil
167185
}
168186

pkg/provisioner/filestorage/filestorage.go

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/golang/glog"
2626
"github.com/kubernetes-incubator/external-storage/lib/controller"
2727
"github.com/oracle/oci-go-sdk/common"
28+
"github.com/oracle/oci-go-sdk/core"
2829
"github.com/oracle/oci-go-sdk/filestorage"
2930
"github.com/oracle/oci-go-sdk/identity"
3031
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -36,6 +37,7 @@ import (
3637

3738
const (
3839
ociVolumeID = "ociVolumeID"
40+
ociExportID = "ociExportID"
3941
volumePrefixEnvVarName = "OCI_VOLUME_NAME_PREFIX"
4042
fsType = "fsType"
4143
subnetID = "subnetId"
@@ -128,28 +130,42 @@ func (filesystem *filesystemProvisioner) Provision(
128130
}
129131

130132
glog.Infof("Creating export set")
131-
_, err = fileStorageClient.CreateExport(ctx, filestorage.CreateExportRequest{
133+
createExportResponse, err := fileStorageClient.CreateExport(ctx, filestorage.CreateExportRequest{
132134
CreateExportDetails: filestorage.CreateExportDetails{
133135
ExportSetId: mntTargetResp.ExportSetId,
134136
FileSystemId: response.FileSystem.Id,
135-
Path: common.String("/"),
137+
Path: common.String("/" + *response.FileSystem.Id),
136138
},
137139
})
138140

139141
if err != nil {
140142
glog.Errorf("Failed to create export:%s", err)
141143
return nil, err
142144
}
143-
mntTargetSubnetIDPtr := ""
144-
if mntTargetResp.SubnetId != nil {
145-
mntTargetSubnetIDPtr = *mntTargetResp.SubnetId
145+
serverIP := ""
146+
if len(mntTargetResp.PrivateIpIds) != 0 {
147+
privateIPID := mntTargetResp.PrivateIpIds[rand.Int()%len(mntTargetResp.PrivateIpIds)]
148+
virtualNetworkClient := filesystem.client.VirtualNetwork()
149+
getPrivateIPResponse, err := virtualNetworkClient.GetPrivateIp(ctx, core.GetPrivateIpRequest{
150+
PrivateIpId: common.String(privateIPID),
151+
})
152+
if err != nil {
153+
glog.Errorf("Failed to retrieve IP address for mount target:%s", err)
154+
return nil, err
155+
}
156+
serverIP = *getPrivateIPResponse.PrivateIp.IpAddress
157+
} else {
158+
glog.Errorf("Failed to find server IDs associated with the mount target to provision a persistent volume")
159+
return nil, fmt.Errorf("Failed to find server IDs associated with the mount target")
146160
}
147-
glog.Infof("Creating persistent volume")
161+
162+
glog.Infof("Creating persistent volume on mount target with private IP address %s", serverIP)
148163
return &v1.PersistentVolume{
149164
ObjectMeta: metav1.ObjectMeta{
150165
Name: *response.FileSystem.Id,
151166
Annotations: map[string]string{
152167
ociVolumeID: *response.FileSystem.Id,
168+
ociExportID: *createExportResponse.Export.Id,
153169
},
154170
Labels: map[string]string{},
155171
},
@@ -162,8 +178,9 @@ func (filesystem *filesystemProvisioner) Provision(
162178
},
163179
PersistentVolumeSource: v1.PersistentVolumeSource{
164180
NFS: &v1.NFSVolumeSource{
165-
Server: mntTargetSubnetIDPtr,
166-
Path: "/",
181+
// Randomnly select IP address associated with the mount target to use for attachment
182+
Server: serverIP,
183+
Path: *common.String("/" + *response.FileSystem.Id),
167184
ReadOnly: false,
168185
},
169186
},
@@ -173,14 +190,27 @@ func (filesystem *filesystemProvisioner) Provision(
173190

174191
// Delete destroys a OCI volume created by Provision
175192
func (filesystem *filesystemProvisioner) Delete(volume *v1.PersistentVolume) error {
193+
exportID, ok := volume.Annotations[ociExportID]
194+
if !ok {
195+
return errors.New("Export ID annotation not found on PV")
196+
}
176197
filesystemID, ok := volume.Annotations[ociVolumeID]
177198
if !ok {
178-
return errors.New("filesystemid annotation not found on PV")
199+
return errors.New("Filesystem ID annotation not found on PV")
179200
}
180-
glog.Infof("Deleting volume %v with filesystemID %v", volume, filesystemID)
181201
ctx, cancel := context.WithTimeout(filesystem.client.Context(), filesystem.client.Timeout())
182202
defer cancel()
183-
_, err := filesystem.client.FileStorage().DeleteFileSystem(ctx,
203+
glog.Infof("Deleting export for filesystemID %v", filesystemID)
204+
_, err := filesystem.client.FileStorage().DeleteExport(ctx,
205+
filestorage.DeleteExportRequest{
206+
ExportId: &exportID,
207+
})
208+
if err != nil {
209+
glog.Errorf("Failed to delete export:%s, %s", exportID, err)
210+
return err
211+
}
212+
glog.Infof("Deleting volume %v with filesystemID %v", volume, filesystemID)
213+
_, err = filesystem.client.FileStorage().DeleteFileSystem(ctx,
184214
filestorage.DeleteFileSystemRequest{
185215
FileSystemId: &filesystemID,
186216
})

0 commit comments

Comments
 (0)