Merge branch 'master' into status-52
This commit is contained in:
2
Gopkg.lock
generated
2
Gopkg.lock
generated
@@ -62,7 +62,6 @@
|
|||||||
"ptypes",
|
"ptypes",
|
||||||
"ptypes/any",
|
"ptypes/any",
|
||||||
"ptypes/duration",
|
"ptypes/duration",
|
||||||
"ptypes/timestamp",
|
|
||||||
"ptypes/wrappers",
|
"ptypes/wrappers",
|
||||||
]
|
]
|
||||||
pruneopts = "NUT"
|
pruneopts = "NUT"
|
||||||
@@ -754,7 +753,6 @@
|
|||||||
"github.com/container-storage-interface/spec/lib/go/csi",
|
"github.com/container-storage-interface/spec/lib/go/csi",
|
||||||
"github.com/golang/mock/gomock",
|
"github.com/golang/mock/gomock",
|
||||||
"github.com/golang/protobuf/ptypes",
|
"github.com/golang/protobuf/ptypes",
|
||||||
"github.com/golang/protobuf/ptypes/timestamp",
|
|
||||||
"github.com/kubernetes-csi/csi-lib-utils/connection",
|
"github.com/kubernetes-csi/csi-lib-utils/connection",
|
||||||
"github.com/kubernetes-csi/csi-lib-utils/leaderelection",
|
"github.com/kubernetes-csi/csi-lib-utils/leaderelection",
|
||||||
"github.com/kubernetes-csi/csi-lib-utils/rpc",
|
"github.com/kubernetes-csi/csi-lib-utils/rpc",
|
||||||
|
@@ -66,7 +66,7 @@ var (
|
|||||||
snapshotNamePrefix = flag.String("snapshot-name-prefix", "snapshot", "Prefix to apply to the name of a created snapshot")
|
snapshotNamePrefix = flag.String("snapshot-name-prefix", "snapshot", "Prefix to apply to the name of a created snapshot")
|
||||||
snapshotNameUUIDLength = flag.Int("snapshot-name-uuid-length", -1, "Length in characters for the generated uuid of a created snapshot. Defaults behavior is to NOT truncate.")
|
snapshotNameUUIDLength = flag.Int("snapshot-name-uuid-length", -1, "Length in characters for the generated uuid of a created snapshot. Defaults behavior is to NOT truncate.")
|
||||||
showVersion = flag.Bool("version", false, "Show version.")
|
showVersion = flag.Bool("version", false, "Show version.")
|
||||||
csiTimeout = flag.Duration("timeout", defaultCSITimeout, "The timeout for any RPCs to the CSI driver. Default is 10s.")
|
csiTimeout = flag.Duration("timeout", defaultCSITimeout, "The timeout for any RPCs to the CSI driver. Default is 1 minute.")
|
||||||
|
|
||||||
leaderElection = flag.Bool("leader-election", false, "Enables leader election.")
|
leaderElection = flag.Bool("leader-election", false, "Enables leader election.")
|
||||||
leaderElectionNamespace = flag.String("leader-election-namespace", "", "The namespace where the leader election resource exists. Defaults to the pod namespace if not set.")
|
leaderElectionNamespace = flag.String("leader-election-namespace", "", "The namespace where the leader election resource exists. Defaults to the pod namespace if not set.")
|
||||||
@@ -184,9 +184,9 @@ func main() {
|
|||||||
snapClient,
|
snapClient,
|
||||||
kubeClient,
|
kubeClient,
|
||||||
*snapshotterName,
|
*snapshotterName,
|
||||||
factory.Volumesnapshot().V1alpha1().VolumeSnapshots(),
|
factory.Snapshot().V1alpha1().VolumeSnapshots(),
|
||||||
factory.Volumesnapshot().V1alpha1().VolumeSnapshotContents(),
|
factory.Snapshot().V1alpha1().VolumeSnapshotContents(),
|
||||||
factory.Volumesnapshot().V1alpha1().VolumeSnapshotClasses(),
|
factory.Snapshot().V1alpha1().VolumeSnapshotClasses(),
|
||||||
coreFactory.Core().V1().PersistentVolumeClaims(),
|
coreFactory.Core().V1().PersistentVolumeClaims(),
|
||||||
*createSnapshotContentRetryCount,
|
*createSnapshotContentRetryCount,
|
||||||
*createSnapshotContentInterval,
|
*createSnapshotContentInterval,
|
||||||
|
@@ -25,7 +25,7 @@ rules:
|
|||||||
verbs: ["get", "list", "watch"]
|
verbs: ["get", "list", "watch"]
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["persistentvolumeclaims"]
|
resources: ["persistentvolumeclaims"]
|
||||||
verbs: ["get", "list", "watch"]
|
verbs: ["get", "list", "watch", "update"]
|
||||||
- apiGroups: ["storage.k8s.io"]
|
- apiGroups: ["storage.k8s.io"]
|
||||||
resources: ["storageclasses"]
|
resources: ["storageclasses"]
|
||||||
verbs: ["get", "list", "watch"]
|
verbs: ["get", "list", "watch"]
|
||||||
|
@@ -72,7 +72,7 @@ spec:
|
|||||||
serviceAccount: csi-snapshotter
|
serviceAccount: csi-snapshotter
|
||||||
containers:
|
containers:
|
||||||
- name: csi-provisioner
|
- name: csi-provisioner
|
||||||
image: quay.io/k8scsi/csi-provisioner:v1.0.1
|
image: quay.io/k8scsi/csi-provisioner:v1.1.0
|
||||||
args:
|
args:
|
||||||
- "--provisioner=csi-hostpath"
|
- "--provisioner=csi-hostpath"
|
||||||
- "--csi-address=$(ADDRESS)"
|
- "--csi-address=$(ADDRESS)"
|
||||||
@@ -85,7 +85,7 @@ spec:
|
|||||||
- name: socket-dir
|
- name: socket-dir
|
||||||
mountPath: /csi
|
mountPath: /csi
|
||||||
- name: csi-snapshotter
|
- name: csi-snapshotter
|
||||||
image: quay.io/k8scsi/csi-snapshotter:v1.0.1
|
image: quay.io/k8scsi/csi-snapshotter:v1.1.0
|
||||||
args:
|
args:
|
||||||
- "--csi-address=$(ADDRESS)"
|
- "--csi-address=$(ADDRESS)"
|
||||||
- "--connection-timeout=15s"
|
- "--connection-timeout=15s"
|
||||||
@@ -98,7 +98,7 @@ spec:
|
|||||||
- name: socket-dir
|
- name: socket-dir
|
||||||
mountPath: /csi
|
mountPath: /csi
|
||||||
- name: hostpath
|
- name: hostpath
|
||||||
image: quay.io/k8scsi/hostpathplugin:v1.0.1
|
image: quay.io/k8scsi/hostpathplugin:v1.1.0
|
||||||
args:
|
args:
|
||||||
- "--v=5"
|
- "--v=5"
|
||||||
- "--endpoint=$(CSI_ENDPOINT)"
|
- "--endpoint=$(CSI_ENDPOINT)"
|
||||||
|
@@ -15,5 +15,6 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=package
|
// +k8s:deepcopy-gen=package
|
||||||
|
// +groupName=snapshot.storage.k8s.io
|
||||||
|
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// +build !ignore_autogenerated
|
// +build !ignore_autogenerated
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +19,7 @@ limitations under the License.
|
|||||||
package versioned
|
package versioned
|
||||||
|
|
||||||
import (
|
import (
|
||||||
volumesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1"
|
snapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1"
|
||||||
discovery "k8s.io/client-go/discovery"
|
discovery "k8s.io/client-go/discovery"
|
||||||
rest "k8s.io/client-go/rest"
|
rest "k8s.io/client-go/rest"
|
||||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||||
@@ -27,27 +27,19 @@ import (
|
|||||||
|
|
||||||
type Interface interface {
|
type Interface interface {
|
||||||
Discovery() discovery.DiscoveryInterface
|
Discovery() discovery.DiscoveryInterface
|
||||||
VolumesnapshotV1alpha1() volumesnapshotv1alpha1.VolumesnapshotV1alpha1Interface
|
SnapshotV1alpha1() snapshotv1alpha1.SnapshotV1alpha1Interface
|
||||||
// Deprecated: please explicitly pick a version if possible.
|
|
||||||
Volumesnapshot() volumesnapshotv1alpha1.VolumesnapshotV1alpha1Interface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clientset contains the clients for groups. Each group has exactly one
|
// Clientset contains the clients for groups. Each group has exactly one
|
||||||
// version included in a Clientset.
|
// version included in a Clientset.
|
||||||
type Clientset struct {
|
type Clientset struct {
|
||||||
*discovery.DiscoveryClient
|
*discovery.DiscoveryClient
|
||||||
volumesnapshotV1alpha1 *volumesnapshotv1alpha1.VolumesnapshotV1alpha1Client
|
snapshotV1alpha1 *snapshotv1alpha1.SnapshotV1alpha1Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// VolumesnapshotV1alpha1 retrieves the VolumesnapshotV1alpha1Client
|
// SnapshotV1alpha1 retrieves the SnapshotV1alpha1Client
|
||||||
func (c *Clientset) VolumesnapshotV1alpha1() volumesnapshotv1alpha1.VolumesnapshotV1alpha1Interface {
|
func (c *Clientset) SnapshotV1alpha1() snapshotv1alpha1.SnapshotV1alpha1Interface {
|
||||||
return c.volumesnapshotV1alpha1
|
return c.snapshotV1alpha1
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Volumesnapshot retrieves the default version of VolumesnapshotClient.
|
|
||||||
// Please explicitly pick a version.
|
|
||||||
func (c *Clientset) Volumesnapshot() volumesnapshotv1alpha1.VolumesnapshotV1alpha1Interface {
|
|
||||||
return c.volumesnapshotV1alpha1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discovery retrieves the DiscoveryClient
|
// Discovery retrieves the DiscoveryClient
|
||||||
@@ -66,7 +58,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
|||||||
}
|
}
|
||||||
var cs Clientset
|
var cs Clientset
|
||||||
var err error
|
var err error
|
||||||
cs.volumesnapshotV1alpha1, err = volumesnapshotv1alpha1.NewForConfig(&configShallowCopy)
|
cs.snapshotV1alpha1, err = snapshotv1alpha1.NewForConfig(&configShallowCopy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -82,7 +74,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
|||||||
// panics if there is an error in the config.
|
// panics if there is an error in the config.
|
||||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||||
var cs Clientset
|
var cs Clientset
|
||||||
cs.volumesnapshotV1alpha1 = volumesnapshotv1alpha1.NewForConfigOrDie(c)
|
cs.snapshotV1alpha1 = snapshotv1alpha1.NewForConfigOrDie(c)
|
||||||
|
|
||||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||||
return &cs
|
return &cs
|
||||||
@@ -91,7 +83,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
|||||||
// New creates a new Clientset for the given RESTClient.
|
// New creates a new Clientset for the given RESTClient.
|
||||||
func New(c rest.Interface) *Clientset {
|
func New(c rest.Interface) *Clientset {
|
||||||
var cs Clientset
|
var cs Clientset
|
||||||
cs.volumesnapshotV1alpha1 = volumesnapshotv1alpha1.New(c)
|
cs.snapshotV1alpha1 = snapshotv1alpha1.New(c)
|
||||||
|
|
||||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||||
return &cs
|
return &cs
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -20,8 +20,8 @@ package fake
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
|
clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
|
||||||
volumesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1"
|
snapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1"
|
||||||
fakevolumesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/fake"
|
fakesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/fake"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
"k8s.io/client-go/discovery"
|
"k8s.io/client-go/discovery"
|
||||||
@@ -71,12 +71,7 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
|||||||
|
|
||||||
var _ clientset.Interface = &Clientset{}
|
var _ clientset.Interface = &Clientset{}
|
||||||
|
|
||||||
// VolumesnapshotV1alpha1 retrieves the VolumesnapshotV1alpha1Client
|
// SnapshotV1alpha1 retrieves the SnapshotV1alpha1Client
|
||||||
func (c *Clientset) VolumesnapshotV1alpha1() volumesnapshotv1alpha1.VolumesnapshotV1alpha1Interface {
|
func (c *Clientset) SnapshotV1alpha1() snapshotv1alpha1.SnapshotV1alpha1Interface {
|
||||||
return &fakevolumesnapshotv1alpha1.FakeVolumesnapshotV1alpha1{Fake: &c.Fake}
|
return &fakesnapshotv1alpha1.FakeSnapshotV1alpha1{Fake: &c.Fake}
|
||||||
}
|
|
||||||
|
|
||||||
// Volumesnapshot retrieves the VolumesnapshotV1alpha1Client
|
|
||||||
func (c *Clientset) Volumesnapshot() volumesnapshotv1alpha1.VolumesnapshotV1alpha1Interface {
|
|
||||||
return &fakevolumesnapshotv1alpha1.FakeVolumesnapshotV1alpha1{Fake: &c.Fake}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +19,7 @@ limitations under the License.
|
|||||||
package fake
|
package fake
|
||||||
|
|
||||||
import (
|
import (
|
||||||
volumesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1"
|
snapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@@ -31,7 +31,7 @@ var scheme = runtime.NewScheme()
|
|||||||
var codecs = serializer.NewCodecFactory(scheme)
|
var codecs = serializer.NewCodecFactory(scheme)
|
||||||
var parameterCodec = runtime.NewParameterCodec(scheme)
|
var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||||
volumesnapshotv1alpha1.AddToScheme,
|
snapshotv1alpha1.AddToScheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +19,7 @@ limitations under the License.
|
|||||||
package scheme
|
package scheme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
volumesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1"
|
snapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@@ -31,7 +31,7 @@ var Scheme = runtime.NewScheme()
|
|||||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||||
volumesnapshotv1alpha1.AddToScheme,
|
snapshotv1alpha1.AddToScheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -30,13 +30,13 @@ import (
|
|||||||
|
|
||||||
// FakeVolumeSnapshots implements VolumeSnapshotInterface
|
// FakeVolumeSnapshots implements VolumeSnapshotInterface
|
||||||
type FakeVolumeSnapshots struct {
|
type FakeVolumeSnapshots struct {
|
||||||
Fake *FakeVolumesnapshotV1alpha1
|
Fake *FakeSnapshotV1alpha1
|
||||||
ns string
|
ns string
|
||||||
}
|
}
|
||||||
|
|
||||||
var volumesnapshotsResource = schema.GroupVersionResource{Group: "volumesnapshot", Version: "v1alpha1", Resource: "volumesnapshots"}
|
var volumesnapshotsResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Resource: "volumesnapshots"}
|
||||||
|
|
||||||
var volumesnapshotsKind = schema.GroupVersionKind{Group: "volumesnapshot", Version: "v1alpha1", Kind: "VolumeSnapshot"}
|
var volumesnapshotsKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Kind: "VolumeSnapshot"}
|
||||||
|
|
||||||
// Get takes name of the volumeSnapshot, and returns the corresponding volumeSnapshot object, and an error if there is any.
|
// Get takes name of the volumeSnapshot, and returns the corresponding volumeSnapshot object, and an error if there is any.
|
||||||
func (c *FakeVolumeSnapshots) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshot, err error) {
|
func (c *FakeVolumeSnapshots) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshot, err error) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -24,25 +24,25 @@ import (
|
|||||||
testing "k8s.io/client-go/testing"
|
testing "k8s.io/client-go/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FakeVolumesnapshotV1alpha1 struct {
|
type FakeSnapshotV1alpha1 struct {
|
||||||
*testing.Fake
|
*testing.Fake
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FakeVolumesnapshotV1alpha1) VolumeSnapshots(namespace string) v1alpha1.VolumeSnapshotInterface {
|
func (c *FakeSnapshotV1alpha1) VolumeSnapshots(namespace string) v1alpha1.VolumeSnapshotInterface {
|
||||||
return &FakeVolumeSnapshots{c, namespace}
|
return &FakeVolumeSnapshots{c, namespace}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FakeVolumesnapshotV1alpha1) VolumeSnapshotClasses() v1alpha1.VolumeSnapshotClassInterface {
|
func (c *FakeSnapshotV1alpha1) VolumeSnapshotClasses() v1alpha1.VolumeSnapshotClassInterface {
|
||||||
return &FakeVolumeSnapshotClasses{c}
|
return &FakeVolumeSnapshotClasses{c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FakeVolumesnapshotV1alpha1) VolumeSnapshotContents() v1alpha1.VolumeSnapshotContentInterface {
|
func (c *FakeSnapshotV1alpha1) VolumeSnapshotContents() v1alpha1.VolumeSnapshotContentInterface {
|
||||||
return &FakeVolumeSnapshotContents{c}
|
return &FakeVolumeSnapshotContents{c}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RESTClient returns a RESTClient that is used to communicate
|
// RESTClient returns a RESTClient that is used to communicate
|
||||||
// with API server by this client implementation.
|
// with API server by this client implementation.
|
||||||
func (c *FakeVolumesnapshotV1alpha1) RESTClient() rest.Interface {
|
func (c *FakeSnapshotV1alpha1) RESTClient() rest.Interface {
|
||||||
var ret *rest.RESTClient
|
var ret *rest.RESTClient
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -30,12 +30,12 @@ import (
|
|||||||
|
|
||||||
// FakeVolumeSnapshotClasses implements VolumeSnapshotClassInterface
|
// FakeVolumeSnapshotClasses implements VolumeSnapshotClassInterface
|
||||||
type FakeVolumeSnapshotClasses struct {
|
type FakeVolumeSnapshotClasses struct {
|
||||||
Fake *FakeVolumesnapshotV1alpha1
|
Fake *FakeSnapshotV1alpha1
|
||||||
}
|
}
|
||||||
|
|
||||||
var volumesnapshotclassesResource = schema.GroupVersionResource{Group: "volumesnapshot", Version: "v1alpha1", Resource: "volumesnapshotclasses"}
|
var volumesnapshotclassesResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Resource: "volumesnapshotclasses"}
|
||||||
|
|
||||||
var volumesnapshotclassesKind = schema.GroupVersionKind{Group: "volumesnapshot", Version: "v1alpha1", Kind: "VolumeSnapshotClass"}
|
var volumesnapshotclassesKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Kind: "VolumeSnapshotClass"}
|
||||||
|
|
||||||
// Get takes name of the volumeSnapshotClass, and returns the corresponding volumeSnapshotClass object, and an error if there is any.
|
// Get takes name of the volumeSnapshotClass, and returns the corresponding volumeSnapshotClass object, and an error if there is any.
|
||||||
func (c *FakeVolumeSnapshotClasses) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshotClass, err error) {
|
func (c *FakeVolumeSnapshotClasses) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshotClass, err error) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -30,12 +30,12 @@ import (
|
|||||||
|
|
||||||
// FakeVolumeSnapshotContents implements VolumeSnapshotContentInterface
|
// FakeVolumeSnapshotContents implements VolumeSnapshotContentInterface
|
||||||
type FakeVolumeSnapshotContents struct {
|
type FakeVolumeSnapshotContents struct {
|
||||||
Fake *FakeVolumesnapshotV1alpha1
|
Fake *FakeSnapshotV1alpha1
|
||||||
}
|
}
|
||||||
|
|
||||||
var volumesnapshotcontentsResource = schema.GroupVersionResource{Group: "volumesnapshot", Version: "v1alpha1", Resource: "volumesnapshotcontents"}
|
var volumesnapshotcontentsResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Resource: "volumesnapshotcontents"}
|
||||||
|
|
||||||
var volumesnapshotcontentsKind = schema.GroupVersionKind{Group: "volumesnapshot", Version: "v1alpha1", Kind: "VolumeSnapshotContent"}
|
var volumesnapshotcontentsKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Kind: "VolumeSnapshotContent"}
|
||||||
|
|
||||||
// Get takes name of the volumeSnapshotContent, and returns the corresponding volumeSnapshotContent object, and an error if there is any.
|
// Get takes name of the volumeSnapshotContent, and returns the corresponding volumeSnapshotContent object, and an error if there is any.
|
||||||
func (c *FakeVolumeSnapshotContents) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshotContent, err error) {
|
func (c *FakeVolumeSnapshotContents) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshotContent, err error) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -56,7 +56,7 @@ type volumeSnapshots struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newVolumeSnapshots returns a VolumeSnapshots
|
// newVolumeSnapshots returns a VolumeSnapshots
|
||||||
func newVolumeSnapshots(c *VolumesnapshotV1alpha1Client, namespace string) *volumeSnapshots {
|
func newVolumeSnapshots(c *SnapshotV1alpha1Client, namespace string) *volumeSnapshots {
|
||||||
return &volumeSnapshots{
|
return &volumeSnapshots{
|
||||||
client: c.RESTClient(),
|
client: c.RESTClient(),
|
||||||
ns: namespace,
|
ns: namespace,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -25,32 +25,32 @@ import (
|
|||||||
rest "k8s.io/client-go/rest"
|
rest "k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VolumesnapshotV1alpha1Interface interface {
|
type SnapshotV1alpha1Interface interface {
|
||||||
RESTClient() rest.Interface
|
RESTClient() rest.Interface
|
||||||
VolumeSnapshotsGetter
|
VolumeSnapshotsGetter
|
||||||
VolumeSnapshotClassesGetter
|
VolumeSnapshotClassesGetter
|
||||||
VolumeSnapshotContentsGetter
|
VolumeSnapshotContentsGetter
|
||||||
}
|
}
|
||||||
|
|
||||||
// VolumesnapshotV1alpha1Client is used to interact with features provided by the volumesnapshot group.
|
// SnapshotV1alpha1Client is used to interact with features provided by the snapshot.storage.k8s.io group.
|
||||||
type VolumesnapshotV1alpha1Client struct {
|
type SnapshotV1alpha1Client struct {
|
||||||
restClient rest.Interface
|
restClient rest.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *VolumesnapshotV1alpha1Client) VolumeSnapshots(namespace string) VolumeSnapshotInterface {
|
func (c *SnapshotV1alpha1Client) VolumeSnapshots(namespace string) VolumeSnapshotInterface {
|
||||||
return newVolumeSnapshots(c, namespace)
|
return newVolumeSnapshots(c, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *VolumesnapshotV1alpha1Client) VolumeSnapshotClasses() VolumeSnapshotClassInterface {
|
func (c *SnapshotV1alpha1Client) VolumeSnapshotClasses() VolumeSnapshotClassInterface {
|
||||||
return newVolumeSnapshotClasses(c)
|
return newVolumeSnapshotClasses(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *VolumesnapshotV1alpha1Client) VolumeSnapshotContents() VolumeSnapshotContentInterface {
|
func (c *SnapshotV1alpha1Client) VolumeSnapshotContents() VolumeSnapshotContentInterface {
|
||||||
return newVolumeSnapshotContents(c)
|
return newVolumeSnapshotContents(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewForConfig creates a new VolumesnapshotV1alpha1Client for the given config.
|
// NewForConfig creates a new SnapshotV1alpha1Client for the given config.
|
||||||
func NewForConfig(c *rest.Config) (*VolumesnapshotV1alpha1Client, error) {
|
func NewForConfig(c *rest.Config) (*SnapshotV1alpha1Client, error) {
|
||||||
config := *c
|
config := *c
|
||||||
if err := setConfigDefaults(&config); err != nil {
|
if err := setConfigDefaults(&config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -59,12 +59,12 @@ func NewForConfig(c *rest.Config) (*VolumesnapshotV1alpha1Client, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &VolumesnapshotV1alpha1Client{client}, nil
|
return &SnapshotV1alpha1Client{client}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewForConfigOrDie creates a new VolumesnapshotV1alpha1Client for the given config and
|
// NewForConfigOrDie creates a new SnapshotV1alpha1Client for the given config and
|
||||||
// panics if there is an error in the config.
|
// panics if there is an error in the config.
|
||||||
func NewForConfigOrDie(c *rest.Config) *VolumesnapshotV1alpha1Client {
|
func NewForConfigOrDie(c *rest.Config) *SnapshotV1alpha1Client {
|
||||||
client, err := NewForConfig(c)
|
client, err := NewForConfig(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -72,9 +72,9 @@ func NewForConfigOrDie(c *rest.Config) *VolumesnapshotV1alpha1Client {
|
|||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new VolumesnapshotV1alpha1Client for the given RESTClient.
|
// New creates a new SnapshotV1alpha1Client for the given RESTClient.
|
||||||
func New(c rest.Interface) *VolumesnapshotV1alpha1Client {
|
func New(c rest.Interface) *SnapshotV1alpha1Client {
|
||||||
return &VolumesnapshotV1alpha1Client{c}
|
return &SnapshotV1alpha1Client{c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setConfigDefaults(config *rest.Config) error {
|
func setConfigDefaults(config *rest.Config) error {
|
||||||
@@ -92,7 +92,7 @@ func setConfigDefaults(config *rest.Config) error {
|
|||||||
|
|
||||||
// RESTClient returns a RESTClient that is used to communicate
|
// RESTClient returns a RESTClient that is used to communicate
|
||||||
// with API server by this client implementation.
|
// with API server by this client implementation.
|
||||||
func (c *VolumesnapshotV1alpha1Client) RESTClient() rest.Interface {
|
func (c *SnapshotV1alpha1Client) RESTClient() rest.Interface {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -54,7 +54,7 @@ type volumeSnapshotClasses struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newVolumeSnapshotClasses returns a VolumeSnapshotClasses
|
// newVolumeSnapshotClasses returns a VolumeSnapshotClasses
|
||||||
func newVolumeSnapshotClasses(c *VolumesnapshotV1alpha1Client) *volumeSnapshotClasses {
|
func newVolumeSnapshotClasses(c *SnapshotV1alpha1Client) *volumeSnapshotClasses {
|
||||||
return &volumeSnapshotClasses{
|
return &volumeSnapshotClasses{
|
||||||
client: c.RESTClient(),
|
client: c.RESTClient(),
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -54,7 +54,7 @@ type volumeSnapshotContents struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newVolumeSnapshotContents returns a VolumeSnapshotContents
|
// newVolumeSnapshotContents returns a VolumeSnapshotContents
|
||||||
func newVolumeSnapshotContents(c *VolumesnapshotV1alpha1Client) *volumeSnapshotContents {
|
func newVolumeSnapshotContents(c *SnapshotV1alpha1Client) *volumeSnapshotContents {
|
||||||
return &volumeSnapshotContents{
|
return &volumeSnapshotContents{
|
||||||
client: c.RESTClient(),
|
client: c.RESTClient(),
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -172,9 +172,9 @@ type SharedInformerFactory interface {
|
|||||||
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
|
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
|
||||||
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
|
||||||
|
|
||||||
Volumesnapshot() volumesnapshot.Interface
|
Snapshot() volumesnapshot.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *sharedInformerFactory) Volumesnapshot() volumesnapshot.Interface {
|
func (f *sharedInformerFactory) Snapshot() volumesnapshot.Interface {
|
||||||
return volumesnapshot.New(f, f.namespace, f.tweakListOptions)
|
return volumesnapshot.New(f, f.namespace, f.tweakListOptions)
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -52,13 +52,13 @@ func (f *genericInformer) Lister() cache.GenericLister {
|
|||||||
// TODO extend this to unknown resources with a client pool
|
// TODO extend this to unknown resources with a client pool
|
||||||
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
|
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
|
||||||
switch resource {
|
switch resource {
|
||||||
// Group=volumesnapshot, Version=v1alpha1
|
// Group=snapshot.storage.k8s.io, Version=v1alpha1
|
||||||
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshots"):
|
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshots"):
|
||||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Volumesnapshot().V1alpha1().VolumeSnapshots().Informer()}, nil
|
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1alpha1().VolumeSnapshots().Informer()}, nil
|
||||||
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshotclasses"):
|
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshotclasses"):
|
||||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Volumesnapshot().V1alpha1().VolumeSnapshotClasses().Informer()}, nil
|
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1alpha1().VolumeSnapshotClasses().Informer()}, nil
|
||||||
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshotcontents"):
|
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshotcontents"):
|
||||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Volumesnapshot().V1alpha1().VolumeSnapshotContents().Informer()}, nil
|
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1alpha1().VolumeSnapshotContents().Informer()}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
// Code generated by informer-gen. DO NOT EDIT.
|
// Code generated by informer-gen. DO NOT EDIT.
|
||||||
|
|
||||||
package volumesnapshot
|
package snapshot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/internalinterfaces"
|
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/internalinterfaces"
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -61,13 +61,13 @@ func NewFilteredVolumeSnapshotInformer(client versioned.Interface, namespace str
|
|||||||
if tweakListOptions != nil {
|
if tweakListOptions != nil {
|
||||||
tweakListOptions(&options)
|
tweakListOptions(&options)
|
||||||
}
|
}
|
||||||
return client.VolumesnapshotV1alpha1().VolumeSnapshots(namespace).List(options)
|
return client.SnapshotV1alpha1().VolumeSnapshots(namespace).List(options)
|
||||||
},
|
},
|
||||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||||
if tweakListOptions != nil {
|
if tweakListOptions != nil {
|
||||||
tweakListOptions(&options)
|
tweakListOptions(&options)
|
||||||
}
|
}
|
||||||
return client.VolumesnapshotV1alpha1().VolumeSnapshots(namespace).Watch(options)
|
return client.SnapshotV1alpha1().VolumeSnapshots(namespace).Watch(options)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&volumesnapshotv1alpha1.VolumeSnapshot{},
|
&volumesnapshotv1alpha1.VolumeSnapshot{},
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -60,13 +60,13 @@ func NewFilteredVolumeSnapshotClassInformer(client versioned.Interface, resyncPe
|
|||||||
if tweakListOptions != nil {
|
if tweakListOptions != nil {
|
||||||
tweakListOptions(&options)
|
tweakListOptions(&options)
|
||||||
}
|
}
|
||||||
return client.VolumesnapshotV1alpha1().VolumeSnapshotClasses().List(options)
|
return client.SnapshotV1alpha1().VolumeSnapshotClasses().List(options)
|
||||||
},
|
},
|
||||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||||
if tweakListOptions != nil {
|
if tweakListOptions != nil {
|
||||||
tweakListOptions(&options)
|
tweakListOptions(&options)
|
||||||
}
|
}
|
||||||
return client.VolumesnapshotV1alpha1().VolumeSnapshotClasses().Watch(options)
|
return client.SnapshotV1alpha1().VolumeSnapshotClasses().Watch(options)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&volumesnapshotv1alpha1.VolumeSnapshotClass{},
|
&volumesnapshotv1alpha1.VolumeSnapshotClass{},
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -60,13 +60,13 @@ func NewFilteredVolumeSnapshotContentInformer(client versioned.Interface, resync
|
|||||||
if tweakListOptions != nil {
|
if tweakListOptions != nil {
|
||||||
tweakListOptions(&options)
|
tweakListOptions(&options)
|
||||||
}
|
}
|
||||||
return client.VolumesnapshotV1alpha1().VolumeSnapshotContents().List(options)
|
return client.SnapshotV1alpha1().VolumeSnapshotContents().List(options)
|
||||||
},
|
},
|
||||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||||
if tweakListOptions != nil {
|
if tweakListOptions != nil {
|
||||||
tweakListOptions(&options)
|
tweakListOptions(&options)
|
||||||
}
|
}
|
||||||
return client.VolumesnapshotV1alpha1().VolumeSnapshotContents().Watch(options)
|
return client.SnapshotV1alpha1().VolumeSnapshotContents().Watch(options)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&volumesnapshotv1alpha1.VolumeSnapshotContent{},
|
&volumesnapshotv1alpha1.VolumeSnapshotContent{},
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 The Kubernetes Authors.
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@@ -30,9 +30,9 @@ import (
|
|||||||
|
|
||||||
// Handler is responsible for handling VolumeSnapshot events from informer.
|
// Handler is responsible for handling VolumeSnapshot events from informer.
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
CreateSnapshot(snapshot *crdv1.VolumeSnapshot, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, int64, int64, bool, error)
|
CreateSnapshot(snapshot *crdv1.VolumeSnapshot, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, time.Time, int64, bool, error)
|
||||||
DeleteSnapshot(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) error
|
DeleteSnapshot(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) error
|
||||||
GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (bool, int64, int64, error)
|
GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (bool, time.Time, int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// csiHandler is a handler that calls CSI to create/delete volume snapshot.
|
// csiHandler is a handler that calls CSI to create/delete volume snapshot.
|
||||||
@@ -58,18 +58,18 @@ func NewCSIHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *csiHandler) CreateSnapshot(snapshot *crdv1.VolumeSnapshot, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, int64, int64, bool, error) {
|
func (handler *csiHandler) CreateSnapshot(snapshot *crdv1.VolumeSnapshot, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, time.Time, int64, bool, error) {
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), handler.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), handler.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
snapshotName, err := makeSnapshotName(handler.snapshotNamePrefix, string(snapshot.UID), handler.snapshotNameUUIDLength)
|
snapshotName, err := makeSnapshotName(handler.snapshotNamePrefix, string(snapshot.UID), handler.snapshotNameUUIDLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", 0, 0, false, err
|
return "", "", time.Time{}, 0, false, err
|
||||||
}
|
}
|
||||||
newParameters, err := removePrefixedParameters(parameters)
|
newParameters, err := removePrefixedParameters(parameters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", 0, 0, false, fmt.Errorf("failed to remove CSI Parameters of prefixed keys: %v", err)
|
return "", "", time.Time{}, 0, false, fmt.Errorf("failed to remove CSI Parameters of prefixed keys: %v", err)
|
||||||
}
|
}
|
||||||
return handler.snapshotter.CreateSnapshot(ctx, snapshotName, volume, newParameters, snapshotterCredentials)
|
return handler.snapshotter.CreateSnapshot(ctx, snapshotName, volume, newParameters, snapshotterCredentials)
|
||||||
}
|
}
|
||||||
@@ -89,16 +89,16 @@ func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *csiHandler) GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (bool, int64, int64, error) {
|
func (handler *csiHandler) GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (bool, time.Time, int64, error) {
|
||||||
if content.Spec.CSI == nil {
|
if content.Spec.CSI == nil {
|
||||||
return false, 0, 0, fmt.Errorf("CSISnapshot not defined in spec")
|
return false, time.Time{}, 0, fmt.Errorf("CSISnapshot not defined in spec")
|
||||||
}
|
}
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), handler.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), handler.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
csiSnapshotStatus, timestamp, size, err := handler.snapshotter.GetSnapshotStatus(ctx, content.Spec.CSI.SnapshotHandle)
|
csiSnapshotStatus, timestamp, size, err := handler.snapshotter.GetSnapshotStatus(ctx, content.Spec.CSI.SnapshotHandle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, 0, fmt.Errorf("failed to list snapshot content %s: %q", content.Name, err)
|
return false, time.Time{}, 0, fmt.Errorf("failed to list snapshot content %s: %q", content.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return csiSnapshotStatus, timestamp, size, nil
|
return csiSnapshotStatus, timestamp, size, nil
|
||||||
|
@@ -21,6 +21,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
sysruntime "runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -53,6 +54,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
"k8s.io/kubernetes/pkg/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is a unit test framework for snapshot controller.
|
// This is a unit test framework for snapshot controller.
|
||||||
@@ -110,7 +112,8 @@ type controllerTest struct {
|
|||||||
// List of expected CSI list snapshot calls
|
// List of expected CSI list snapshot calls
|
||||||
expectedListCalls []listCall
|
expectedListCalls []listCall
|
||||||
// Function to call as the test.
|
// Function to call as the test.
|
||||||
test testCall
|
test testCall
|
||||||
|
expectSuccess bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type testCall func(ctrl *csiSnapshotController, reactor *snapshotReactor, test controllerTest) error
|
type testCall func(ctrl *csiSnapshotController, reactor *snapshotReactor, test controllerTest) error
|
||||||
@@ -177,6 +180,11 @@ func withContentFinalizer(content *crdv1.VolumeSnapshotContent) *crdv1.VolumeSna
|
|||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withPVCFinalizer(pvc *v1.PersistentVolumeClaim) *v1.PersistentVolumeClaim {
|
||||||
|
pvc.ObjectMeta.Finalizers = append(pvc.ObjectMeta.Finalizers, PVCFinalizer)
|
||||||
|
return pvc
|
||||||
|
}
|
||||||
|
|
||||||
// React is a callback called by fake kubeClient from the controller.
|
// React is a callback called by fake kubeClient from the controller.
|
||||||
// In other words, every snapshot/content change performed by the controller ends
|
// In other words, every snapshot/content change performed by the controller ends
|
||||||
// here.
|
// here.
|
||||||
@@ -331,6 +339,32 @@ func (r *snapshotReactor) React(action core.Action) (handled bool, ret runtime.O
|
|||||||
klog.V(4).Infof("GetClaim: claim %s not found", name)
|
klog.V(4).Infof("GetClaim: claim %s not found", name)
|
||||||
return true, nil, fmt.Errorf("cannot find claim %s", name)
|
return true, nil, fmt.Errorf("cannot find claim %s", name)
|
||||||
|
|
||||||
|
case action.Matches("update", "persistentvolumeclaims"):
|
||||||
|
obj := action.(core.UpdateAction).GetObject()
|
||||||
|
claim := obj.(*v1.PersistentVolumeClaim)
|
||||||
|
|
||||||
|
// Check and bump object version
|
||||||
|
storedClaim, found := r.claims[claim.Name]
|
||||||
|
if found {
|
||||||
|
storedVer, _ := strconv.Atoi(storedClaim.ResourceVersion)
|
||||||
|
requestedVer, _ := strconv.Atoi(claim.ResourceVersion)
|
||||||
|
if storedVer != requestedVer {
|
||||||
|
return true, obj, errVersionConflict
|
||||||
|
}
|
||||||
|
// Don't modify the existing object
|
||||||
|
claim = claim.DeepCopy()
|
||||||
|
claim.ResourceVersion = strconv.Itoa(storedVer + 1)
|
||||||
|
} else {
|
||||||
|
return true, nil, fmt.Errorf("cannot update claim %s: claim not found", claim.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the updated object to appropriate places.
|
||||||
|
r.claims[claim.Name] = claim
|
||||||
|
r.changedObjects = append(r.changedObjects, claim)
|
||||||
|
r.changedSinceLastSync++
|
||||||
|
klog.V(4).Infof("saved updated claim %s", claim.Name)
|
||||||
|
return true, claim, nil
|
||||||
|
|
||||||
case action.Matches("get", "storageclasses"):
|
case action.Matches("get", "storageclasses"):
|
||||||
name := action.(core.GetAction).GetName()
|
name := action.(core.GetAction).GetName()
|
||||||
storageClass, found := r.storageClasses[name]
|
storageClass, found := r.storageClasses[name]
|
||||||
@@ -550,6 +584,9 @@ func (r *snapshotReactor) syncAll() {
|
|||||||
for _, v := range r.contents {
|
for _, v := range r.contents {
|
||||||
r.changedObjects = append(r.changedObjects, v)
|
r.changedObjects = append(r.changedObjects, v)
|
||||||
}
|
}
|
||||||
|
for _, pvc := range r.claims {
|
||||||
|
r.changedObjects = append(r.changedObjects, pvc)
|
||||||
|
}
|
||||||
r.changedSinceLastSync = 0
|
r.changedSinceLastSync = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,6 +736,7 @@ func newSnapshotReactor(kubeClient *kubefake.Clientset, client *fake.Clientset,
|
|||||||
client.AddReactor("delete", "volumesnapshotcontents", reactor.React)
|
client.AddReactor("delete", "volumesnapshotcontents", reactor.React)
|
||||||
client.AddReactor("delete", "volumesnapshots", reactor.React)
|
client.AddReactor("delete", "volumesnapshots", reactor.React)
|
||||||
kubeClient.AddReactor("get", "persistentvolumeclaims", reactor.React)
|
kubeClient.AddReactor("get", "persistentvolumeclaims", reactor.React)
|
||||||
|
kubeClient.AddReactor("update", "persistentvolumeclaims", reactor.React)
|
||||||
kubeClient.AddReactor("get", "persistentvolumes", reactor.React)
|
kubeClient.AddReactor("get", "persistentvolumes", reactor.React)
|
||||||
kubeClient.AddReactor("get", "storageclasses", reactor.React)
|
kubeClient.AddReactor("get", "storageclasses", reactor.React)
|
||||||
kubeClient.AddReactor("get", "secrets", reactor.React)
|
kubeClient.AddReactor("get", "secrets", reactor.React)
|
||||||
@@ -728,9 +766,9 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte
|
|||||||
clientset,
|
clientset,
|
||||||
kubeClient,
|
kubeClient,
|
||||||
mockDriverName,
|
mockDriverName,
|
||||||
informerFactory.Volumesnapshot().V1alpha1().VolumeSnapshots(),
|
informerFactory.Snapshot().V1alpha1().VolumeSnapshots(),
|
||||||
informerFactory.Volumesnapshot().V1alpha1().VolumeSnapshotContents(),
|
informerFactory.Snapshot().V1alpha1().VolumeSnapshotContents(),
|
||||||
informerFactory.Volumesnapshot().V1alpha1().VolumeSnapshotClasses(),
|
informerFactory.Snapshot().V1alpha1().VolumeSnapshotClasses(),
|
||||||
coreFactory.Core().V1().PersistentVolumeClaims(),
|
coreFactory.Core().V1().PersistentVolumeClaims(),
|
||||||
3,
|
3,
|
||||||
5*time.Millisecond,
|
5*time.Millisecond,
|
||||||
@@ -746,6 +784,7 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte
|
|||||||
ctrl.contentListerSynced = alwaysReady
|
ctrl.contentListerSynced = alwaysReady
|
||||||
ctrl.snapshotListerSynced = alwaysReady
|
ctrl.snapshotListerSynced = alwaysReady
|
||||||
ctrl.classListerSynced = alwaysReady
|
ctrl.classListerSynced = alwaysReady
|
||||||
|
ctrl.pvcListerSynced = alwaysReady
|
||||||
|
|
||||||
return ctrl, nil
|
return ctrl, nil
|
||||||
}
|
}
|
||||||
@@ -845,7 +884,7 @@ func newSnapshotArray(name, className, boundToContent, snapshotUID, claimName st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newClaim returns a new claim with given attributes
|
// newClaim returns a new claim with given attributes
|
||||||
func newClaim(name, claimUID, capacity, boundToVolume string, phase v1.PersistentVolumeClaimPhase, class *string) *v1.PersistentVolumeClaim {
|
func newClaim(name, claimUID, capacity, boundToVolume string, phase v1.PersistentVolumeClaimPhase, class *string, bFinalizer bool) *v1.PersistentVolumeClaim {
|
||||||
claim := v1.PersistentVolumeClaim{
|
claim := v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
@@ -877,6 +916,9 @@ func newClaim(name, claimUID, capacity, boundToVolume string, phase v1.Persisten
|
|||||||
claim.Status.Capacity = claim.Spec.Resources.Requests
|
claim.Status.Capacity = claim.Spec.Resources.Requests
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if bFinalizer {
|
||||||
|
return withPVCFinalizer(&claim)
|
||||||
|
}
|
||||||
return &claim
|
return &claim
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -884,7 +926,15 @@ func newClaim(name, claimUID, capacity, boundToVolume string, phase v1.Persisten
|
|||||||
// newClaim() with the same parameters.
|
// newClaim() with the same parameters.
|
||||||
func newClaimArray(name, claimUID, capacity, boundToVolume string, phase v1.PersistentVolumeClaimPhase, class *string) []*v1.PersistentVolumeClaim {
|
func newClaimArray(name, claimUID, capacity, boundToVolume string, phase v1.PersistentVolumeClaimPhase, class *string) []*v1.PersistentVolumeClaim {
|
||||||
return []*v1.PersistentVolumeClaim{
|
return []*v1.PersistentVolumeClaim{
|
||||||
newClaim(name, claimUID, capacity, boundToVolume, phase, class),
|
newClaim(name, claimUID, capacity, boundToVolume, phase, class, false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// newClaimArrayFinalizer returns array with a single claim that would be returned by
|
||||||
|
// newClaim() with the same parameters plus finalizer.
|
||||||
|
func newClaimArrayFinalizer(name, claimUID, capacity, boundToVolume string, phase v1.PersistentVolumeClaimPhase, class *string) []*v1.PersistentVolumeClaim {
|
||||||
|
return []*v1.PersistentVolumeClaim{
|
||||||
|
newClaim(name, claimUID, capacity, boundToVolume, phase, class, true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,6 +1011,14 @@ func testSyncContent(ctrl *csiSnapshotController, reactor *snapshotReactor, test
|
|||||||
return ctrl.syncContent(test.initialContents[0])
|
return ctrl.syncContent(test.initialContents[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAddPVCFinalizer(ctrl *csiSnapshotController, reactor *snapshotReactor, test controllerTest) error {
|
||||||
|
return ctrl.ensureSnapshotSourceFinalizer(test.initialSnapshots[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRemovePVCFinalizer(ctrl *csiSnapshotController, reactor *snapshotReactor, test controllerTest) error {
|
||||||
|
return ctrl.checkandRemoveSnapshotSourceFinalizer(test.initialSnapshots[0])
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
classEmpty string
|
classEmpty string
|
||||||
classGold = "gold"
|
classGold = "gold"
|
||||||
@@ -1097,6 +1155,113 @@ func runSyncTests(t *testing.T, tests []controllerTest, snapshotClasses []*crdv1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This tests ensureSnapshotSourceFinalizer and checkandRemoveSnapshotSourceFinalizer
|
||||||
|
func runPVCFinalizerTests(t *testing.T, tests []controllerTest, snapshotClasses []*crdv1.VolumeSnapshotClass) {
|
||||||
|
snapshotscheme.AddToScheme(scheme.Scheme)
|
||||||
|
for _, test := range tests {
|
||||||
|
klog.V(4).Infof("starting test %q", test.name)
|
||||||
|
|
||||||
|
// Initialize the controller
|
||||||
|
kubeClient := &kubefake.Clientset{}
|
||||||
|
client := &fake.Clientset{}
|
||||||
|
|
||||||
|
ctrl, err := newTestController(kubeClient, client, nil, t, test)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Test %q construct persistent content failed: %v", test.name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
reactor := newSnapshotReactor(kubeClient, client, ctrl, nil, nil, test.errors)
|
||||||
|
for _, snapshot := range test.initialSnapshots {
|
||||||
|
ctrl.snapshotStore.Add(snapshot)
|
||||||
|
reactor.snapshots[snapshot.Name] = snapshot
|
||||||
|
}
|
||||||
|
for _, content := range test.initialContents {
|
||||||
|
if ctrl.isDriverMatch(test.initialContents[0]) {
|
||||||
|
ctrl.contentStore.Add(content)
|
||||||
|
reactor.contents[content.Name] = content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pvcIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
|
||||||
|
for _, claim := range test.initialClaims {
|
||||||
|
reactor.claims[claim.Name] = claim
|
||||||
|
pvcIndexer.Add(claim)
|
||||||
|
}
|
||||||
|
ctrl.pvcLister = corelisters.NewPersistentVolumeClaimLister(pvcIndexer)
|
||||||
|
|
||||||
|
for _, volume := range test.initialVolumes {
|
||||||
|
reactor.volumes[volume.Name] = volume
|
||||||
|
}
|
||||||
|
for _, storageClass := range test.initialStorageClasses {
|
||||||
|
reactor.storageClasses[storageClass.Name] = storageClass
|
||||||
|
}
|
||||||
|
for _, secret := range test.initialSecrets {
|
||||||
|
reactor.secrets[secret.Name] = secret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject classes into controller via a custom lister.
|
||||||
|
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
|
||||||
|
for _, class := range snapshotClasses {
|
||||||
|
indexer.Add(class)
|
||||||
|
}
|
||||||
|
ctrl.classLister = storagelisters.NewVolumeSnapshotClassLister(indexer)
|
||||||
|
|
||||||
|
// Run the tested functions
|
||||||
|
err = test.test(ctrl, reactor, test)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Test %q failed: %v", test.name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify PVCFinalizer tests results
|
||||||
|
evaluatePVCFinalizerTests(ctrl, reactor, test, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate PVCFinalizer tests results
|
||||||
|
func evaluatePVCFinalizerTests(ctrl *csiSnapshotController, reactor *snapshotReactor, test controllerTest, t *testing.T) {
|
||||||
|
// Evaluate results
|
||||||
|
bHasPVCFinalizer := false
|
||||||
|
name := sysruntime.FuncForPC(reflect.ValueOf(test.test).Pointer()).Name()
|
||||||
|
index := strings.LastIndex(name, ".")
|
||||||
|
if index == -1 {
|
||||||
|
t.Errorf("Test %q: failed to test finalizer - invalid test call name [%s]", test.name, name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
names := []rune(name)
|
||||||
|
funcName := string(names[index+1 : len(name)])
|
||||||
|
klog.V(4).Infof("test %q: PVCFinalizer test func name: [%s]", test.name, funcName)
|
||||||
|
|
||||||
|
if funcName == "testAddPVCFinalizer" {
|
||||||
|
for _, pvc := range reactor.claims {
|
||||||
|
if test.initialClaims[0].Name == pvc.Name {
|
||||||
|
if !slice.ContainsString(test.initialClaims[0].ObjectMeta.Finalizers, PVCFinalizer, nil) && slice.ContainsString(pvc.ObjectMeta.Finalizers, PVCFinalizer, nil) {
|
||||||
|
klog.V(4).Infof("test %q succeeded. PVCFinalizer is added to PVC %s", test.name, pvc.Name)
|
||||||
|
bHasPVCFinalizer = true
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if test.expectSuccess && !bHasPVCFinalizer {
|
||||||
|
t.Errorf("Test %q: failed to add finalizer to PVC %s", test.name, test.initialClaims[0].Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bHasPVCFinalizer = true
|
||||||
|
if funcName == "testRemovePVCFinalizer" {
|
||||||
|
for _, pvc := range reactor.claims {
|
||||||
|
if test.initialClaims[0].Name == pvc.Name {
|
||||||
|
if slice.ContainsString(test.initialClaims[0].ObjectMeta.Finalizers, PVCFinalizer, nil) && !slice.ContainsString(pvc.ObjectMeta.Finalizers, PVCFinalizer, nil) {
|
||||||
|
klog.V(4).Infof("test %q succeeded. PVCFinalizer is removed from PVC %s", test.name, pvc.Name)
|
||||||
|
bHasPVCFinalizer = false
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if test.expectSuccess && bHasPVCFinalizer {
|
||||||
|
t.Errorf("Test %q: failed to remove finalizer from PVC %s", test.name, test.initialClaims[0].Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getSize(size int64) *resource.Quantity {
|
func getSize(size int64) *resource.Quantity {
|
||||||
return resource.NewQuantity(size, resource.BinarySI)
|
return resource.NewQuantity(size, resource.BinarySI)
|
||||||
}
|
}
|
||||||
@@ -1126,7 +1291,7 @@ type listCall struct {
|
|||||||
snapshotID string
|
snapshotID string
|
||||||
// information to return
|
// information to return
|
||||||
readyToUse bool
|
readyToUse bool
|
||||||
createTime int64
|
createTime time.Time
|
||||||
size int64
|
size int64
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
@@ -1144,12 +1309,12 @@ type createCall struct {
|
|||||||
parameters map[string]string
|
parameters map[string]string
|
||||||
secrets map[string]string
|
secrets map[string]string
|
||||||
// information to return
|
// information to return
|
||||||
driverName string
|
driverName string
|
||||||
snapshotId string
|
snapshotId string
|
||||||
timestamp int64
|
creationTime time.Time
|
||||||
size int64
|
size int64
|
||||||
readyToUse bool
|
readyToUse bool
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fake SnapShotter implementation that check that Attach/Detach is called
|
// Fake SnapShotter implementation that check that Attach/Detach is called
|
||||||
@@ -1164,10 +1329,10 @@ type fakeSnapshotter struct {
|
|||||||
t *testing.T
|
t *testing.T
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fakeSnapshotter) CreateSnapshot(ctx context.Context, snapshotName string, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, int64, int64, bool, error) {
|
func (f *fakeSnapshotter) CreateSnapshot(ctx context.Context, snapshotName string, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, time.Time, int64, bool, error) {
|
||||||
if f.createCallCounter >= len(f.createCalls) {
|
if f.createCallCounter >= len(f.createCalls) {
|
||||||
f.t.Errorf("Unexpected CSI Create Snapshot call: snapshotName=%s, volume=%v, index: %d, calls: %+v", snapshotName, volume.Name, f.createCallCounter, f.createCalls)
|
f.t.Errorf("Unexpected CSI Create Snapshot call: snapshotName=%s, volume=%v, index: %d, calls: %+v", snapshotName, volume.Name, f.createCallCounter, f.createCalls)
|
||||||
return "", "", 0, 0, false, fmt.Errorf("unexpected call")
|
return "", "", time.Time{}, 0, false, fmt.Errorf("unexpected call")
|
||||||
}
|
}
|
||||||
call := f.createCalls[f.createCallCounter]
|
call := f.createCalls[f.createCallCounter]
|
||||||
f.createCallCounter++
|
f.createCallCounter++
|
||||||
@@ -1194,10 +1359,10 @@ func (f *fakeSnapshotter) CreateSnapshot(ctx context.Context, snapshotName strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", 0, 0, false, fmt.Errorf("unexpected call")
|
return "", "", time.Time{}, 0, false, fmt.Errorf("unexpected call")
|
||||||
}
|
}
|
||||||
|
|
||||||
return call.driverName, call.snapshotId, call.timestamp, call.size, call.readyToUse, call.err
|
return call.driverName, call.snapshotId, call.creationTime, call.size, call.readyToUse, call.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fakeSnapshotter) DeleteSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) error {
|
func (f *fakeSnapshotter) DeleteSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) error {
|
||||||
@@ -1226,10 +1391,10 @@ func (f *fakeSnapshotter) DeleteSnapshot(ctx context.Context, snapshotID string,
|
|||||||
return call.err
|
return call.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fakeSnapshotter) GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, int64, int64, error) {
|
func (f *fakeSnapshotter) GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, time.Time, int64, error) {
|
||||||
if f.listCallCounter >= len(f.listCalls) {
|
if f.listCallCounter >= len(f.listCalls) {
|
||||||
f.t.Errorf("Unexpected CSI list Snapshot call: snapshotID=%s, index: %d, calls: %+v", snapshotID, f.createCallCounter, f.createCalls)
|
f.t.Errorf("Unexpected CSI list Snapshot call: snapshotID=%s, index: %d, calls: %+v", snapshotID, f.createCallCounter, f.createCalls)
|
||||||
return false, 0, 0, fmt.Errorf("unexpected call")
|
return false, time.Time{}, 0, fmt.Errorf("unexpected call")
|
||||||
}
|
}
|
||||||
call := f.listCalls[f.listCallCounter]
|
call := f.listCalls[f.listCallCounter]
|
||||||
f.listCallCounter++
|
f.listCallCounter++
|
||||||
@@ -1241,7 +1406,7 @@ func (f *fakeSnapshotter) GetSnapshotStatus(ctx context.Context, snapshotID stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, 0, fmt.Errorf("unexpected call")
|
return false, time.Time{}, 0, fmt.Errorf("unexpected call")
|
||||||
}
|
}
|
||||||
|
|
||||||
return call.readyToUse, call.createTime, call.size, call.err
|
return call.readyToUse, call.createTime, call.size, call.err
|
||||||
|
@@ -192,11 +192,19 @@ func (ctrl *csiSnapshotController) syncSnapshot(snapshot *crdv1.VolumeSnapshot)
|
|||||||
return ctrl.addSnapshotFinalizer(snapshot)
|
return ctrl.addSnapshotFinalizer(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
klog.V(5).Infof("syncSnapshot[%s]: check if we should remove finalizer on snapshot source and remove it if we can", snapshotKey(snapshot))
|
||||||
|
// Check if we should remove finalizer on snapshot source and remove it if we can.
|
||||||
|
errFinalizer := ctrl.checkandRemoveSnapshotSourceFinalizer(snapshot)
|
||||||
|
if errFinalizer != nil {
|
||||||
|
klog.Errorf("error check and remove snapshot source finalizer for snapshot [%s]: %v", snapshot.Name, errFinalizer)
|
||||||
|
// Log an event and keep the original error from syncUnready/ReadySnapshot
|
||||||
|
ctrl.eventRecorder.Event(snapshot, v1.EventTypeWarning, "ErrorSnapshotSourceFinalizer", "Error check and remove PVC Finalizer for VolumeSnapshot")
|
||||||
|
}
|
||||||
|
|
||||||
if !snapshot.Status.ReadyToUse {
|
if !snapshot.Status.ReadyToUse {
|
||||||
return ctrl.syncUnreadySnapshot(snapshot)
|
return ctrl.syncUnreadySnapshot(snapshot)
|
||||||
}
|
}
|
||||||
return ctrl.syncReadySnapshot(snapshot)
|
return ctrl.syncReadySnapshot(snapshot)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// syncReadySnapshot checks the snapshot which has been bound to snapshot content successfully before.
|
// syncReadySnapshot checks the snapshot which has been bound to snapshot content successfully before.
|
||||||
@@ -367,7 +375,6 @@ func (ctrl *csiSnapshotController) createSnapshot(snapshot *crdv1.VolumeSnapshot
|
|||||||
// We will get an "snapshot update" event soon, this is not a big error
|
// We will get an "snapshot update" event soon, this is not a big error
|
||||||
klog.V(4).Infof("createSnapshot [%s]: cannot update internal cache: %v", snapshotKey(snapshotObj), updateErr)
|
klog.V(4).Infof("createSnapshot [%s]: cannot update internal cache: %v", snapshotKey(snapshotObj), updateErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
@@ -451,7 +458,7 @@ func IsSnapshotBound(snapshot *crdv1.VolumeSnapshot, content *crdv1.VolumeSnapsh
|
|||||||
// isSnapshotConentBeingUsed checks if snapshot content is bound to snapshot.
|
// isSnapshotConentBeingUsed checks if snapshot content is bound to snapshot.
|
||||||
func (ctrl *csiSnapshotController) isSnapshotContentBeingUsed(content *crdv1.VolumeSnapshotContent) bool {
|
func (ctrl *csiSnapshotController) isSnapshotContentBeingUsed(content *crdv1.VolumeSnapshotContent) bool {
|
||||||
if content.Spec.VolumeSnapshotRef != nil {
|
if content.Spec.VolumeSnapshotRef != nil {
|
||||||
snapshotObj, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshots(content.Spec.VolumeSnapshotRef.Namespace).Get(content.Spec.VolumeSnapshotRef.Name, metav1.GetOptions{})
|
snapshotObj, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(content.Spec.VolumeSnapshotRef.Namespace).Get(content.Spec.VolumeSnapshotRef.Name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Infof("isSnapshotContentBeingUsed: Cannot get snapshot %s from api server: [%v]. VolumeSnapshot object may be deleted already.", content.Spec.VolumeSnapshotRef.Name, err)
|
klog.Infof("isSnapshotContentBeingUsed: Cannot get snapshot %s from api server: [%v]. VolumeSnapshot object may be deleted already.", content.Spec.VolumeSnapshotRef.Name, err)
|
||||||
return false
|
return false
|
||||||
@@ -503,7 +510,7 @@ func (ctrl *csiSnapshotController) checkandBindSnapshotContent(snapshot *crdv1.V
|
|||||||
contentClone.Spec.VolumeSnapshotRef.UID = snapshot.UID
|
contentClone.Spec.VolumeSnapshotRef.UID = snapshot.UID
|
||||||
className := *(snapshot.Spec.VolumeSnapshotClassName)
|
className := *(snapshot.Spec.VolumeSnapshotClassName)
|
||||||
contentClone.Spec.VolumeSnapshotClassName = &className
|
contentClone.Spec.VolumeSnapshotClassName = &className
|
||||||
newContent, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
|
newContent, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.V(4).Infof("updating VolumeSnapshotContent[%s] error status failed %v", newContent.Name, err)
|
klog.V(4).Infof("updating VolumeSnapshotContent[%s] error status failed %v", newContent.Name, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -556,7 +563,7 @@ func (ctrl *csiSnapshotController) getCreateSnapshotInput(snapshot *crdv1.Volume
|
|||||||
|
|
||||||
func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(snapshot *crdv1.VolumeSnapshot, content *crdv1.VolumeSnapshotContent) (*crdv1.VolumeSnapshot, error) {
|
func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(snapshot *crdv1.VolumeSnapshot, content *crdv1.VolumeSnapshotContent) (*crdv1.VolumeSnapshot, error) {
|
||||||
var err error
|
var err error
|
||||||
var timestamp int64
|
var creationTime time.Time
|
||||||
var size int64
|
var size int64
|
||||||
var readyToUse = false
|
var readyToUse = false
|
||||||
var driverName string
|
var driverName string
|
||||||
@@ -564,7 +571,7 @@ func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(sn
|
|||||||
|
|
||||||
if snapshot.Spec.Source == nil {
|
if snapshot.Spec.Source == nil {
|
||||||
klog.V(5).Infof("checkandUpdateBoundSnapshotStatusOperation: checking whether snapshot [%s] is pre-bound to content [%s]", snapshot.Name, content.Name)
|
klog.V(5).Infof("checkandUpdateBoundSnapshotStatusOperation: checking whether snapshot [%s] is pre-bound to content [%s]", snapshot.Name, content.Name)
|
||||||
readyToUse, timestamp, size, err = ctrl.handler.GetSnapshotStatus(content)
|
readyToUse, creationTime, size, err = ctrl.handler.GetSnapshotStatus(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("checkandUpdateBoundSnapshotStatusOperation: failed to call get snapshot status to check whether snapshot is ready to use %q", err)
|
klog.Errorf("checkandUpdateBoundSnapshotStatusOperation: failed to call get snapshot status to check whether snapshot is ready to use %q", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -577,18 +584,18 @@ func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(sn
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get input parameters to create snapshot %s: %q", snapshot.Name, err)
|
return nil, fmt.Errorf("failed to get input parameters to create snapshot %s: %q", snapshot.Name, err)
|
||||||
}
|
}
|
||||||
driverName, snapshotID, timestamp, size, readyToUse, err = ctrl.handler.CreateSnapshot(snapshot, volume, class.Parameters, snapshotterCredentials)
|
driverName, snapshotID, creationTime, size, readyToUse, err = ctrl.handler.CreateSnapshot(snapshot, volume, class.Parameters, snapshotterCredentials)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("checkandUpdateBoundSnapshotStatusOperation: failed to call create snapshot to check whether the snapshot is ready to use %q", err)
|
klog.Errorf("checkandUpdateBoundSnapshotStatusOperation: failed to call create snapshot to check whether the snapshot is ready to use %q", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
klog.V(5).Infof("checkandUpdateBoundSnapshotStatusOperation: driver %s, snapshotId %s, timestamp %d, size %d, readyToUse %t", driverName, snapshotID, timestamp, size, readyToUse)
|
klog.V(5).Infof("checkandUpdateBoundSnapshotStatusOperation: driver %s, snapshotId %s, creationTime %v, size %d, readyToUse %t", driverName, snapshotID, creationTime, size, readyToUse)
|
||||||
|
|
||||||
if timestamp == 0 {
|
if creationTime.IsZero() {
|
||||||
timestamp = time.Now().UnixNano()
|
creationTime = time.Now()
|
||||||
}
|
}
|
||||||
newSnapshot, err := ctrl.updateSnapshotStatus(snapshot, readyToUse, timestamp, size, IsSnapshotBound(snapshot, content))
|
newSnapshot, err := ctrl.updateSnapshotStatus(snapshot, readyToUse, creationTime, size, IsSnapshotBound(snapshot, content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -612,22 +619,31 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
|
|||||||
return snapshot, nil
|
return snapshot, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If PVC is not being deleted and finalizer is not added yet, a finalizer should be added.
|
||||||
|
klog.V(5).Infof("createSnapshotOperation: Check if PVC is not being deleted and add Finalizer for source of snapshot [%s] if needed", snapshot.Name)
|
||||||
|
err := ctrl.ensureSnapshotSourceFinalizer(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("createSnapshotOperation failed to add finalizer for source of snapshot %s", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
class, volume, contentName, snapshotterCredentials, err := ctrl.getCreateSnapshotInput(snapshot)
|
class, volume, contentName, snapshotterCredentials, err := ctrl.getCreateSnapshotInput(snapshot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get input parameters to create snapshot %s: %q", snapshot.Name, err)
|
return nil, fmt.Errorf("failed to get input parameters to create snapshot %s: %q", snapshot.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
driverName, snapshotID, timestamp, size, readyToUse, err := ctrl.handler.CreateSnapshot(snapshot, volume, class.Parameters, snapshotterCredentials)
|
driverName, snapshotID, creationTime, size, readyToUse, err := ctrl.handler.CreateSnapshot(snapshot, volume, class.Parameters, snapshotterCredentials)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to take snapshot of the volume, %s: %q", volume.Name, err)
|
return nil, fmt.Errorf("failed to take snapshot of the volume, %s: %q", volume.Name, err)
|
||||||
}
|
}
|
||||||
klog.V(5).Infof("Created snapshot: driver %s, snapshotId %s, timestamp %d, size %d, readyToUse %t", driverName, snapshotID, timestamp, size, readyToUse)
|
|
||||||
|
klog.V(5).Infof("Created snapshot: driver %s, snapshotId %s, creationTime %v, size %d, readyToUse %t", driverName, snapshotID, creationTime, size, readyToUse)
|
||||||
|
|
||||||
var newSnapshot *crdv1.VolumeSnapshot
|
var newSnapshot *crdv1.VolumeSnapshot
|
||||||
// Update snapshot status with timestamp
|
// Update snapshot status with creationTime
|
||||||
for i := 0; i < ctrl.createSnapshotContentRetryCount; i++ {
|
for i := 0; i < ctrl.createSnapshotContentRetryCount; i++ {
|
||||||
klog.V(5).Infof("createSnapshot [%s]: trying to update snapshot creation timestamp", snapshotKey(snapshot))
|
klog.V(5).Infof("createSnapshot [%s]: trying to update snapshot creation timestamp", snapshotKey(snapshot))
|
||||||
newSnapshot, err = ctrl.updateSnapshotStatus(snapshot, readyToUse, timestamp, size, false)
|
newSnapshot, err = ctrl.updateSnapshotStatus(snapshot, readyToUse, creationTime, size, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -651,6 +667,7 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
|
|||||||
class.DeletionPolicy = new(crdv1.DeletionPolicy)
|
class.DeletionPolicy = new(crdv1.DeletionPolicy)
|
||||||
*class.DeletionPolicy = crdv1.VolumeSnapshotContentDelete
|
*class.DeletionPolicy = crdv1.VolumeSnapshotContentDelete
|
||||||
}
|
}
|
||||||
|
timestamp := creationTime.UnixNano()
|
||||||
snapshotContent := &crdv1.VolumeSnapshotContent{
|
snapshotContent := &crdv1.VolumeSnapshotContent{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: contentName,
|
Name: contentName,
|
||||||
@@ -674,7 +691,7 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
|
|||||||
// Try to create the VolumeSnapshotContent object several times
|
// Try to create the VolumeSnapshotContent object several times
|
||||||
for i := 0; i < ctrl.createSnapshotContentRetryCount; i++ {
|
for i := 0; i < ctrl.createSnapshotContentRetryCount; i++ {
|
||||||
klog.V(5).Infof("createSnapshot [%s]: trying to save volume snapshot content %s", snapshotKey(snapshot), snapshotContent.Name)
|
klog.V(5).Infof("createSnapshot [%s]: trying to save volume snapshot content %s", snapshotKey(snapshot), snapshotContent.Name)
|
||||||
if _, err = ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshotContents().Create(snapshotContent); err == nil || apierrs.IsAlreadyExists(err) {
|
if _, err = ctrl.clientset.SnapshotV1alpha1().VolumeSnapshotContents().Create(snapshotContent); err == nil || apierrs.IsAlreadyExists(err) {
|
||||||
// Save succeeded.
|
// Save succeeded.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.V(3).Infof("volume snapshot content %q for snapshot %q already exists, reusing", snapshotContent.Name, snapshotKey(snapshot))
|
klog.V(3).Infof("volume snapshot content %q for snapshot %q already exists, reusing", snapshotContent.Name, snapshotKey(snapshot))
|
||||||
@@ -741,7 +758,7 @@ func (ctrl *csiSnapshotController) deleteSnapshotContentOperation(content *crdv1
|
|||||||
return fmt.Errorf("failed to delete snapshot %#v, err: %v", content.Name, err)
|
return fmt.Errorf("failed to delete snapshot %#v, err: %v", content.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshotContents().Delete(content.Name, &metav1.DeleteOptions{})
|
err = ctrl.clientset.SnapshotV1alpha1().VolumeSnapshotContents().Delete(content.Name, &metav1.DeleteOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotContentObjectDeleteError", "Failed to delete snapshot content API object")
|
ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotContentObjectDeleteError", "Failed to delete snapshot content API object")
|
||||||
return fmt.Errorf("failed to delete VolumeSnapshotContent %s from API server: %q", content.Name, err)
|
return fmt.Errorf("failed to delete VolumeSnapshotContent %s from API server: %q", content.Name, err)
|
||||||
@@ -752,7 +769,7 @@ func (ctrl *csiSnapshotController) deleteSnapshotContentOperation(content *crdv1
|
|||||||
|
|
||||||
func (ctrl *csiSnapshotController) bindandUpdateVolumeSnapshot(snapshotContent *crdv1.VolumeSnapshotContent, snapshot *crdv1.VolumeSnapshot) (*crdv1.VolumeSnapshot, error) {
|
func (ctrl *csiSnapshotController) bindandUpdateVolumeSnapshot(snapshotContent *crdv1.VolumeSnapshotContent, snapshot *crdv1.VolumeSnapshot) (*crdv1.VolumeSnapshot, error) {
|
||||||
klog.V(5).Infof("bindandUpdateVolumeSnapshot for snapshot [%s]: snapshotContent [%s]", snapshot.Name, snapshotContent.Name)
|
klog.V(5).Infof("bindandUpdateVolumeSnapshot for snapshot [%s]: snapshotContent [%s]", snapshot.Name, snapshotContent.Name)
|
||||||
snapshotObj, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshots(snapshot.Namespace).Get(snapshot.Name, metav1.GetOptions{})
|
snapshotObj, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshot.Namespace).Get(snapshot.Name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error get snapshot %s from api server: %v", snapshotKey(snapshot), err)
|
return nil, fmt.Errorf("error get snapshot %s from api server: %v", snapshotKey(snapshot), err)
|
||||||
}
|
}
|
||||||
@@ -765,7 +782,7 @@ func (ctrl *csiSnapshotController) bindandUpdateVolumeSnapshot(snapshotContent *
|
|||||||
} else {
|
} else {
|
||||||
klog.Infof("bindVolumeSnapshotContentToVolumeSnapshot: before bind VolumeSnapshot %s to volumeSnapshotContent [%s]", snapshot.Name, snapshotContent.Name)
|
klog.Infof("bindVolumeSnapshotContentToVolumeSnapshot: before bind VolumeSnapshot %s to volumeSnapshotContent [%s]", snapshot.Name, snapshotContent.Name)
|
||||||
snapshotCopy.Spec.SnapshotContentName = snapshotContent.Name
|
snapshotCopy.Spec.SnapshotContentName = snapshotContent.Name
|
||||||
updateSnapshot, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshots(snapshot.Namespace).Update(snapshotCopy)
|
updateSnapshot, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshot.Namespace).Update(snapshotCopy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Infof("bindVolumeSnapshotContentToVolumeSnapshot: Error binding VolumeSnapshot %s to volumeSnapshotContent [%s]. Error [%#v]", snapshot.Name, snapshotContent.Name, err)
|
klog.Infof("bindVolumeSnapshotContentToVolumeSnapshot: Error binding VolumeSnapshot %s to volumeSnapshotContent [%s]. Error [%#v]", snapshot.Name, snapshotContent.Name, err)
|
||||||
return nil, newControllerUpdateError(snapshotKey(snapshot), err.Error())
|
return nil, newControllerUpdateError(snapshotKey(snapshot), err.Error())
|
||||||
@@ -791,7 +808,7 @@ func (ctrl *csiSnapshotController) updateSnapshotContentSize(content *crdv1.Volu
|
|||||||
}
|
}
|
||||||
contentClone := content.DeepCopy()
|
contentClone := content.DeepCopy()
|
||||||
contentClone.Spec.VolumeSnapshotSource.CSI.RestoreSize = &size
|
contentClone.Spec.VolumeSnapshotSource.CSI.RestoreSize = &size
|
||||||
_, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
|
_, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newControllerUpdateError(content.Name, err.Error())
|
return newControllerUpdateError(content.Name, err.Error())
|
||||||
}
|
}
|
||||||
@@ -804,12 +821,12 @@ func (ctrl *csiSnapshotController) updateSnapshotContentSize(content *crdv1.Volu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSnapshotStatus converts snapshot status to crdv1.VolumeSnapshotCondition
|
// UpdateSnapshotStatus converts snapshot status to crdv1.VolumeSnapshotCondition
|
||||||
func (ctrl *csiSnapshotController) updateSnapshotStatus(snapshot *crdv1.VolumeSnapshot, readyToUse bool, createdAt, size int64, bound bool) (*crdv1.VolumeSnapshot, error) {
|
func (ctrl *csiSnapshotController) updateSnapshotStatus(snapshot *crdv1.VolumeSnapshot, readyToUse bool, createdAt time.Time, size int64, bound bool) (*crdv1.VolumeSnapshot, error) {
|
||||||
klog.V(5).Infof("updating VolumeSnapshot[]%s, readyToUse %v, timestamp %v", snapshotKey(snapshot), readyToUse, createdAt)
|
klog.V(5).Infof("updating VolumeSnapshot[]%s, readyToUse %v, timestamp %v", snapshotKey(snapshot), readyToUse, createdAt)
|
||||||
status := snapshot.Status
|
status := snapshot.Status
|
||||||
change := false
|
change := false
|
||||||
timeAt := &metav1.Time{
|
timeAt := &metav1.Time{
|
||||||
Time: time.Unix(0, createdAt),
|
Time: createdAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotClone := snapshot.DeepCopy()
|
snapshotClone := snapshot.DeepCopy()
|
||||||
@@ -932,7 +949,7 @@ func (ctrl *csiSnapshotController) SetDefaultSnapshotClass(snapshot *crdv1.Volum
|
|||||||
klog.V(5).Infof("setDefaultSnapshotClass [%s]: default VolumeSnapshotClassName [%s]", snapshot.Name, defaultClasses[0].Name)
|
klog.V(5).Infof("setDefaultSnapshotClass [%s]: default VolumeSnapshotClassName [%s]", snapshot.Name, defaultClasses[0].Name)
|
||||||
snapshotClone := snapshot.DeepCopy()
|
snapshotClone := snapshot.DeepCopy()
|
||||||
snapshotClone.Spec.VolumeSnapshotClassName = &(defaultClasses[0].Name)
|
snapshotClone.Spec.VolumeSnapshotClassName = &(defaultClasses[0].Name)
|
||||||
newSnapshot, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone)
|
newSnapshot, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.V(4).Infof("updating VolumeSnapshot[%s] default class failed %v", snapshotKey(snapshot), err)
|
klog.V(4).Infof("updating VolumeSnapshot[%s] default class failed %v", snapshotKey(snapshot), err)
|
||||||
}
|
}
|
||||||
@@ -999,7 +1016,7 @@ func (ctrl *csiSnapshotController) addContentFinalizer(content *crdv1.VolumeSnap
|
|||||||
contentClone := content.DeepCopy()
|
contentClone := content.DeepCopy()
|
||||||
contentClone.ObjectMeta.Finalizers = append(contentClone.ObjectMeta.Finalizers, VolumeSnapshotContentFinalizer)
|
contentClone.ObjectMeta.Finalizers = append(contentClone.ObjectMeta.Finalizers, VolumeSnapshotContentFinalizer)
|
||||||
|
|
||||||
_, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
|
_, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newControllerUpdateError(content.Name, err.Error())
|
return newControllerUpdateError(content.Name, err.Error())
|
||||||
}
|
}
|
||||||
@@ -1018,7 +1035,7 @@ func (ctrl *csiSnapshotController) removeContentFinalizer(content *crdv1.VolumeS
|
|||||||
contentClone := content.DeepCopy()
|
contentClone := content.DeepCopy()
|
||||||
contentClone.ObjectMeta.Finalizers = slice.RemoveString(contentClone.ObjectMeta.Finalizers, VolumeSnapshotContentFinalizer, nil)
|
contentClone.ObjectMeta.Finalizers = slice.RemoveString(contentClone.ObjectMeta.Finalizers, VolumeSnapshotContentFinalizer, nil)
|
||||||
|
|
||||||
_, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
|
_, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newControllerUpdateError(content.Name, err.Error())
|
return newControllerUpdateError(content.Name, err.Error())
|
||||||
}
|
}
|
||||||
@@ -1036,7 +1053,7 @@ func (ctrl *csiSnapshotController) removeContentFinalizer(content *crdv1.VolumeS
|
|||||||
func (ctrl *csiSnapshotController) addSnapshotFinalizer(snapshot *crdv1.VolumeSnapshot) error {
|
func (ctrl *csiSnapshotController) addSnapshotFinalizer(snapshot *crdv1.VolumeSnapshot) error {
|
||||||
snapshotClone := snapshot.DeepCopy()
|
snapshotClone := snapshot.DeepCopy()
|
||||||
snapshotClone.ObjectMeta.Finalizers = append(snapshotClone.ObjectMeta.Finalizers, VolumeSnapshotFinalizer)
|
snapshotClone.ObjectMeta.Finalizers = append(snapshotClone.ObjectMeta.Finalizers, VolumeSnapshotFinalizer)
|
||||||
_, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone)
|
_, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newControllerUpdateError(snapshot.Name, err.Error())
|
return newControllerUpdateError(snapshot.Name, err.Error())
|
||||||
}
|
}
|
||||||
@@ -1055,7 +1072,7 @@ func (ctrl *csiSnapshotController) removeSnapshotFinalizer(snapshot *crdv1.Volum
|
|||||||
snapshotClone := snapshot.DeepCopy()
|
snapshotClone := snapshot.DeepCopy()
|
||||||
snapshotClone.ObjectMeta.Finalizers = slice.RemoveString(snapshotClone.ObjectMeta.Finalizers, VolumeSnapshotFinalizer, nil)
|
snapshotClone.ObjectMeta.Finalizers = slice.RemoveString(snapshotClone.ObjectMeta.Finalizers, VolumeSnapshotFinalizer, nil)
|
||||||
|
|
||||||
_, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone)
|
_, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newControllerUpdateError(snapshot.Name, err.Error())
|
return newControllerUpdateError(snapshot.Name, err.Error())
|
||||||
}
|
}
|
||||||
@@ -1068,3 +1085,113 @@ func (ctrl *csiSnapshotController) removeSnapshotFinalizer(snapshot *crdv1.Volum
|
|||||||
klog.V(5).Infof("Removed protection finalizer from volume snapshot %s", snapshotKey(snapshot))
|
klog.V(5).Infof("Removed protection finalizer from volume snapshot %s", snapshotKey(snapshot))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensureSnapshotSourceFinalizer checks if a Finalizer needs to be added for the snapshot source;
|
||||||
|
// if true, adds a Finalizer for VolumeSnapshot Source PVC
|
||||||
|
func (ctrl *csiSnapshotController) ensureSnapshotSourceFinalizer(snapshot *crdv1.VolumeSnapshot) error {
|
||||||
|
// Get snapshot source which is a PVC
|
||||||
|
pvc, err := ctrl.getClaimFromVolumeSnapshot(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
klog.Infof("cannot get claim from snapshot [%s]: [%v] Claim may be deleted already.", snapshot.Name, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If PVC is not being deleted and PVCFinalizer is not added yet, the PVCFinalizer should be added.
|
||||||
|
if pvc.ObjectMeta.DeletionTimestamp == nil && !slice.ContainsString(pvc.ObjectMeta.Finalizers, PVCFinalizer, nil) {
|
||||||
|
// Add the finalizer
|
||||||
|
pvcClone := pvc.DeepCopy()
|
||||||
|
pvcClone.ObjectMeta.Finalizers = append(pvcClone.ObjectMeta.Finalizers, PVCFinalizer)
|
||||||
|
_, err = ctrl.client.CoreV1().PersistentVolumeClaims(pvcClone.Namespace).Update(pvcClone)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("cannot add finalizer on claim [%s] for snapshot [%s]: [%v]", pvc.Name, snapshot.Name, err)
|
||||||
|
return newControllerUpdateError(pvcClone.Name, err.Error())
|
||||||
|
}
|
||||||
|
klog.Infof("Added protection finalizer to persistent volume claim %s", pvc.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeSnapshotSourceFinalizer removes a Finalizer for VolumeSnapshot Source PVC.
|
||||||
|
func (ctrl *csiSnapshotController) removeSnapshotSourceFinalizer(snapshot *crdv1.VolumeSnapshot) error {
|
||||||
|
// Get snapshot source which is a PVC
|
||||||
|
pvc, err := ctrl.getClaimFromVolumeSnapshot(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
klog.Infof("cannot get claim from snapshot [%s]: [%v] Claim may be deleted already. No need to remove finalizer on the claim.", snapshot.Name, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pvcClone := pvc.DeepCopy()
|
||||||
|
pvcClone.ObjectMeta.Finalizers = slice.RemoveString(pvcClone.ObjectMeta.Finalizers, PVCFinalizer, nil)
|
||||||
|
|
||||||
|
_, err = ctrl.client.CoreV1().PersistentVolumeClaims(pvcClone.Namespace).Update(pvcClone)
|
||||||
|
if err != nil {
|
||||||
|
return newControllerUpdateError(pvcClone.Name, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(5).Infof("Removed protection finalizer from persistent volume claim %s", pvc.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// isSnapshotSourceBeingUsed checks if a PVC is being used as a source to create a snapshot
|
||||||
|
func (ctrl *csiSnapshotController) isSnapshotSourceBeingUsed(snapshot *crdv1.VolumeSnapshot) bool {
|
||||||
|
klog.V(5).Infof("isSnapshotSourceBeingUsed[%s]: started", snapshotKey(snapshot))
|
||||||
|
// Get snapshot source which is a PVC
|
||||||
|
pvc, err := ctrl.getClaimFromVolumeSnapshot(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
klog.Infof("isSnapshotSourceBeingUsed: cannot to get claim from snapshot: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Going through snapshots in the cache (snapshotLister). If a snapshot's PVC source
|
||||||
|
// is the same as the input snapshot's PVC source and snapshot's ReadyToUse status
|
||||||
|
// is false, the snapshot is still being created from the PVC and the PVC is in-use.
|
||||||
|
snapshots, err := ctrl.snapshotLister.VolumeSnapshots(snapshot.Namespace).List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, snap := range snapshots {
|
||||||
|
// Skip static bound snapshot without a PVC source
|
||||||
|
if snap.Spec.Source == nil {
|
||||||
|
klog.V(4).Infof("Skipping static bound snapshot %s when checking PVC %s/%s", snap.Name, pvc.Namespace, pvc.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pvc.Name == snap.Spec.Source.Name && snap.Status.ReadyToUse == false {
|
||||||
|
klog.V(2).Infof("Keeping PVC %s/%s, it is used by snapshot %s/%s", pvc.Namespace, pvc.Name, snap.Namespace, snap.Name)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(5).Infof("isSnapshotSourceBeingUsed: no snapshot is being created from PVC %s/%s", pvc.Namespace, pvc.Name)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkandRemoveSnapshotSourceFinalizer checks if the snapshot source finalizer should be removed
|
||||||
|
// and removed it if needed.
|
||||||
|
func (ctrl *csiSnapshotController) checkandRemoveSnapshotSourceFinalizer(snapshot *crdv1.VolumeSnapshot) error {
|
||||||
|
// Get snapshot source which is a PVC
|
||||||
|
pvc, err := ctrl.getClaimFromVolumeSnapshot(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
klog.Infof("cannot get claim from snapshot [%s]: [%v] Claim may be deleted already. No need to remove finalizer on the claim.", snapshot.Name, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(5).Infof("checkandRemoveSnapshotSourceFinalizer for snapshot [%s]: snapshot status [%#v]", snapshot.Name, snapshot.Status)
|
||||||
|
|
||||||
|
// Check if there is a Finalizer on PVC to be removed
|
||||||
|
if slice.ContainsString(pvc.ObjectMeta.Finalizers, PVCFinalizer, nil) {
|
||||||
|
// There is a Finalizer on PVC. Check if PVC is used
|
||||||
|
// and remove finalizer if it's not used.
|
||||||
|
isUsed := ctrl.isSnapshotSourceBeingUsed(snapshot)
|
||||||
|
if !isUsed {
|
||||||
|
klog.Infof("checkandRemoveSnapshotSourceFinalizer[%s]: Remove Finalizer for PVC %s as it is not used by snapshots in creation", snapshot.Name, pvc.Name)
|
||||||
|
err = ctrl.removeSnapshotSourceFinalizer(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("checkandRemoveSnapshotSourceFinalizer [%s]: removeSnapshotSourceFinalizer failed to remove finalizer %v", snapshot.Name, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -27,10 +27,11 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var timeNow = time.Now().UnixNano()
|
var timeNow = time.Now()
|
||||||
|
var timeNowStamp = timeNow.UnixNano()
|
||||||
|
|
||||||
var metaTimeNowUnix = &metav1.Time{
|
var metaTimeNowUnix = &metav1.Time{
|
||||||
Time: time.Unix(0, timeNow),
|
Time: timeNow,
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultSize int64 = 1000
|
var defaultSize int64 = 1000
|
||||||
@@ -68,7 +69,7 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "6-1 - successful create snapshot with snapshot class gold",
|
name: "6-1 - successful create snapshot with snapshot class gold",
|
||||||
initialContents: nocontents,
|
initialContents: nocontents,
|
||||||
expectedContents: newContentArray("snapcontent-snapuid6-1", classGold, "sid6-1", "pv-uid6-1", "volume6-1", "snapuid6-1", "snap6-1", &deletePolicy, &defaultSize, &timeNow, false),
|
expectedContents: newContentArray("snapcontent-snapuid6-1", classGold, "sid6-1", "pv-uid6-1", "volume6-1", "snapuid6-1", "snap6-1", &deletePolicy, &defaultSize, &timeNowStamp, false),
|
||||||
initialSnapshots: newSnapshotArray("snap6-1", classGold, "", "snapuid6-1", "claim6-1", false, nil, nil, nil),
|
initialSnapshots: newSnapshotArray("snap6-1", classGold, "", "snapuid6-1", "claim6-1", false, nil, nil, nil),
|
||||||
expectedSnapshots: newSnapshotArray("snap6-1", classGold, "snapcontent-snapuid6-1", "snapuid6-1", "claim6-1", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
expectedSnapshots: newSnapshotArray("snap6-1", classGold, "snapcontent-snapuid6-1", "snapuid6-1", "claim6-1", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
||||||
initialClaims: newClaimArray("claim6-1", "pvc-uid6-1", "1Gi", "volume6-1", v1.ClaimBound, &classEmpty),
|
initialClaims: newClaimArray("claim6-1", "pvc-uid6-1", "1Gi", "volume6-1", v1.ClaimBound, &classEmpty),
|
||||||
@@ -79,11 +80,11 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
volume: newVolume("volume6-1", "pv-uid6-1", "pv-handle6-1", "1Gi", "pvc-uid6-1", "claim6-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
volume: newVolume("volume6-1", "pv-uid6-1", "pv-handle6-1", "1Gi", "pvc-uid6-1", "claim6-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
||||||
parameters: map[string]string{"param1": "value1"},
|
parameters: map[string]string{"param1": "value1"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid6-1",
|
snapshotId: "sid6-1",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: noerrors,
|
errors: noerrors,
|
||||||
@@ -92,7 +93,7 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "6-2 - successful create snapshot with snapshot class silver",
|
name: "6-2 - successful create snapshot with snapshot class silver",
|
||||||
initialContents: nocontents,
|
initialContents: nocontents,
|
||||||
expectedContents: newContentArray("snapcontent-snapuid6-2", classSilver, "sid6-2", "pv-uid6-2", "volume6-2", "snapuid6-2", "snap6-2", &deletePolicy, &defaultSize, &timeNow, false),
|
expectedContents: newContentArray("snapcontent-snapuid6-2", classSilver, "sid6-2", "pv-uid6-2", "volume6-2", "snapuid6-2", "snap6-2", &deletePolicy, &defaultSize, &timeNowStamp, false),
|
||||||
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil),
|
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil),
|
||||||
expectedSnapshots: newSnapshotArray("snap6-2", classSilver, "snapcontent-snapuid6-2", "snapuid6-2", "claim6-2", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
expectedSnapshots: newSnapshotArray("snap6-2", classSilver, "snapcontent-snapuid6-2", "snapuid6-2", "claim6-2", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
||||||
initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
|
initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
|
||||||
@@ -103,11 +104,11 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
volume: newVolume("volume6-2", "pv-uid6-2", "pv-handle6-2", "1Gi", "pvc-uid6-2", "claim6-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
volume: newVolume("volume6-2", "pv-uid6-2", "pv-handle6-2", "1Gi", "pvc-uid6-2", "claim6-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
||||||
parameters: map[string]string{"param2": "value2"},
|
parameters: map[string]string{"param2": "value2"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid6-2",
|
snapshotId: "sid6-2",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: noerrors,
|
errors: noerrors,
|
||||||
@@ -116,7 +117,7 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "6-3 - successful create snapshot with snapshot class valid-secret-class",
|
name: "6-3 - successful create snapshot with snapshot class valid-secret-class",
|
||||||
initialContents: nocontents,
|
initialContents: nocontents,
|
||||||
expectedContents: newContentArray("snapcontent-snapuid6-3", validSecretClass, "sid6-3", "pv-uid6-3", "volume6-3", "snapuid6-3", "snap6-3", &deletePolicy, &defaultSize, &timeNow, false),
|
expectedContents: newContentArray("snapcontent-snapuid6-3", validSecretClass, "sid6-3", "pv-uid6-3", "volume6-3", "snapuid6-3", "snap6-3", &deletePolicy, &defaultSize, &timeNowStamp, false),
|
||||||
initialSnapshots: newSnapshotArray("snap6-3", validSecretClass, "", "snapuid6-3", "claim6-3", false, nil, nil, nil),
|
initialSnapshots: newSnapshotArray("snap6-3", validSecretClass, "", "snapuid6-3", "claim6-3", false, nil, nil, nil),
|
||||||
expectedSnapshots: newSnapshotArray("snap6-3", validSecretClass, "snapcontent-snapuid6-3", "snapuid6-3", "claim6-3", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
expectedSnapshots: newSnapshotArray("snap6-3", validSecretClass, "snapcontent-snapuid6-3", "snapuid6-3", "claim6-3", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
||||||
initialClaims: newClaimArray("claim6-3", "pvc-uid6-3", "1Gi", "volume6-3", v1.ClaimBound, &classEmpty),
|
initialClaims: newClaimArray("claim6-3", "pvc-uid6-3", "1Gi", "volume6-3", v1.ClaimBound, &classEmpty),
|
||||||
@@ -129,11 +130,11 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
parameters: class5Parameters,
|
parameters: class5Parameters,
|
||||||
secrets: map[string]string{"foo": "bar"},
|
secrets: map[string]string{"foo": "bar"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid6-3",
|
snapshotId: "sid6-3",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: noerrors,
|
errors: noerrors,
|
||||||
@@ -142,7 +143,7 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "6-4 - successful create snapshot with snapshot class empty-secret-class",
|
name: "6-4 - successful create snapshot with snapshot class empty-secret-class",
|
||||||
initialContents: nocontents,
|
initialContents: nocontents,
|
||||||
expectedContents: newContentArray("snapcontent-snapuid6-4", emptySecretClass, "sid6-4", "pv-uid6-4", "volume6-4", "snapuid6-4", "snap6-4", &deletePolicy, &defaultSize, &timeNow, false),
|
expectedContents: newContentArray("snapcontent-snapuid6-4", emptySecretClass, "sid6-4", "pv-uid6-4", "volume6-4", "snapuid6-4", "snap6-4", &deletePolicy, &defaultSize, &timeNowStamp, false),
|
||||||
initialSnapshots: newSnapshotArray("snap6-4", emptySecretClass, "", "snapuid6-4", "claim6-4", false, nil, nil, nil),
|
initialSnapshots: newSnapshotArray("snap6-4", emptySecretClass, "", "snapuid6-4", "claim6-4", false, nil, nil, nil),
|
||||||
expectedSnapshots: newSnapshotArray("snap6-4", emptySecretClass, "snapcontent-snapuid6-4", "snapuid6-4", "claim6-4", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
expectedSnapshots: newSnapshotArray("snap6-4", emptySecretClass, "snapcontent-snapuid6-4", "snapuid6-4", "claim6-4", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
||||||
initialClaims: newClaimArray("claim6-4", "pvc-uid6-4", "1Gi", "volume6-4", v1.ClaimBound, &classEmpty),
|
initialClaims: newClaimArray("claim6-4", "pvc-uid6-4", "1Gi", "volume6-4", v1.ClaimBound, &classEmpty),
|
||||||
@@ -155,11 +156,11 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
parameters: class4Parameters,
|
parameters: class4Parameters,
|
||||||
secrets: map[string]string{},
|
secrets: map[string]string{},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid6-4",
|
snapshotId: "sid6-4",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: noerrors,
|
errors: noerrors,
|
||||||
@@ -168,7 +169,7 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "6-5 - successful create snapshot with status uploading",
|
name: "6-5 - successful create snapshot with status uploading",
|
||||||
initialContents: nocontents,
|
initialContents: nocontents,
|
||||||
expectedContents: newContentArray("snapcontent-snapuid6-5", classGold, "sid6-5", "pv-uid6-5", "volume6-5", "snapuid6-5", "snap6-5", &deletePolicy, &defaultSize, &timeNow, false),
|
expectedContents: newContentArray("snapcontent-snapuid6-5", classGold, "sid6-5", "pv-uid6-5", "volume6-5", "snapuid6-5", "snap6-5", &deletePolicy, &defaultSize, &timeNowStamp, false),
|
||||||
initialSnapshots: newSnapshotArray("snap6-5", classGold, "", "snapuid6-5", "claim6-5", false, nil, nil, nil),
|
initialSnapshots: newSnapshotArray("snap6-5", classGold, "", "snapuid6-5", "claim6-5", false, nil, nil, nil),
|
||||||
expectedSnapshots: newSnapshotArray("snap6-5", classGold, "snapcontent-snapuid6-5", "snapuid6-5", "claim6-5", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
expectedSnapshots: newSnapshotArray("snap6-5", classGold, "snapcontent-snapuid6-5", "snapuid6-5", "claim6-5", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
||||||
initialClaims: newClaimArray("claim6-5", "pvc-uid6-5", "1Gi", "volume6-5", v1.ClaimBound, &classEmpty),
|
initialClaims: newClaimArray("claim6-5", "pvc-uid6-5", "1Gi", "volume6-5", v1.ClaimBound, &classEmpty),
|
||||||
@@ -179,11 +180,11 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
volume: newVolume("volume6-5", "pv-uid6-5", "pv-handle6-5", "1Gi", "pvc-uid6-5", "claim6-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
volume: newVolume("volume6-5", "pv-uid6-5", "pv-handle6-5", "1Gi", "pvc-uid6-5", "claim6-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
||||||
parameters: map[string]string{"param1": "value1"},
|
parameters: map[string]string{"param1": "value1"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid6-5",
|
snapshotId: "sid6-5",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: noerrors,
|
errors: noerrors,
|
||||||
@@ -192,7 +193,7 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "6-6 - successful create snapshot with status error uploading",
|
name: "6-6 - successful create snapshot with status error uploading",
|
||||||
initialContents: nocontents,
|
initialContents: nocontents,
|
||||||
expectedContents: newContentArray("snapcontent-snapuid6-6", classGold, "sid6-6", "pv-uid6-6", "volume6-6", "snapuid6-6", "snap6-6", &deletePolicy, &defaultSize, &timeNow, false),
|
expectedContents: newContentArray("snapcontent-snapuid6-6", classGold, "sid6-6", "pv-uid6-6", "volume6-6", "snapuid6-6", "snap6-6", &deletePolicy, &defaultSize, &timeNowStamp, false),
|
||||||
initialSnapshots: newSnapshotArray("snap6-6", classGold, "", "snapuid6-6", "claim6-6", false, nil, nil, nil),
|
initialSnapshots: newSnapshotArray("snap6-6", classGold, "", "snapuid6-6", "claim6-6", false, nil, nil, nil),
|
||||||
expectedSnapshots: newSnapshotArray("snap6-6", classGold, "snapcontent-snapuid6-6", "snapuid6-6", "claim6-6", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
expectedSnapshots: newSnapshotArray("snap6-6", classGold, "snapcontent-snapuid6-6", "snapuid6-6", "claim6-6", false, nil, metaTimeNowUnix, getSize(defaultSize)),
|
||||||
initialClaims: newClaimArray("claim6-6", "pvc-uid6-6", "1Gi", "volume6-6", v1.ClaimBound, &classEmpty),
|
initialClaims: newClaimArray("claim6-6", "pvc-uid6-6", "1Gi", "volume6-6", v1.ClaimBound, &classEmpty),
|
||||||
@@ -203,11 +204,11 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
volume: newVolume("volume6-6", "pv-uid6-6", "pv-handle6-6", "1Gi", "pvc-uid6-6", "claim6-6", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
volume: newVolume("volume6-6", "pv-uid6-6", "pv-handle6-6", "1Gi", "pvc-uid6-6", "claim6-6", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
||||||
parameters: map[string]string{"param1": "value1"},
|
parameters: map[string]string{"param1": "value1"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid6-6",
|
snapshotId: "sid6-6",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: noerrors,
|
errors: noerrors,
|
||||||
@@ -318,11 +319,11 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
volume: newVolume("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
volume: newVolume("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
||||||
parameters: map[string]string{"param1": "value1"},
|
parameters: map[string]string{"param1": "value1"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid7-8",
|
snapshotId: "sid7-8",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: []reactorError{
|
errors: []reactorError{
|
||||||
@@ -349,11 +350,11 @@ func TestCreateSnapshotSync(t *testing.T) {
|
|||||||
volume: newVolume("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
volume: newVolume("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
|
||||||
parameters: map[string]string{"param1": "value1"},
|
parameters: map[string]string{"param1": "value1"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid7-9",
|
snapshotId: "sid7-9",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: []reactorError{
|
errors: []reactorError{
|
||||||
|
67
pkg/controller/snapshot_finalizer_test.go
Normal file
67
pkg/controller/snapshot_finalizer_test.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Test single call to ensureSnapshotSourceFinalizer and checkandRemoveSnapshotSourceFinalizer,
|
||||||
|
// expecting PVCFinalizer to be added or removed
|
||||||
|
func TestPVCFinalizer(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []controllerTest{
|
||||||
|
{
|
||||||
|
name: "1-1 - successful add PVC finalizer",
|
||||||
|
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil),
|
||||||
|
initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
|
||||||
|
test: testAddPVCFinalizer,
|
||||||
|
expectSuccess: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-2 - won't add PVC finalizer; already added",
|
||||||
|
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil),
|
||||||
|
initialClaims: newClaimArrayFinalizer("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
|
||||||
|
test: testAddPVCFinalizer,
|
||||||
|
expectSuccess: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-3 - successful remove PVC finalizer",
|
||||||
|
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil),
|
||||||
|
initialClaims: newClaimArrayFinalizer("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
|
||||||
|
test: testRemovePVCFinalizer,
|
||||||
|
expectSuccess: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-4 - won't remove PVC finalizer; already removed",
|
||||||
|
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil),
|
||||||
|
initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
|
||||||
|
test: testRemovePVCFinalizer,
|
||||||
|
expectSuccess: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-5 - won't remove PVC finalizer; PVC in-use",
|
||||||
|
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil),
|
||||||
|
initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
|
||||||
|
test: testRemovePVCFinalizer,
|
||||||
|
expectSuccess: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
runPVCFinalizerTests(t, tests, snapshotClasses)
|
||||||
|
}
|
@@ -79,10 +79,10 @@ func TestSync(t *testing.T) {
|
|||||||
parameters: class5Parameters,
|
parameters: class5Parameters,
|
||||||
secrets: map[string]string{"foo": "bar"},
|
secrets: map[string]string{"foo": "bar"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
snapshotId: "sid2-3",
|
snapshotId: "sid2-3",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: false,
|
readyToUse: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: noerrors,
|
errors: noerrors,
|
||||||
@@ -114,10 +114,10 @@ func TestSync(t *testing.T) {
|
|||||||
parameters: class5Parameters,
|
parameters: class5Parameters,
|
||||||
secrets: map[string]string{"foo": "bar"},
|
secrets: map[string]string{"foo": "bar"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
snapshotId: "sid2-5",
|
snapshotId: "sid2-5",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: noerrors,
|
errors: noerrors,
|
||||||
@@ -125,8 +125,8 @@ func TestSync(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "2-6 - snapshot bound to prebound content correctly, status ready false -> true, ref.UID '' -> 'snapuid2-6'",
|
name: "2-6 - snapshot bound to prebound content correctly, status ready false -> true, ref.UID '' -> 'snapuid2-6'",
|
||||||
initialContents: newContentArray("content2-6", validSecretClass, "sid2-6", noVolume, noVolume, noBoundUID, "snap2-6", &deletePolicy, nil, &timeNow, false),
|
initialContents: newContentArray("content2-6", validSecretClass, "sid2-6", noVolume, noVolume, noBoundUID, "snap2-6", &deletePolicy, nil, &timeNowStamp, false),
|
||||||
expectedContents: newContentArray("content2-6", validSecretClass, "sid2-6", noVolume, noVolume, "snapuid2-6", "snap2-6", &deletePolicy, nil, &timeNow, false),
|
expectedContents: newContentArray("content2-6", validSecretClass, "sid2-6", noVolume, noVolume, "snapuid2-6", "snap2-6", &deletePolicy, nil, &timeNowStamp, false),
|
||||||
initialSnapshots: newSnapshotArray("snap2-6", validSecretClass, "content2-6", "snapuid2-6", noClaim, false, nil, metaTimeNow, nil),
|
initialSnapshots: newSnapshotArray("snap2-6", validSecretClass, "content2-6", "snapuid2-6", noClaim, false, nil, metaTimeNow, nil),
|
||||||
expectedSnapshots: newSnapshotArray("snap2-6", validSecretClass, "content2-6", "snapuid2-6", noClaim, true, nil, metaTimeNow, nil),
|
expectedSnapshots: newSnapshotArray("snap2-6", validSecretClass, "content2-6", "snapuid2-6", noClaim, true, nil, metaTimeNow, nil),
|
||||||
expectedListCalls: []listCall{
|
expectedListCalls: []listCall{
|
||||||
@@ -178,11 +178,11 @@ func TestSync(t *testing.T) {
|
|||||||
parameters: class5Parameters,
|
parameters: class5Parameters,
|
||||||
secrets: map[string]string{"foo": "bar"},
|
secrets: map[string]string{"foo": "bar"},
|
||||||
// information to return
|
// information to return
|
||||||
driverName: mockDriverName,
|
driverName: mockDriverName,
|
||||||
size: defaultSize,
|
size: defaultSize,
|
||||||
snapshotId: "sid2-8",
|
snapshotId: "sid2-8",
|
||||||
timestamp: timeNow,
|
creationTime: timeNow,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errors: []reactorError{
|
errors: []reactorError{
|
||||||
|
@@ -75,6 +75,9 @@ var snapshotterSecretParams = deprecatedSecretParamsMap{
|
|||||||
secretNamespaceKey: prefixedSnapshotterSecretNamespaceKey,
|
secretNamespaceKey: prefixedSnapshotterSecretNamespaceKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name of finalizer on PVCs that have been used as a source to create VolumeSnapshots
|
||||||
|
const PVCFinalizer = "snapshot.storage.kubernetes.io/pvc-protection"
|
||||||
|
|
||||||
func snapshotKey(vs *crdv1.VolumeSnapshot) string {
|
func snapshotKey(vs *crdv1.VolumeSnapshot) string {
|
||||||
return fmt.Sprintf("%s/%s", vs.Namespace, vs.Name)
|
return fmt.Sprintf("%s/%s", vs.Namespace, vs.Name)
|
||||||
}
|
}
|
||||||
|
@@ -19,10 +19,10 @@ package snapshotter
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/container-storage-interface/spec/lib/go/csi"
|
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
"github.com/golang/protobuf/ptypes"
|
"github.com/golang/protobuf/ptypes"
|
||||||
"github.com/golang/protobuf/ptypes/timestamp"
|
|
||||||
csirpc "github.com/kubernetes-csi/csi-lib-utils/rpc"
|
csirpc "github.com/kubernetes-csi/csi-lib-utils/rpc"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
@@ -34,13 +34,13 @@ import (
|
|||||||
// Snapshotter implements CreateSnapshot/DeleteSnapshot operations against a remote CSI driver.
|
// Snapshotter implements CreateSnapshot/DeleteSnapshot operations against a remote CSI driver.
|
||||||
type Snapshotter interface {
|
type Snapshotter interface {
|
||||||
// CreateSnapshot creates a snapshot for a volume
|
// CreateSnapshot creates a snapshot for a volume
|
||||||
CreateSnapshot(ctx context.Context, snapshotName string, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (driverName string, snapshotId string, timestamp int64, size int64, readyToUse bool, err error)
|
CreateSnapshot(ctx context.Context, snapshotName string, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (driverName string, snapshotId string, timestamp time.Time, size int64, readyToUse bool, err error)
|
||||||
|
|
||||||
// DeleteSnapshot deletes a snapshot from a volume
|
// DeleteSnapshot deletes a snapshot from a volume
|
||||||
DeleteSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) (err error)
|
DeleteSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) (err error)
|
||||||
|
|
||||||
// GetSnapshotStatus returns if a snapshot is ready to use, creation time, and restore size.
|
// GetSnapshotStatus returns if a snapshot is ready to use, creation time, and restore size.
|
||||||
GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, int64, int64, error)
|
GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, time.Time, int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type snapshot struct {
|
type snapshot struct {
|
||||||
@@ -53,17 +53,17 @@ func NewSnapshotter(conn *grpc.ClientConn) Snapshotter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *snapshot) CreateSnapshot(ctx context.Context, snapshotName string, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, int64, int64, bool, error) {
|
func (s *snapshot) CreateSnapshot(ctx context.Context, snapshotName string, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, time.Time, int64, bool, error) {
|
||||||
klog.V(5).Infof("CSI CreateSnapshot: %s", snapshotName)
|
klog.V(5).Infof("CSI CreateSnapshot: %s", snapshotName)
|
||||||
if volume.Spec.CSI == nil {
|
if volume.Spec.CSI == nil {
|
||||||
return "", "", 0, 0, false, fmt.Errorf("CSIPersistentVolumeSource not defined in spec")
|
return "", "", time.Time{}, 0, false, fmt.Errorf("CSIPersistentVolumeSource not defined in spec")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := csi.NewControllerClient(s.conn)
|
client := csi.NewControllerClient(s.conn)
|
||||||
|
|
||||||
driverName, err := csirpc.GetDriverName(ctx, s.conn)
|
driverName, err := csirpc.GetDriverName(ctx, s.conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", 0, 0, false, err
|
return "", "", time.Time{}, 0, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req := csi.CreateSnapshotRequest{
|
req := csi.CreateSnapshotRequest{
|
||||||
@@ -75,13 +75,13 @@ func (s *snapshot) CreateSnapshot(ctx context.Context, snapshotName string, volu
|
|||||||
|
|
||||||
rsp, err := client.CreateSnapshot(ctx, &req)
|
rsp, err := client.CreateSnapshot(ctx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", 0, 0, false, err
|
return "", "", time.Time{}, 0, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
klog.V(5).Infof("CSI CreateSnapshot: %s driver name [%s] snapshot ID [%s] time stamp [%d] size [%d] readyToUse [%v]", snapshotName, driverName, rsp.Snapshot.SnapshotId, rsp.Snapshot.CreationTime, rsp.Snapshot.SizeBytes, rsp.Snapshot.ReadyToUse)
|
klog.V(5).Infof("CSI CreateSnapshot: %s driver name [%s] snapshot ID [%s] time stamp [%d] size [%d] readyToUse [%v]", snapshotName, driverName, rsp.Snapshot.SnapshotId, rsp.Snapshot.CreationTime, rsp.Snapshot.SizeBytes, rsp.Snapshot.ReadyToUse)
|
||||||
creationTime, err := timestampToUnixTime(rsp.Snapshot.CreationTime)
|
creationTime, err := ptypes.Timestamp(rsp.Snapshot.CreationTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", 0, 0, false, err
|
return "", "", time.Time{}, 0, false, err
|
||||||
}
|
}
|
||||||
return driverName, rsp.Snapshot.SnapshotId, creationTime, rsp.Snapshot.SizeBytes, rsp.Snapshot.ReadyToUse, nil
|
return driverName, rsp.Snapshot.SnapshotId, creationTime, rsp.Snapshot.SizeBytes, rsp.Snapshot.ReadyToUse, nil
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ func (s *snapshot) DeleteSnapshot(ctx context.Context, snapshotID string, snapsh
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *snapshot) GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, int64, int64, error) {
|
func (s *snapshot) GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, time.Time, int64, error) {
|
||||||
client := csi.NewControllerClient(s.conn)
|
client := csi.NewControllerClient(s.conn)
|
||||||
|
|
||||||
req := csi.ListSnapshotsRequest{
|
req := csi.ListSnapshotsRequest{
|
||||||
@@ -110,26 +110,16 @@ func (s *snapshot) GetSnapshotStatus(ctx context.Context, snapshotID string) (bo
|
|||||||
|
|
||||||
rsp, err := client.ListSnapshots(ctx, &req)
|
rsp, err := client.ListSnapshots(ctx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, 0, err
|
return false, time.Time{}, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if rsp.Entries == nil || len(rsp.Entries) == 0 {
|
if rsp.Entries == nil || len(rsp.Entries) == 0 {
|
||||||
return false, 0, 0, fmt.Errorf("can not find snapshot for snapshotID %s", snapshotID)
|
return false, time.Time{}, 0, fmt.Errorf("can not find snapshot for snapshotID %s", snapshotID)
|
||||||
}
|
}
|
||||||
|
|
||||||
creationTime, err := timestampToUnixTime(rsp.Entries[0].Snapshot.CreationTime)
|
creationTime, err := ptypes.Timestamp(rsp.Entries[0].Snapshot.CreationTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, 0, err
|
return false, time.Time{}, 0, err
|
||||||
}
|
}
|
||||||
return rsp.Entries[0].Snapshot.ReadyToUse, creationTime, rsp.Entries[0].Snapshot.SizeBytes, nil
|
return rsp.Entries[0].Snapshot.ReadyToUse, creationTime, rsp.Entries[0].Snapshot.SizeBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func timestampToUnixTime(t *timestamp.Timestamp) (int64, error) {
|
|
||||||
time, err := ptypes.Timestamp(t)
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
// TODO: clean this up, we probably don't need this translation layer
|
|
||||||
// and can just use time.Time
|
|
||||||
return time.UnixNano(), nil
|
|
||||||
}
|
|
||||||
|
@@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/container-storage-interface/spec/lib/go/csi"
|
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
@@ -118,7 +119,7 @@ func TestCreateSnapshot(t *testing.T) {
|
|||||||
type snapshotResult struct {
|
type snapshotResult struct {
|
||||||
driverName string
|
driverName string
|
||||||
snapshotId string
|
snapshotId string
|
||||||
timestamp int64
|
timestamp time.Time
|
||||||
size int64
|
size int64
|
||||||
readyToUse bool
|
readyToUse bool
|
||||||
}
|
}
|
||||||
@@ -127,7 +128,7 @@ func TestCreateSnapshot(t *testing.T) {
|
|||||||
size: 1000,
|
size: 1000,
|
||||||
driverName: driverName,
|
driverName: driverName,
|
||||||
snapshotId: defaultID,
|
snapshotId: defaultID,
|
||||||
timestamp: createTime.UnixNano(),
|
timestamp: createTime,
|
||||||
readyToUse: true,
|
readyToUse: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +377,7 @@ func TestGetSnapshotStatus(t *testing.T) {
|
|||||||
injectError codes.Code
|
injectError codes.Code
|
||||||
expectError bool
|
expectError bool
|
||||||
expectReady bool
|
expectReady bool
|
||||||
expectCreateAt int64
|
expectCreateAt time.Time
|
||||||
expectSize int64
|
expectSize int64
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -386,7 +387,7 @@ func TestGetSnapshotStatus(t *testing.T) {
|
|||||||
output: defaultResponse,
|
output: defaultResponse,
|
||||||
expectError: false,
|
expectError: false,
|
||||||
expectReady: true,
|
expectReady: true,
|
||||||
expectCreateAt: createTime.UnixNano(),
|
expectCreateAt: createTime,
|
||||||
expectSize: size,
|
expectSize: size,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user