/
import.go
125 lines (103 loc) · 4.03 KB
/
import.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
// Copyright 2019 NetApp, Inc. All Rights Reserved.
package kubernetes
import (
"encoding/base64"
"encoding/json"
"fmt"
"strconv"
"github.com/netapp/trident/storage"
log "github.com/sirupsen/logrus"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"github.com/netapp/trident/frontend/csi"
)
/////////////////////////////////////////////////////////////////////////////
//
// This file contains the event handlers that import existing volumes from backends.
//
/////////////////////////////////////////////////////////////////////////////
func (p *Plugin) ImportVolume(request *storage.ImportVolumeRequest) (*storage.VolumeExternal, error) {
log.WithField("request", request).Debug("ImportVolume")
// Get PVC from ImportVolumeRequest
jsonData, err := base64.StdEncoding.DecodeString(request.PVCData)
if err != nil {
return nil, fmt.Errorf("the pvcData field does not contain valid base64-encoded data: %v", err)
}
claim := &v1.PersistentVolumeClaim{}
err = json.Unmarshal(jsonData, &claim)
if err != nil {
return nil, fmt.Errorf("could not parse JSON PVC: %v", err)
}
log.WithFields(log.Fields{
"PVC": claim.Name,
"PVC_storageClass": getStorageClassForPVC(claim),
"PVC_accessModes": claim.Spec.AccessModes,
"PVC_annotations": claim.Annotations,
"PVC_volume": claim.Spec.VolumeName,
"PVC_requestedSize": claim.Spec.Resources.Requests[v1.ResourceStorage],
}).Debug("ImportVolume: received PVC data.")
if err = p.checkValidStorageClassReceived(claim); err != nil {
return nil, err
}
if len(claim.Namespace) == 0 {
return nil, fmt.Errorf("a valid PVC namespace is required for volume import")
}
// Lookup backend ID from given name
backend, err := p.orchestrator.GetBackend(request.Backend)
if err != nil {
return nil, fmt.Errorf("could not find backend %s; %v", request.Backend, err)
}
// Set required annotations
if claim.Annotations == nil {
claim.Annotations = map[string]string{}
}
claim.Annotations[AnnNotManaged] = strconv.FormatBool(request.NoManage)
claim.Annotations[AnnImportOriginalName] = request.InternalName
claim.Annotations[AnnImportBackendUUID] = backend.BackendUUID
claim.Annotations[AnnStorageProvisioner] = csi.Provisioner
// Set the PVC's storage field to the actual volume size.
volExternal, err := p.orchestrator.GetVolumeExternal(request.InternalName, request.Backend)
if err != nil {
return nil, fmt.Errorf("volume import failed to get size of volume: %v", err)
}
if claim.Spec.Resources.Requests == nil {
claim.Spec.Resources.Requests = v1.ResourceList{}
}
claim.Spec.Resources.Requests[v1.ResourceStorage] = resource.MustParse(volExternal.Config.Size)
log.WithFields(log.Fields{
"size": volExternal.Config.Size,
"claimSize": claim.Spec.Resources.Requests[v1.ResourceStorage],
}).Debug("Volume import determined volume size")
pvc, pvcErr := p.createImportPVC(claim)
if pvcErr != nil {
log.WithFields(log.Fields{
"claim": claim.Name,
"error": pvcErr,
}).Warn("ImportVolume: error occurred during PVC creation.")
return nil, pvcErr
}
log.WithField("PVC", pvc).Debug("ImportVolume: created pending PVC.")
pvName := fmt.Sprintf("pvc-%s", pvc.GetUID())
// Wait for the import to happen and the PV to be created by the sidecar
// after which we can then request the volume object from the core to return
_, err = p.waitForCachedPVByName(pvName, ImportPVCacheWaitPeriod)
if err != nil {
return nil, fmt.Errorf("error waiting for PV %s; %v", pvName, err)
}
volume, err := p.orchestrator.GetVolume(pvName)
if err != nil {
return nil, fmt.Errorf("error getting volume %s; %v", pvName, err)
}
return volume, nil
}
func (p *Plugin) createImportPVC(claim *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) {
log.WithFields(log.Fields{
"claim": claim,
"namespace": claim.Namespace,
}).Debug("CreateImportPVC: ready to create PVC")
pvc, err := p.kubeClient.CoreV1().PersistentVolumeClaims(claim.Namespace).Create(claim)
if err != nil {
return nil, fmt.Errorf("error occurred during PVC creation: %v", err)
}
return pvc, nil
}