Merge pull request #139 from xing-yang/beta

Update VolumeSnapshot CRD version to v1beta
This commit is contained in:
Kubernetes Prow Robot
2019-10-24 16:51:39 -07:00
committed by GitHub
78 changed files with 1778 additions and 14457 deletions

16
Gopkg.lock generated
View File

@@ -404,20 +404,6 @@
pruneopts = "NUT" pruneopts = "NUT"
revision = "3ab596449d6fc6d35213dfc7e6254ae5d866e48e" revision = "3ab596449d6fc6d35213dfc7e6254ae5d866e48e"
[[projects]]
digest = "1:edf8a3c5c2f8f46ae492c7272bb451f18a423639e86b10cd0ec72b56fe50f60a"
name = "k8s.io/apiextensions-apiserver"
packages = [
"pkg/apis/apiextensions",
"pkg/apis/apiextensions/v1beta1",
"pkg/client/clientset/clientset",
"pkg/client/clientset/clientset/scheme",
"pkg/client/clientset/clientset/typed/apiextensions/v1beta1",
]
pruneopts = "NUT"
revision = "53c4693659ed354d76121458fb819202dd1635fa"
version = "kubernetes-1.14.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:23397eb6bf14ddd6ac3594595ace5e424c75f3fb78f525ad06f128bf49aa8070" digest = "1:23397eb6bf14ddd6ac3594595ace5e424c75f3fb78f525ad06f128bf49aa8070"
@@ -783,8 +769,6 @@
"k8s.io/api/core/v1", "k8s.io/api/core/v1",
"k8s.io/api/storage/v1", "k8s.io/api/storage/v1",
"k8s.io/api/storage/v1beta1", "k8s.io/api/storage/v1beta1",
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1",
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset",
"k8s.io/apimachinery/pkg/api/errors", "k8s.io/apimachinery/pkg/api/errors",
"k8s.io/apimachinery/pkg/api/meta", "k8s.io/apimachinery/pkg/api/meta",
"k8s.io/apimachinery/pkg/api/resource", "k8s.io/apimachinery/pkg/api/resource",

View File

@@ -40,10 +40,6 @@ required = [
name = "k8s.io/code-generator" name = "k8s.io/code-generator"
version = "kubernetes-1.14.0" version = "kubernetes-1.14.0"
[[constraint]]
name = "k8s.io/apiextensions-apiserver"
version = "kubernetes-1.14.0"
[[constraint]] [[constraint]]
name = "github.com/kubernetes-csi/csi-lib-utils" name = "github.com/kubernetes-csi/csi-lib-utils"
version = ">=v0.6.1" version = ">=v0.6.1"

View File

@@ -1,100 +0,0 @@
/*
Copyright 2018 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 main
import (
"reflect"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog"
)
// CreateCRD creates CustomResourceDefinition
func CreateCRD(clientset apiextensionsclient.Interface) error {
crd := &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: crdv1.VolumeSnapshotClassResourcePlural + "." + crdv1.GroupName,
},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: crdv1.GroupName,
Version: crdv1.SchemeGroupVersion.Version,
Scope: apiextensionsv1beta1.ClusterScoped,
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Plural: crdv1.VolumeSnapshotClassResourcePlural,
Kind: reflect.TypeOf(crdv1.VolumeSnapshotClass{}).Name(),
},
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
},
},
}
res, err := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd)
if err != nil && !apierrors.IsAlreadyExists(err) {
klog.Fatalf("failed to create VolumeSnapshotResource: %#v, err: %#v",
res, err)
}
crd = &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: crdv1.VolumeSnapshotContentResourcePlural + "." + crdv1.GroupName,
},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: crdv1.GroupName,
Version: crdv1.SchemeGroupVersion.Version,
Scope: apiextensionsv1beta1.ClusterScoped,
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Plural: crdv1.VolumeSnapshotContentResourcePlural,
Kind: reflect.TypeOf(crdv1.VolumeSnapshotContent{}).Name(),
},
},
}
res, err = clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd)
if err != nil && !apierrors.IsAlreadyExists(err) {
klog.Fatalf("failed to create VolumeSnapshotContentResource: %#v, err: %#v",
res, err)
}
crd = &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: crdv1.VolumeSnapshotResourcePlural + "." + crdv1.GroupName,
},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: crdv1.GroupName,
Version: crdv1.SchemeGroupVersion.Version,
Scope: apiextensionsv1beta1.NamespaceScoped,
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Plural: crdv1.VolumeSnapshotResourcePlural,
Kind: reflect.TypeOf(crdv1.VolumeSnapshot{}).Name(),
},
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
},
},
}
res, err = clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd)
if err != nil && !apierrors.IsAlreadyExists(err) {
klog.Fatalf("failed to create VolumeSnapshotResource: %#v, err: %#v",
res, err)
}
return nil
}

View File

@@ -43,7 +43,6 @@ import (
clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned" clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
snapshotscheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" snapshotscheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme"
informers "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions" informers "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions"
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
coreinformers "k8s.io/client-go/informers" coreinformers "k8s.io/client-go/informers"
) )
@@ -119,20 +118,6 @@ func main() {
factory := informers.NewSharedInformerFactory(snapClient, *resyncPeriod) factory := informers.NewSharedInformerFactory(snapClient, *resyncPeriod)
coreFactory := coreinformers.NewSharedInformerFactory(kubeClient, *resyncPeriod) coreFactory := coreinformers.NewSharedInformerFactory(kubeClient, *resyncPeriod)
// Create CRD resource
aeclientset, err := apiextensionsclient.NewForConfig(config)
if err != nil {
klog.Error(err.Error())
os.Exit(1)
}
// initialize CRD resource if it does not exist
err = CreateCRD(aeclientset)
if err != nil {
klog.Error(err.Error())
os.Exit(1)
}
// Add Snapshot types to the defualt Kubernetes so events can be logged for them // Add Snapshot types to the defualt Kubernetes so events can be logged for them
snapshotscheme.AddToScheme(scheme.Scheme) snapshotscheme.AddToScheme(scheme.Scheme)
@@ -185,9 +170,9 @@ func main() {
snapClient, snapClient,
kubeClient, kubeClient,
*snapshotterName, *snapshotterName,
factory.Snapshot().V1alpha1().VolumeSnapshots(), factory.Snapshot().V1beta1().VolumeSnapshots(),
factory.Snapshot().V1alpha1().VolumeSnapshotContents(), factory.Snapshot().V1beta1().VolumeSnapshotContents(),
factory.Snapshot().V1alpha1().VolumeSnapshotClasses(), factory.Snapshot().V1beta1().VolumeSnapshotClasses(),
coreFactory.Core().V1().PersistentVolumeClaims(), coreFactory.Core().V1().PersistentVolumeClaims(),
*createSnapshotContentRetryCount, *createSnapshotContentRetryCount,
*createSnapshotContentInterval, *createSnapshotContentInterval,

View File

@@ -0,0 +1,72 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: (devel)
api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/139"
creationTimestamp: null
name: volumesnapshotclasses.snapshot.storage.k8s.io
spec:
group: snapshot.storage.k8s.io
names:
kind: VolumeSnapshotClass
listKind: VolumeSnapshotClassList
plural: volumesnapshotclasses
singular: volumesnapshotclass
scope: Cluster
preserveUnknownFields: false
validation:
openAPIV3Schema:
description: VolumeSnapshotClass specifies parameters that a underlying storage
system uses when creating a volume snapshot. A specific VolumeSnapshotClass
is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses
are non-namespaced
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
deletionPolicy:
description: deletionPolicy determines whether a VolumeSnapshotContent created
through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot
is deleted. Supported values are "Retain" and "Delete". "Retain" means
that the VolumeSnapshotContent and its physical snapshot on underlying
storage system are kept. "Delete" means that the VolumeSnapshotContent
and its physical snapshot on underlying storage system are deleted. Required.
enum:
- Delete
- Retain
type: string
driver:
description: driver is the name of the storage driver that handles this
VolumeSnapshotClass. Required.
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
parameters:
additionalProperties:
type: string
description: parameters is a key-value map with storage driver specific
parameters for creating snapshots. These values are opaque to Kubernetes.
type: object
required:
- deletionPolicy
- driver
type: object
version: v1beta1
versions:
- name: v1beta1
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -0,0 +1,201 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: (devel)
api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/139"
creationTimestamp: null
name: volumesnapshotcontents.snapshot.storage.k8s.io
spec:
group: snapshot.storage.k8s.io
names:
kind: VolumeSnapshotContent
listKind: VolumeSnapshotContentList
plural: volumesnapshotcontents
singular: volumesnapshotcontent
scope: Cluster
subresources:
status: {}
preserveUnknownFields: false
validation:
openAPIV3Schema:
description: VolumeSnapshotContent represents the actual "on-disk" snapshot
object in the underlying storage system
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
spec:
description: spec defines properties of a VolumeSnapshotContent created
by the underlying storage system. Required.
properties:
deletionPolicy:
description: deletionPolicy determines whether this VolumeSnapshotContent
and its physical snapshot on the underlying storage system should
be deleted when its bound VolumeSnapshot is deleted. Supported values
are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent
and its physical snapshot on underlying storage system are kept. "Delete"
means that the VolumeSnapshotContent and its physical snapshot on
underlying storage system are deleted. In dynamic snapshot creation
case, this field will be filled in with the "DeletionPolicy" field
defined in the VolumeSnapshotClass the VolumeSnapshot refers to. For
pre-existing snapshots, users MUST specify this field when creating
the VolumeSnapshotContent object. Required.
enum:
- Delete
- Retain
type: string
driver:
description: driver is the name of the CSI driver used to create the
physical snapshot on the underlying storage system. This MUST be the
same as the name returned by the CSI GetPluginName() call for that
driver. Required.
type: string
source:
description: source specifies from where a snapshot will be created.
This field is immutable after creation. Required.
properties:
snapshotHandle:
description: snapshotHandle specifies the CSI "snapshot_id" of a
pre-existing snapshot on the underlying storage system. This field
is immutable.
type: string
volumeHandle:
description: volumeHandle specifies the CSI "volume_id" of the volume
from which a snapshot should be dynamically taken from. This field
is immutable.
type: string
type: object
volumeSnapshotClassName:
description: name of the VolumeSnapshotClass to which this snapshot
belongs.
type: string
volumeSnapshotRef:
description: volumeSnapshotRef specifies the VolumeSnapshot object to
which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName
field must reference to this VolumeSnapshotContent's name for the
bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent
object, name and namespace of the VolumeSnapshot object MUST be provided
for binding to happen. This field is immutable after creation. Required.
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead of an
entire object, this string should contain a valid JSON/Go field
access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within
a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]"
(container with index 2 in this pod). This syntax is chosen only
to have some well-defined way of referencing a part of an object.
TODO: this design is not final and this field is subject to change
in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference is
made, if any. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
required:
- deletionPolicy
- driver
- source
- volumeSnapshotRef
type: object
status:
description: status represents the current information of a snapshot.
properties:
creationTime:
description: creationTime is the timestamp when the point-in-time snapshot
is taken by the underlying storage system. In dynamic snapshot creation
case, this field will be filled in with the "creation_time" value
returned from CSI "CreateSnapshotRequest" gRPC call. For a pre-existing
snapshot, this field will be filled with the "creation_time" value
returned from the CSI "ListSnapshots" gRPC call if the driver supports
it. If not specified, it indicates the creation time is unknown. The
format of this field is a Unix nanoseconds time encoded as an int64.
On Unix, the command `date +%s%N` returns the current time in nanoseconds
since 1970-01-01 00:00:00 UTC.
format: int64
type: integer
error:
description: error is the latest observed error during snapshot creation,
if any.
properties:
message:
description: 'message is a string detailing the encountered error
during snapshot creation if specified. NOTE: message may be logged,
and it should not contain sensitive information.'
type: string
time:
description: time is the timestamp when the error was encountered.
format: date-time
type: string
type: object
readyToUse:
description: readyToUse indicates if a snapshot is ready to be used
to restore a volume. In dynamic snapshot creation case, this field
will be filled in with the "ready_to_use" value returned from CSI
"CreateSnapshotRequest" gRPC call. For a pre-existing snapshot, this
field will be filled with the "ready_to_use" value returned from the
CSI "ListSnapshots" gRPC call if the driver supports it, otherwise,
this field will be set to "True". If not specified, it means the readiness
of a snapshot is unknown.
type: boolean
restoreSize:
description: restoreSize represents the complete size of the snapshot
in bytes. In dynamic snapshot creation case, this field will be filled
in with the "size_bytes" value returned from CSI "CreateSnapshotRequest"
gRPC call. For a pre-existing snapshot, this field will be filled
with the "size_bytes" value returned from the CSI "ListSnapshots"
gRPC call if the driver supports it. When restoring a volume from
this snapshot, the size of the volume MUST NOT be smaller than the
restoreSize if it is specified, otherwise the restoration will fail.
If not specified, it indicates that the size is unknown.
format: int64
minimum: 0
type: integer
snapshotHandle:
description: snapshotHandle is the CSI "snapshot_id" of a snapshot on
the underlying storage system. If not specified, it indicates that
dynamic snapshot creation has either failed or it is still in progress.
type: string
type: object
required:
- spec
type: object
version: v1beta1
versions:
- name: v1beta1
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -0,0 +1,148 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: (devel)
api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/139"
creationTimestamp: null
name: volumesnapshots.snapshot.storage.k8s.io
spec:
group: snapshot.storage.k8s.io
names:
kind: VolumeSnapshot
listKind: VolumeSnapshotList
plural: volumesnapshots
singular: volumesnapshot
scope: Namespaced
subresources:
status: {}
preserveUnknownFields: false
validation:
openAPIV3Schema:
description: VolumeSnapshot is a user's request for either creating a point-in-time
snapshot of a persistent volume, or binding to a pre-existing snapshot.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
spec:
description: 'spec defines the desired characteristics of a snapshot requested
by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots
Required.'
properties:
source:
description: source specifies where a snapshot will be created from.
This field is immutable after creation. Required.
properties:
persistentVolumeClaimName:
description: persistentVolumeClaimName specifies the name of the
PersistentVolumeClaim object in the same namespace as the VolumeSnapshot
object where the snapshot should be dynamically taken from. This
field is immutable.
type: string
volumeSnapshotContentName:
description: volumeSnapshotContentName specifies the name of a pre-existing
VolumeSnapshotContent object. This field is immutable.
type: string
type: object
volumeSnapshotClassName:
description: 'volumeSnapshotClassName is the name of the VolumeSnapshotClass
requested by the VolumeSnapshot. If not specified, the default snapshot
class will be used if one exists. If not specified, and there is no
default snapshot class, dynamic snapshot creation will fail. Empty
string is not allowed for this field. TODO(xiangqian): a webhook validation
on empty string. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes'
type: string
required:
- source
type: object
status:
description: 'status represents the current information of a snapshot. NOTE:
status can be modified by sources other than system controllers, and must
not be depended upon for accuracy. Controllers should only use information
from the VolumeSnapshotContent object after verifying that the binding
is accurate and complete.'
properties:
boundVolumeSnapshotContentName:
description: 'boundVolumeSnapshotContentName represents the name of
the VolumeSnapshotContent object to which the VolumeSnapshot object
is bound. If not specified, it indicates that the VolumeSnapshot object
has not been successfully bound to a VolumeSnapshotContent object
yet. NOTE: Specified boundVolumeSnapshotContentName alone does not
mean binding is valid. Controllers MUST always verify bidirectional
binding between VolumeSnapshot and VolumeSnapshotContent to
avoid possible security issues.'
type: string
creationTime:
description: creationTime is the timestamp when the point-in-time snapshot
is taken by the underlying storage system. In dynamic snapshot creation
case, this field will be filled in with the "creation_time" value
returned from CSI "CreateSnapshotRequest" gRPC call. For a pre-existing
snapshot, this field will be filled with the "creation_time" value
returned from the CSI "ListSnapshots" gRPC call if the driver supports
it. If not specified, it indicates that the creation time of the snapshot
is unknown.
format: date-time
type: string
error:
description: error is the last observed error during snapshot creation,
if any. This field could be helpful to upper level controllers(i.e.,
application controller) to decide whether they should continue on
waiting for the snapshot to be created based on the type of error
reported.
properties:
message:
description: 'message is a string detailing the encountered error
during snapshot creation if specified. NOTE: message may be logged,
and it should not contain sensitive information.'
type: string
time:
description: time is the timestamp when the error was encountered.
format: date-time
type: string
type: object
readyToUse:
description: readyToUse indicates if a snapshot is ready to be used
to restore a volume. In dynamic snapshot creation case, this field
will be filled in with the "ready_to_use" value returned from CSI
"CreateSnapshotRequest" gRPC call. For a pre-existing snapshot, this
field will be filled with the "ready_to_use" value returned from the
CSI "ListSnapshots" gRPC call if the driver supports it, otherwise,
this field will be set to "True". If not specified, it means the readiness
of a snapshot is unknown.
type: boolean
restoreSize:
description: restoreSize represents the complete size of the snapshot
in bytes. In dynamic snapshot creation case, this field will be filled
in with the "size_bytes" value returned from CSI "CreateSnapshotRequest"
gRPC call. For a pre-existing snapshot, this field will be filled
with the "size_bytes" value returned from the CSI "ListSnapshots"
gRPC call if the driver supports it. When restoring a volume from
this snapshot, the size of the volume MUST NOT be smaller than the
restoreSize if it is specified, otherwise the restoration will fail.
If not specified, it indicates that the size is unknown.
type: string
type: object
required:
- spec
type: object
version: v1beta1
versions:
- name: v1beta1
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -45,6 +45,9 @@ rules:
- apiGroups: ["snapshot.storage.k8s.io"] - apiGroups: ["snapshot.storage.k8s.io"]
resources: ["volumesnapshotcontents"] resources: ["volumesnapshotcontents"]
verbs: ["create", "get", "list", "watch", "update", "delete"] verbs: ["create", "get", "list", "watch", "update", "delete"]
- apiGroups: ["snapshot.storage.k8s.io"]
resources: ["volumesnapshotcontents/status"]
verbs: ["update"]
- apiGroups: ["snapshot.storage.k8s.io"] - apiGroups: ["snapshot.storage.k8s.io"]
resources: ["volumesnapshots"] resources: ["volumesnapshots"]
verbs: ["get", "list", "watch", "update"] verbs: ["get", "list", "watch", "update"]

View File

@@ -29,7 +29,7 @@ CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-ge
# instead of the $GOPATH directly. For normal projects this can be dropped. # instead of the $GOPATH directly. For normal projects this can be dropped.
${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \ ${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
github.com/kubernetes-csi/external-snapshotter/pkg/client github.com/kubernetes-csi/external-snapshotter/pkg/apis \ github.com/kubernetes-csi/external-snapshotter/pkg/client github.com/kubernetes-csi/external-snapshotter/pkg/apis \
volumesnapshot:v1alpha1 \ volumesnapshot:v1beta1 \
--go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt
# To use your own boilerplate text use: # To use your own boilerplate text use:

View File

@@ -1,256 +0,0 @@
/*
Copyright 2018 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 v1alpha1
import (
core_v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1beta1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
// VolumeSnapshotContentResourcePlural is "volumesnapshotcontents"
VolumeSnapshotContentResourcePlural = "volumesnapshotcontents"
// VolumeSnapshotResourcePlural is "volumesnapshots"
VolumeSnapshotResourcePlural = "volumesnapshots"
// VolumeSnapshotClassResourcePlural is "volumesnapshotclasses"
VolumeSnapshotClassResourcePlural = "volumesnapshotclasses"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshot is a user's request for taking a snapshot. Upon successful creation of the actual
// snapshot by the volume provider it is bound to the corresponding VolumeSnapshotContent.
// Only the VolumeSnapshot object is accessible to the user in the namespace.
type VolumeSnapshot struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Spec defines the desired characteristics of a snapshot requested by a user.
Spec VolumeSnapshotSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
// Status represents the latest observed state of the snapshot
// +optional
Status VolumeSnapshotStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotList is a list of VolumeSnapshot objects
type VolumeSnapshotList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Items is the list of VolumeSnapshots
Items []VolumeSnapshot `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// VolumeSnapshotSpec describes the common attributes of a volume snapshot
type VolumeSnapshotSpec struct {
// Source has the information about where the snapshot is created from.
// In Alpha version, only PersistentVolumeClaim is supported as the source.
// If not specified, user can create VolumeSnapshotContent and bind it with VolumeSnapshot manually.
// +optional
Source *core_v1.TypedLocalObjectReference `json:"source" protobuf:"bytes,1,opt,name=source"`
// SnapshotContentName binds the VolumeSnapshot object with the VolumeSnapshotContent
// +optional
SnapshotContentName string `json:"snapshotContentName" protobuf:"bytes,2,opt,name=snapshotContentName"`
// Name of the VolumeSnapshotClass used by the VolumeSnapshot. If not specified, a default snapshot class will
// be used if it is available.
// +optional
VolumeSnapshotClassName *string `json:"snapshotClassName" protobuf:"bytes,3,opt,name=snapshotClassName"`
}
// VolumeSnapshotStatus is the status of the VolumeSnapshot
type VolumeSnapshotStatus struct {
// CreationTime is the time the snapshot was successfully created. If it is set,
// it means the snapshot was created; Otherwise the snapshot was not created.
// +optional
CreationTime *metav1.Time `json:"creationTime" protobuf:"bytes,1,opt,name=creationTime"`
// When restoring volume from the snapshot, the volume size should be equal to or
// larger than the RestoreSize if it is specified. If RestoreSize is set to nil, it means
// that the storage plugin does not have this information available.
// +optional
RestoreSize *resource.Quantity `json:"restoreSize" protobuf:"bytes,2,opt,name=restoreSize"`
// ReadyToUse is set to true only if the snapshot is ready to use (e.g., finish uploading if
// there is an uploading phase) and also VolumeSnapshot and its VolumeSnapshotContent
// bind correctly with each other. If any of the above condition is not true, ReadyToUse is
// set to false
// +optional
ReadyToUse bool `json:"readyToUse" protobuf:"varint,3,opt,name=readyToUse"`
// The last error encountered during create snapshot operation, if any.
// This field must only be set by the entity completing the create snapshot
// operation, i.e. the external-snapshotter.
// +optional
Error *storage.VolumeError `json:"error,omitempty" protobuf:"bytes,4,opt,name=error,casttype=VolumeError"`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotClass describes the parameters used by storage system when
// provisioning VolumeSnapshots from PVCs.
// The name of a VolumeSnapshotClass object is significant, and is how users can request a particular class.
type VolumeSnapshotClass struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Snapshotter is the driver expected to handle this VolumeSnapshotClass.
Snapshotter string `json:"snapshotter" protobuf:"bytes,2,opt,name=snapshotter"`
// Parameters holds parameters for the snapshotter.
// These values are opaque to the system and are passed directly
// to the snapshotter.
// +optional
Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"`
// Optional: what happens to a snapshot content when released from its snapshot.
// The default policy is Delete if not specified.
// +optional
DeletionPolicy *DeletionPolicy `json:"deletionPolicy,omitempty" protobuf:"bytes,4,opt,name=deletionPolicy"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotClassList is a collection of snapshot classes.
type VolumeSnapshotClassList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Items is the list of VolumeSnapshotClasses
Items []VolumeSnapshotClass `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotContent represents the actual "on-disk" snapshot object
type VolumeSnapshotContent struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Spec represents the desired state of the snapshot content
Spec VolumeSnapshotContentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotContentList is a list of VolumeSnapshotContent objects
type VolumeSnapshotContentList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Items is the list of VolumeSnapshotContents
Items []VolumeSnapshotContent `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// VolumeSnapshotContentSpec is the spec of the volume snapshot content
type VolumeSnapshotContentSpec struct {
// Source represents the location and type of the volume snapshot
VolumeSnapshotSource `json:",inline" protobuf:"bytes,1,opt,name=volumeSnapshotSource"`
// VolumeSnapshotRef is part of bi-directional binding between VolumeSnapshot
// and VolumeSnapshotContent. It becomes non-nil when bound.
// +optional
VolumeSnapshotRef *core_v1.ObjectReference `json:"volumeSnapshotRef" protobuf:"bytes,2,opt,name=volumeSnapshotRef"`
// PersistentVolumeRef represents the PersistentVolume that the snapshot has been
// taken from. It becomes non-nil when VolumeSnapshot and VolumeSnapshotContent are bound.
// +optional
PersistentVolumeRef *core_v1.ObjectReference `json:"persistentVolumeRef" protobuf:"bytes,3,opt,name=persistentVolumeRef"`
// Name of the VolumeSnapshotClass used by the VolumeSnapshot. If not specified, a default snapshot class will
// be used if it is available.
// +optional
VolumeSnapshotClassName *string `json:"snapshotClassName" protobuf:"bytes,4,opt,name=snapshotClassName"`
// Optional: what happens to a snapshot content when released from its snapshot. It will be set to Delete by default
// if not specified
// +optional
DeletionPolicy *DeletionPolicy `json:"deletionPolicy" protobuf:"bytes,5,opt,name=deletionPolicy"`
}
// VolumeSnapshotSource represents the actual location and type of the snapshot. Only one of its members may be specified.
type VolumeSnapshotSource struct {
// CSI (Container Storage Interface) represents storage that handled by an external CSI Volume Driver (Alpha feature).
// +optional
CSI *CSIVolumeSnapshotSource `json:"csiVolumeSnapshotSource,omitempty"`
}
// CSIVolumeSnapshotSource represents the source from CSI volume snapshot
type CSIVolumeSnapshotSource struct {
// Driver is the name of the driver to use for this snapshot.
// This MUST be the same name returned by the CSI GetPluginName() call for
// that driver.
// Required.
Driver string `json:"driver" protobuf:"bytes,1,opt,name=driver"`
// SnapshotHandle is the unique snapshot id returned by the CSI volume
// plugins CreateSnapshot to refer to the snapshot on all subsequent calls.
// Required.
SnapshotHandle string `json:"snapshotHandle" protobuf:"bytes,2,opt,name=snapshotHandle"`
// Timestamp when the point-in-time snapshot is taken on the storage
// system. This timestamp will be generated by the CSI volume driver after
// the snapshot is cut. The format of this field should be a Unix nanoseconds
// time encoded as an int64. On Unix, the command `date +%s%N` returns
// the current time in nanoseconds since 1970-01-01 00:00:00 UTC.
// This field is required in the CSI spec but optional here to support static binding.
// +optional
CreationTime *int64 `json:"creationTime,omitempty" protobuf:"varint,3,opt,name=creationTime"`
// When restoring volume from the snapshot, the volume size should be equal to or
// larger than the RestoreSize if it is specified. If RestoreSize is set to nil, it means
// that the storage plugin does not have this information available.
// +optional
RestoreSize *int64 `json:"restoreSize,omitempty" protobuf:"bytes,4,opt,name=restoreSize"`
}
// DeletionPolicy describes a policy for end-of-life maintenance of volume snapshot contents
type DeletionPolicy string
const (
// VolumeSnapshotContentDelete means the snapshot content will be deleted from Kubernetes on release from its volume snapshot.
VolumeSnapshotContentDelete DeletionPolicy = "Delete"
// VolumeSnapshotContentRetain means the snapshot will be left in its current state on release from its volume snapshot.
// The default policy is Retain if not specified.
VolumeSnapshotContentRetain DeletionPolicy = "Retain"
)

View File

@@ -17,4 +17,4 @@ limitations under the License.
// +k8s:deepcopy-gen=package // +k8s:deepcopy-gen=package
// +groupName=snapshot.storage.k8s.io // +groupName=snapshot.storage.k8s.io
package v1alpha1 package v1beta1

View File

@@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package v1alpha1 package v1beta1
import ( import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -28,7 +28,7 @@ var (
// AddToScheme adds to scheme // AddToScheme adds to scheme
AddToScheme = SchemeBuilder.AddToScheme AddToScheme = SchemeBuilder.AddToScheme
// SchemeGroupVersion is the group version used to register these objects. // SchemeGroupVersion is the group version used to register these objects.
SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"}
) )
// Resource takes an unqualified resource and returns a Group-qualified GroupResource. // Resource takes an unqualified resource and returns a Group-qualified GroupResource.

View File

@@ -0,0 +1,377 @@
/*
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.
*/
// +kubebuilder:object:generate=true
package v1beta1
import (
core_v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshot is a user's request for either creating a point-in-time
// snapshot of a persistent volume, or binding to a pre-existing snapshot.
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Namespaced
// +kubebuilder:subresource:status
type VolumeSnapshot struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// spec defines the desired characteristics of a snapshot requested by a user.
// More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots
// Required.
Spec VolumeSnapshotSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
// status represents the current information of a snapshot.
// NOTE: status can be modified by sources other than system controllers,
// and must not be depended upon for accuracy.
// Controllers should only use information from the VolumeSnapshotContent object
// after verifying that the binding is accurate and complete.
// +optional
Status *VolumeSnapshotStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotList is a list of VolumeSnapshot objects
type VolumeSnapshotList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of VolumeSnapshots
Items []VolumeSnapshot `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// VolumeSnapshotSpec describes the common attributes of a volume snapshot.
type VolumeSnapshotSpec struct {
// source specifies where a snapshot will be created from.
// This field is immutable after creation.
// Required.
Source VolumeSnapshotSource `json:"source" protobuf:"bytes,1,opt,name=source"`
// volumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot.
// If not specified, the default snapshot class will be used if one exists.
// If not specified, and there is no default snapshot class, dynamic snapshot creation will fail.
// Empty string is not allowed for this field.
// TODO(xiangqian): a webhook validation on empty string.
// More info: https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes
// +optional
VolumeSnapshotClassName *string `json:"volumeSnapshotClassName,omitempty" protobuf:"bytes,2,opt,name=volumeSnapshotClassName"`
}
// VolumeSnapshotSource specifies whether the underlying snapshot should be
// dynamically taken upon creation or if a pre-existing VolumeSnapshotContent
// object should be used.
// Exactly one of its members must be set.
// Members in VolumeSnapshotSource are immutable.
// TODO(xiangqian): Add a webhook to ensure that VolumeSnapshotSource members
// will not be updated once specified.
type VolumeSnapshotSource struct {
// persistentVolumeClaimName specifies the name of the PersistentVolumeClaim
// object in the same namespace as the VolumeSnapshot object where the
// snapshot should be dynamically taken from.
// This field is immutable.
// +optional
PersistentVolumeClaimName *string `json:"persistentVolumeClaimName,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeClaimName"`
// volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent
// object.
// This field is immutable.
// +optional
VolumeSnapshotContentName *string `json:"volumeSnapshotContentName,omitempty" protobuf:"bytes,2,opt,name=volumeSnapshotContentName"`
}
// VolumeSnapshotStatus is the status of the VolumeSnapshot
type VolumeSnapshotStatus struct {
// boundVolumeSnapshotContentName represents the name of the VolumeSnapshotContent
// object to which the VolumeSnapshot object is bound.
// If not specified, it indicates that the VolumeSnapshot object has not been
// successfully bound to a VolumeSnapshotContent object yet.
// NOTE: Specified boundVolumeSnapshotContentName alone does not mean binding
// is valid. Controllers MUST always verify bidirectional binding between
// VolumeSnapshot and VolumeSnapshotContent to avoid possible security issues.
// +optional
BoundVolumeSnapshotContentName *string `json:"boundVolumeSnapshotContentName,omitempty" protobuf:"bytes,1,opt,name=boundVolumeSnapshotContentName"`
// creationTime is the timestamp when the point-in-time snapshot is taken
// by the underlying storage system.
// In dynamic snapshot creation case, this field will be filled in with the
// "creation_time" value returned from CSI "CreateSnapshotRequest" gRPC call.
// For a pre-existing snapshot, this field will be filled with the "creation_time"
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it.
// If not specified, it indicates that the creation time of the snapshot is unknown.
// +optional
CreationTime *metav1.Time `json:"creationTime,omitempty" protobuf:"bytes,2,opt,name=creationTime"`
// readyToUse indicates if a snapshot is ready to be used to restore a volume.
// In dynamic snapshot creation case, this field will be filled in with the
// "ready_to_use" value returned from CSI "CreateSnapshotRequest" gRPC call.
// For a pre-existing snapshot, this field will be filled with the "ready_to_use"
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it,
// otherwise, this field will be set to "True".
// If not specified, it means the readiness of a snapshot is unknown.
// +optional
ReadyToUse *bool `json:"readyToUse,omitempty" protobuf:"varint,3,opt,name=readyToUse"`
// restoreSize represents the complete size of the snapshot in bytes.
// In dynamic snapshot creation case, this field will be filled in with the
// "size_bytes" value returned from CSI "CreateSnapshotRequest" gRPC call.
// For a pre-existing snapshot, this field will be filled with the "size_bytes"
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it.
// When restoring a volume from this snapshot, the size of the volume MUST NOT
// be smaller than the restoreSize if it is specified, otherwise the restoration will fail.
// If not specified, it indicates that the size is unknown.
// +optional
RestoreSize *resource.Quantity `json:"restoreSize,omitempty" protobuf:"bytes,4,opt,name=restoreSize"`
// error is the last observed error during snapshot creation, if any.
// This field could be helpful to upper level controllers(i.e., application controller)
// to decide whether they should continue on waiting for the snapshot to be created
// based on the type of error reported.
// +optional
Error *VolumeSnapshotError `json:"error,omitempty" protobuf:"bytes,5,opt,name=error,casttype=VolumeSnapshotError"`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotClass specifies parameters that a underlying storage system uses when
// creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its
// name in a VolumeSnapshot object.
// VolumeSnapshotClasses are non-namespaced
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster
type VolumeSnapshotClass struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// driver is the name of the storage driver that handles this VolumeSnapshotClass.
// Required.
Driver string `json:"driver" protobuf:"bytes,2,opt,name=driver"`
// parameters is a key-value map with storage driver specific parameters for creating snapshots.
// These values are opaque to Kubernetes.
// +optional
Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"`
// deletionPolicy determines whether a VolumeSnapshotContent created through
// the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted.
// Supported values are "Retain" and "Delete".
// "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept.
// "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted.
// Required.
DeletionPolicy DeletionPolicy `json:"deletionPolicy" protobuf:"bytes,4,opt,name=deletionPolicy"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotClassList is a collection of VolumeSnapshotClasses.
// +kubebuilder:object:root=true
type VolumeSnapshotClassList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// items is the list of VolumeSnapshotClasses
Items []VolumeSnapshotClass `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotContent represents the actual "on-disk" snapshot object in the
// underlying storage system
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:subresource:status
type VolumeSnapshotContent struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// spec defines properties of a VolumeSnapshotContent created by the underlying storage system.
// Required.
Spec VolumeSnapshotContentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
// status represents the current information of a snapshot.
// +optional
Status *VolumeSnapshotContentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// VolumeSnapshotContentList is a list of VolumeSnapshotContent objects
// +kubebuilder:object:root=true
type VolumeSnapshotContentList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// items is the list of VolumeSnapshotContents
Items []VolumeSnapshotContent `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// VolumeSnapshotContentSpec is the specification of a VolumeSnapshotContent
type VolumeSnapshotContentSpec struct {
// volumeSnapshotRef specifies the VolumeSnapshot object to which this
// VolumeSnapshotContent object is bound.
// VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to
// this VolumeSnapshotContent's name for the bidirectional binding to be valid.
// For a pre-existing VolumeSnapshotContent object, name and namespace of the
// VolumeSnapshot object MUST be provided for binding to happen.
// This field is immutable after creation.
// Required.
VolumeSnapshotRef core_v1.ObjectReference `json:"volumeSnapshotRef" protobuf:"bytes,1,opt,name=volumeSnapshotRef"`
// deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on
// the underlying storage system should be deleted when its bound VolumeSnapshot is deleted.
// Supported values are "Retain" and "Delete".
// "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept.
// "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted.
// In dynamic snapshot creation case, this field will be filled in with the "DeletionPolicy" field defined in the
// VolumeSnapshotClass the VolumeSnapshot refers to.
// For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object.
// Required.
DeletionPolicy DeletionPolicy `json:"deletionPolicy" protobuf:"bytes,2,opt,name=deletionPolicy"`
// driver is the name of the CSI driver used to create the physical snapshot on
// the underlying storage system.
// This MUST be the same as the name returned by the CSI GetPluginName() call for
// that driver.
// Required.
Driver string `json:"driver" protobuf:"bytes,3,opt,name=driver"`
// name of the VolumeSnapshotClass to which this snapshot belongs.
// +optional
VolumeSnapshotClassName *string `json:"volumeSnapshotClassName,omitempty" protobuf:"bytes,4,opt,name=volumeSnapshotClassName"`
// source specifies from where a snapshot will be created.
// This field is immutable after creation.
// Required.
Source VolumeSnapshotContentSource `json:"source" protobuf:"bytes,5,opt,name=source"`
}
// VolumeSnapshotContentSource represents the CSI source of a snapshot.
// Exactly one of its members must be set.
// Members in VolumeSnapshotContentSource are immutable.
// TODO(xiangqian): Add a webhook to ensure that VolumeSnapshotContentSource members
// will be immutable once specified.
type VolumeSnapshotContentSource struct {
// volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot
// should be dynamically taken from.
// This field is immutable.
// +optional
VolumeHandle *string `json:"volumeHandle,omitempty" protobuf:"bytes,1,opt,name=volumeHandle"`
// snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on
// the underlying storage system.
// This field is immutable.
// +optional
SnapshotHandle *string `json:"snapshotHandle,omitempty" protobuf:"bytes,2,opt,name=snapshotHandle"`
}
// VolumeSnapshotContentStatus is the status of a VolumeSnapshotContent object
type VolumeSnapshotContentStatus struct {
// snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system.
// If not specified, it indicates that dynamic snapshot creation has either failed
// or it is still in progress.
// +optional
SnapshotHandle *string `json:"snapshotHandle,omitempty" protobuf:"bytes,1,opt,name=snapshotHandle"`
// creationTime is the timestamp when the point-in-time snapshot is taken
// by the underlying storage system.
// In dynamic snapshot creation case, this field will be filled in with the
// "creation_time" value returned from CSI "CreateSnapshotRequest" gRPC call.
// For a pre-existing snapshot, this field will be filled with the "creation_time"
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it.
// If not specified, it indicates the creation time is unknown.
// The format of this field is a Unix nanoseconds time encoded as an int64.
// On Unix, the command `date +%s%N` returns the current time in nanoseconds
// since 1970-01-01 00:00:00 UTC.
// +optional
CreationTime *int64 `json:"creationTime,omitempty" protobuf:"varint,2,opt,name=creationTime"`
// restoreSize represents the complete size of the snapshot in bytes.
// In dynamic snapshot creation case, this field will be filled in with the
// "size_bytes" value returned from CSI "CreateSnapshotRequest" gRPC call.
// For a pre-existing snapshot, this field will be filled with the "size_bytes"
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it.
// When restoring a volume from this snapshot, the size of the volume MUST NOT
// be smaller than the restoreSize if it is specified, otherwise the restoration will fail.
// If not specified, it indicates that the size is unknown.
// +kubebuilder:validation:Minimum=0
// +optional
RestoreSize *int64 `json:"restoreSize,omitempty" protobuf:"bytes,3,opt,name=restoreSize"`
// readyToUse indicates if a snapshot is ready to be used to restore a volume.
// In dynamic snapshot creation case, this field will be filled in with the
// "ready_to_use" value returned from CSI "CreateSnapshotRequest" gRPC call.
// For a pre-existing snapshot, this field will be filled with the "ready_to_use"
// value returned from the CSI "ListSnapshots" gRPC call if the driver supports it,
// otherwise, this field will be set to "True".
// If not specified, it means the readiness of a snapshot is unknown.
// +optional.
ReadyToUse *bool `json:"readyToUse,omitempty" protobuf:"varint,4,opt,name=readyToUse"`
// error is the latest observed error during snapshot creation, if any.
// +optional
Error *VolumeSnapshotError `json:"error,omitempty" protobuf:"bytes,5,opt,name=error,casttype=VolumeSnapshotError"`
}
// DeletionPolicy describes a policy for end-of-life maintenance of volume snapshot contents
// +kubebuilder:validation:Enum=Delete;Retain
type DeletionPolicy string
const (
// volumeSnapshotContentDelete means the snapshot will be deleted from the
// underlying storage system on release from its volume snapshot.
VolumeSnapshotContentDelete DeletionPolicy = "Delete"
// volumeSnapshotContentRetain means the snapshot will be left in its current
// state on release from its volume snapshot.
VolumeSnapshotContentRetain DeletionPolicy = "Retain"
)
// VolumeSnapshotError describes an error encountered during snapshot creation.
type VolumeSnapshotError struct {
// time is the timestamp when the error was encountered.
// +optional
Time *metav1.Time `json:"time,omitempty" protobuf:"bytes,1,opt,name=time"`
// message is a string detailing the encountered error during snapshot
// creation if specified.
// NOTE: message may be logged, and it should not contain sensitive
// information.
// +optional
Message *string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
}

View File

@@ -2,13 +2,10 @@
/* /*
Copyright 2019 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.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,50 +13,25 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// Code generated by deepcopy-gen. DO NOT EDIT. // Code generated by controller-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime"
v1beta1 "k8s.io/api/storage/v1beta1"
runtime "k8s.io/apimachinery/pkg/runtime"
) )
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CSIVolumeSnapshotSource) DeepCopyInto(out *CSIVolumeSnapshotSource) {
*out = *in
if in.CreationTime != nil {
in, out := &in.CreationTime, &out.CreationTime
*out = new(int64)
**out = **in
}
if in.RestoreSize != nil {
in, out := &in.RestoreSize, &out.RestoreSize
*out = new(int64)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSIVolumeSnapshotSource.
func (in *CSIVolumeSnapshotSource) DeepCopy() *CSIVolumeSnapshotSource {
if in == nil {
return nil
}
out := new(CSIVolumeSnapshotSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshot) DeepCopyInto(out *VolumeSnapshot) { func (in *VolumeSnapshot) DeepCopyInto(out *VolumeSnapshot) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec) in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status) if in.Status != nil {
return in, out := &in.Status, &out.Status
*out = new(VolumeSnapshotStatus)
(*in).DeepCopyInto(*out)
}
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshot. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshot.
@@ -92,12 +64,6 @@ func (in *VolumeSnapshotClass) DeepCopyInto(out *VolumeSnapshotClass) {
(*out)[key] = val (*out)[key] = val
} }
} }
if in.DeletionPolicy != nil {
in, out := &in.DeletionPolicy, &out.DeletionPolicy
*out = new(DeletionPolicy)
**out = **in
}
return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotClass. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotClass.
@@ -122,7 +88,7 @@ func (in *VolumeSnapshotClass) DeepCopyObject() runtime.Object {
func (in *VolumeSnapshotClassList) DeepCopyInto(out *VolumeSnapshotClassList) { func (in *VolumeSnapshotClassList) DeepCopyInto(out *VolumeSnapshotClassList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]VolumeSnapshotClass, len(*in)) *out = make([]VolumeSnapshotClass, len(*in))
@@ -130,7 +96,6 @@ func (in *VolumeSnapshotClassList) DeepCopyInto(out *VolumeSnapshotClassList) {
(*in)[i].DeepCopyInto(&(*out)[i]) (*in)[i].DeepCopyInto(&(*out)[i])
} }
} }
return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotClassList. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotClassList.
@@ -157,7 +122,11 @@ func (in *VolumeSnapshotContent) DeepCopyInto(out *VolumeSnapshotContent) {
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec) in.Spec.DeepCopyInto(&out.Spec)
return if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(VolumeSnapshotContentStatus)
(*in).DeepCopyInto(*out)
}
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContent. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContent.
@@ -182,7 +151,7 @@ func (in *VolumeSnapshotContent) DeepCopyObject() runtime.Object {
func (in *VolumeSnapshotContentList) DeepCopyInto(out *VolumeSnapshotContentList) { func (in *VolumeSnapshotContentList) DeepCopyInto(out *VolumeSnapshotContentList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]VolumeSnapshotContent, len(*in)) *out = make([]VolumeSnapshotContent, len(*in))
@@ -190,7 +159,6 @@ func (in *VolumeSnapshotContentList) DeepCopyInto(out *VolumeSnapshotContentList
(*in)[i].DeepCopyInto(&(*out)[i]) (*in)[i].DeepCopyInto(&(*out)[i])
} }
} }
return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentList. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentList.
@@ -211,31 +179,41 @@ func (in *VolumeSnapshotContentList) DeepCopyObject() runtime.Object {
return nil return nil
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshotContentSource) DeepCopyInto(out *VolumeSnapshotContentSource) {
*out = *in
if in.VolumeHandle != nil {
in, out := &in.VolumeHandle, &out.VolumeHandle
*out = new(string)
**out = **in
}
if in.SnapshotHandle != nil {
in, out := &in.SnapshotHandle, &out.SnapshotHandle
*out = new(string)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentSource.
func (in *VolumeSnapshotContentSource) DeepCopy() *VolumeSnapshotContentSource {
if in == nil {
return nil
}
out := new(VolumeSnapshotContentSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshotContentSpec) DeepCopyInto(out *VolumeSnapshotContentSpec) { func (in *VolumeSnapshotContentSpec) DeepCopyInto(out *VolumeSnapshotContentSpec) {
*out = *in *out = *in
in.VolumeSnapshotSource.DeepCopyInto(&out.VolumeSnapshotSource) out.VolumeSnapshotRef = in.VolumeSnapshotRef
if in.VolumeSnapshotRef != nil {
in, out := &in.VolumeSnapshotRef, &out.VolumeSnapshotRef
*out = new(v1.ObjectReference)
**out = **in
}
if in.PersistentVolumeRef != nil {
in, out := &in.PersistentVolumeRef, &out.PersistentVolumeRef
*out = new(v1.ObjectReference)
**out = **in
}
if in.VolumeSnapshotClassName != nil { if in.VolumeSnapshotClassName != nil {
in, out := &in.VolumeSnapshotClassName, &out.VolumeSnapshotClassName in, out := &in.VolumeSnapshotClassName, &out.VolumeSnapshotClassName
*out = new(string) *out = new(string)
**out = **in **out = **in
} }
if in.DeletionPolicy != nil { in.Source.DeepCopyInto(&out.Source)
in, out := &in.DeletionPolicy, &out.DeletionPolicy
*out = new(DeletionPolicy)
**out = **in
}
return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentSpec. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentSpec.
@@ -248,11 +226,75 @@ func (in *VolumeSnapshotContentSpec) DeepCopy() *VolumeSnapshotContentSpec {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshotContentStatus) DeepCopyInto(out *VolumeSnapshotContentStatus) {
*out = *in
if in.SnapshotHandle != nil {
in, out := &in.SnapshotHandle, &out.SnapshotHandle
*out = new(string)
**out = **in
}
if in.CreationTime != nil {
in, out := &in.CreationTime, &out.CreationTime
*out = new(int64)
**out = **in
}
if in.RestoreSize != nil {
in, out := &in.RestoreSize, &out.RestoreSize
*out = new(int64)
**out = **in
}
if in.ReadyToUse != nil {
in, out := &in.ReadyToUse, &out.ReadyToUse
*out = new(bool)
**out = **in
}
if in.Error != nil {
in, out := &in.Error, &out.Error
*out = new(VolumeSnapshotError)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotContentStatus.
func (in *VolumeSnapshotContentStatus) DeepCopy() *VolumeSnapshotContentStatus {
if in == nil {
return nil
}
out := new(VolumeSnapshotContentStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshotError) DeepCopyInto(out *VolumeSnapshotError) {
*out = *in
if in.Time != nil {
in, out := &in.Time, &out.Time
*out = (*in).DeepCopy()
}
if in.Message != nil {
in, out := &in.Message, &out.Message
*out = new(string)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotError.
func (in *VolumeSnapshotError) DeepCopy() *VolumeSnapshotError {
if in == nil {
return nil
}
out := new(VolumeSnapshotError)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshotList) DeepCopyInto(out *VolumeSnapshotList) { func (in *VolumeSnapshotList) DeepCopyInto(out *VolumeSnapshotList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]VolumeSnapshot, len(*in)) *out = make([]VolumeSnapshot, len(*in))
@@ -260,7 +302,6 @@ func (in *VolumeSnapshotList) DeepCopyInto(out *VolumeSnapshotList) {
(*in)[i].DeepCopyInto(&(*out)[i]) (*in)[i].DeepCopyInto(&(*out)[i])
} }
} }
return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotList. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotList.
@@ -284,12 +325,16 @@ func (in *VolumeSnapshotList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshotSource) DeepCopyInto(out *VolumeSnapshotSource) { func (in *VolumeSnapshotSource) DeepCopyInto(out *VolumeSnapshotSource) {
*out = *in *out = *in
if in.CSI != nil { if in.PersistentVolumeClaimName != nil {
in, out := &in.CSI, &out.CSI in, out := &in.PersistentVolumeClaimName, &out.PersistentVolumeClaimName
*out = new(CSIVolumeSnapshotSource) *out = new(string)
(*in).DeepCopyInto(*out) **out = **in
}
if in.VolumeSnapshotContentName != nil {
in, out := &in.VolumeSnapshotContentName, &out.VolumeSnapshotContentName
*out = new(string)
**out = **in
} }
return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotSource. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotSource.
@@ -305,17 +350,12 @@ func (in *VolumeSnapshotSource) DeepCopy() *VolumeSnapshotSource {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshotSpec) DeepCopyInto(out *VolumeSnapshotSpec) { func (in *VolumeSnapshotSpec) DeepCopyInto(out *VolumeSnapshotSpec) {
*out = *in *out = *in
if in.Source != nil { in.Source.DeepCopyInto(&out.Source)
in, out := &in.Source, &out.Source
*out = new(v1.TypedLocalObjectReference)
(*in).DeepCopyInto(*out)
}
if in.VolumeSnapshotClassName != nil { if in.VolumeSnapshotClassName != nil {
in, out := &in.VolumeSnapshotClassName, &out.VolumeSnapshotClassName in, out := &in.VolumeSnapshotClassName, &out.VolumeSnapshotClassName
*out = new(string) *out = new(string)
**out = **in **out = **in
} }
return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotSpec. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotSpec.
@@ -331,10 +371,20 @@ func (in *VolumeSnapshotSpec) DeepCopy() *VolumeSnapshotSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeSnapshotStatus) DeepCopyInto(out *VolumeSnapshotStatus) { func (in *VolumeSnapshotStatus) DeepCopyInto(out *VolumeSnapshotStatus) {
*out = *in *out = *in
if in.BoundVolumeSnapshotContentName != nil {
in, out := &in.BoundVolumeSnapshotContentName, &out.BoundVolumeSnapshotContentName
*out = new(string)
**out = **in
}
if in.CreationTime != nil { if in.CreationTime != nil {
in, out := &in.CreationTime, &out.CreationTime in, out := &in.CreationTime, &out.CreationTime
*out = (*in).DeepCopy() *out = (*in).DeepCopy()
} }
if in.ReadyToUse != nil {
in, out := &in.ReadyToUse, &out.ReadyToUse
*out = new(bool)
**out = **in
}
if in.RestoreSize != nil { if in.RestoreSize != nil {
in, out := &in.RestoreSize, &out.RestoreSize in, out := &in.RestoreSize, &out.RestoreSize
x := (*in).DeepCopy() x := (*in).DeepCopy()
@@ -342,10 +392,9 @@ func (in *VolumeSnapshotStatus) DeepCopyInto(out *VolumeSnapshotStatus) {
} }
if in.Error != nil { if in.Error != nil {
in, out := &in.Error, &out.Error in, out := &in.Error, &out.Error
*out = new(v1beta1.VolumeError) *out = new(VolumeSnapshotError)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
return
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotStatus. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSnapshotStatus.

View File

@@ -19,7 +19,7 @@ limitations under the License.
package versioned package versioned
import ( import (
snapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1" snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1"
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,19 +27,19 @@ import (
type Interface interface { type Interface interface {
Discovery() discovery.DiscoveryInterface Discovery() discovery.DiscoveryInterface
SnapshotV1alpha1() snapshotv1alpha1.SnapshotV1alpha1Interface SnapshotV1beta1() snapshotv1beta1.SnapshotV1beta1Interface
} }
// 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
snapshotV1alpha1 *snapshotv1alpha1.SnapshotV1alpha1Client snapshotV1beta1 *snapshotv1beta1.SnapshotV1beta1Client
} }
// SnapshotV1alpha1 retrieves the SnapshotV1alpha1Client // SnapshotV1beta1 retrieves the SnapshotV1beta1Client
func (c *Clientset) SnapshotV1alpha1() snapshotv1alpha1.SnapshotV1alpha1Interface { func (c *Clientset) SnapshotV1beta1() snapshotv1beta1.SnapshotV1beta1Interface {
return c.snapshotV1alpha1 return c.snapshotV1beta1
} }
// Discovery retrieves the DiscoveryClient // Discovery retrieves the DiscoveryClient
@@ -58,7 +58,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
} }
var cs Clientset var cs Clientset
var err error var err error
cs.snapshotV1alpha1, err = snapshotv1alpha1.NewForConfig(&configShallowCopy) cs.snapshotV1beta1, err = snapshotv1beta1.NewForConfig(&configShallowCopy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -74,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.snapshotV1alpha1 = snapshotv1alpha1.NewForConfigOrDie(c) cs.snapshotV1beta1 = snapshotv1beta1.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs return &cs
@@ -83,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.snapshotV1alpha1 = snapshotv1alpha1.New(c) cs.snapshotV1beta1 = snapshotv1beta1.New(c)
cs.DiscoveryClient = discovery.NewDiscoveryClient(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &cs return &cs

View File

@@ -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"
snapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1" snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1"
fakesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/fake" fakesnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1/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,7 +71,7 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
var _ clientset.Interface = &Clientset{} var _ clientset.Interface = &Clientset{}
// SnapshotV1alpha1 retrieves the SnapshotV1alpha1Client // SnapshotV1beta1 retrieves the SnapshotV1beta1Client
func (c *Clientset) SnapshotV1alpha1() snapshotv1alpha1.SnapshotV1alpha1Interface { func (c *Clientset) SnapshotV1beta1() snapshotv1beta1.SnapshotV1beta1Interface {
return &fakesnapshotv1alpha1.FakeSnapshotV1alpha1{Fake: &c.Fake} return &fakesnapshotv1beta1.FakeSnapshotV1beta1{Fake: &c.Fake}
} }

View File

@@ -19,7 +19,7 @@ limitations under the License.
package fake package fake
import ( import (
snapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
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{
snapshotv1alpha1.AddToScheme, snapshotv1beta1.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

View File

@@ -19,7 +19,7 @@ limitations under the License.
package scheme package scheme
import ( import (
snapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
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{
snapshotv1alpha1.AddToScheme, snapshotv1beta1.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

View File

@@ -17,4 +17,4 @@ limitations under the License.
// Code generated by client-gen. DO NOT EDIT. // Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients. // This package has the automatically generated typed clients.
package v1alpha1 package v1beta1

View File

@@ -19,7 +19,7 @@ limitations under the License.
package fake package fake
import ( import (
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels" labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema" schema "k8s.io/apimachinery/pkg/runtime/schema"
@@ -30,29 +30,29 @@ import (
// FakeVolumeSnapshots implements VolumeSnapshotInterface // FakeVolumeSnapshots implements VolumeSnapshotInterface
type FakeVolumeSnapshots struct { type FakeVolumeSnapshots struct {
Fake *FakeSnapshotV1alpha1 Fake *FakeSnapshotV1beta1
ns string ns string
} }
var volumesnapshotsResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Resource: "volumesnapshots"} var volumesnapshotsResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1beta1", Resource: "volumesnapshots"}
var volumesnapshotsKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Kind: "VolumeSnapshot"} var volumesnapshotsKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1beta1", 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 *v1beta1.VolumeSnapshot, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewGetAction(volumesnapshotsResource, c.ns, name), &v1alpha1.VolumeSnapshot{}) Invokes(testing.NewGetAction(volumesnapshotsResource, c.ns, name), &v1beta1.VolumeSnapshot{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshot), err return obj.(*v1beta1.VolumeSnapshot), err
} }
// List takes label and field selectors, and returns the list of VolumeSnapshots that match those selectors. // List takes label and field selectors, and returns the list of VolumeSnapshots that match those selectors.
func (c *FakeVolumeSnapshots) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotList, err error) { func (c *FakeVolumeSnapshots) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotList, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewListAction(volumesnapshotsResource, volumesnapshotsKind, c.ns, opts), &v1alpha1.VolumeSnapshotList{}) Invokes(testing.NewListAction(volumesnapshotsResource, volumesnapshotsKind, c.ns, opts), &v1beta1.VolumeSnapshotList{})
if obj == nil { if obj == nil {
return nil, err return nil, err
@@ -62,8 +62,8 @@ func (c *FakeVolumeSnapshots) List(opts v1.ListOptions) (result *v1alpha1.Volume
if label == nil { if label == nil {
label = labels.Everything() label = labels.Everything()
} }
list := &v1alpha1.VolumeSnapshotList{ListMeta: obj.(*v1alpha1.VolumeSnapshotList).ListMeta} list := &v1beta1.VolumeSnapshotList{ListMeta: obj.(*v1beta1.VolumeSnapshotList).ListMeta}
for _, item := range obj.(*v1alpha1.VolumeSnapshotList).Items { for _, item := range obj.(*v1beta1.VolumeSnapshotList).Items {
if label.Matches(labels.Set(item.Labels)) { if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item) list.Items = append(list.Items, item)
} }
@@ -79,43 +79,43 @@ func (c *FakeVolumeSnapshots) Watch(opts v1.ListOptions) (watch.Interface, error
} }
// Create takes the representation of a volumeSnapshot and creates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any. // Create takes the representation of a volumeSnapshot and creates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any.
func (c *FakeVolumeSnapshots) Create(volumeSnapshot *v1alpha1.VolumeSnapshot) (result *v1alpha1.VolumeSnapshot, err error) { func (c *FakeVolumeSnapshots) Create(volumeSnapshot *v1beta1.VolumeSnapshot) (result *v1beta1.VolumeSnapshot, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewCreateAction(volumesnapshotsResource, c.ns, volumeSnapshot), &v1alpha1.VolumeSnapshot{}) Invokes(testing.NewCreateAction(volumesnapshotsResource, c.ns, volumeSnapshot), &v1beta1.VolumeSnapshot{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshot), err return obj.(*v1beta1.VolumeSnapshot), err
} }
// Update takes the representation of a volumeSnapshot and updates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any. // Update takes the representation of a volumeSnapshot and updates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any.
func (c *FakeVolumeSnapshots) Update(volumeSnapshot *v1alpha1.VolumeSnapshot) (result *v1alpha1.VolumeSnapshot, err error) { func (c *FakeVolumeSnapshots) Update(volumeSnapshot *v1beta1.VolumeSnapshot) (result *v1beta1.VolumeSnapshot, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewUpdateAction(volumesnapshotsResource, c.ns, volumeSnapshot), &v1alpha1.VolumeSnapshot{}) Invokes(testing.NewUpdateAction(volumesnapshotsResource, c.ns, volumeSnapshot), &v1beta1.VolumeSnapshot{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshot), err return obj.(*v1beta1.VolumeSnapshot), err
} }
// UpdateStatus was generated because the type contains a Status member. // UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeVolumeSnapshots) UpdateStatus(volumeSnapshot *v1alpha1.VolumeSnapshot) (*v1alpha1.VolumeSnapshot, error) { func (c *FakeVolumeSnapshots) UpdateStatus(volumeSnapshot *v1beta1.VolumeSnapshot) (*v1beta1.VolumeSnapshot, error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(volumesnapshotsResource, "status", c.ns, volumeSnapshot), &v1alpha1.VolumeSnapshot{}) Invokes(testing.NewUpdateSubresourceAction(volumesnapshotsResource, "status", c.ns, volumeSnapshot), &v1beta1.VolumeSnapshot{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshot), err return obj.(*v1beta1.VolumeSnapshot), err
} }
// Delete takes name of the volumeSnapshot and deletes it. Returns an error if one occurs. // Delete takes name of the volumeSnapshot and deletes it. Returns an error if one occurs.
func (c *FakeVolumeSnapshots) Delete(name string, options *v1.DeleteOptions) error { func (c *FakeVolumeSnapshots) Delete(name string, options *v1.DeleteOptions) error {
_, err := c.Fake. _, err := c.Fake.
Invokes(testing.NewDeleteAction(volumesnapshotsResource, c.ns, name), &v1alpha1.VolumeSnapshot{}) Invokes(testing.NewDeleteAction(volumesnapshotsResource, c.ns, name), &v1beta1.VolumeSnapshot{})
return err return err
} }
@@ -124,17 +124,17 @@ func (c *FakeVolumeSnapshots) Delete(name string, options *v1.DeleteOptions) err
func (c *FakeVolumeSnapshots) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { func (c *FakeVolumeSnapshots) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(volumesnapshotsResource, c.ns, listOptions) action := testing.NewDeleteCollectionAction(volumesnapshotsResource, c.ns, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha1.VolumeSnapshotList{}) _, err := c.Fake.Invokes(action, &v1beta1.VolumeSnapshotList{})
return err return err
} }
// Patch applies the patch and returns the patched volumeSnapshot. // Patch applies the patch and returns the patched volumeSnapshot.
func (c *FakeVolumeSnapshots) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshot, err error) { func (c *FakeVolumeSnapshots) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshot, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(volumesnapshotsResource, c.ns, name, pt, data, subresources...), &v1alpha1.VolumeSnapshot{}) Invokes(testing.NewPatchSubresourceAction(volumesnapshotsResource, c.ns, name, pt, data, subresources...), &v1beta1.VolumeSnapshot{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshot), err return obj.(*v1beta1.VolumeSnapshot), err
} }

View File

@@ -19,30 +19,30 @@ limitations under the License.
package fake package fake
import ( import (
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/typed/volumesnapshot/v1beta1"
rest "k8s.io/client-go/rest" rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing" testing "k8s.io/client-go/testing"
) )
type FakeSnapshotV1alpha1 struct { type FakeSnapshotV1beta1 struct {
*testing.Fake *testing.Fake
} }
func (c *FakeSnapshotV1alpha1) VolumeSnapshots(namespace string) v1alpha1.VolumeSnapshotInterface { func (c *FakeSnapshotV1beta1) VolumeSnapshots(namespace string) v1beta1.VolumeSnapshotInterface {
return &FakeVolumeSnapshots{c, namespace} return &FakeVolumeSnapshots{c, namespace}
} }
func (c *FakeSnapshotV1alpha1) VolumeSnapshotClasses() v1alpha1.VolumeSnapshotClassInterface { func (c *FakeSnapshotV1beta1) VolumeSnapshotClasses() v1beta1.VolumeSnapshotClassInterface {
return &FakeVolumeSnapshotClasses{c} return &FakeVolumeSnapshotClasses{c}
} }
func (c *FakeSnapshotV1alpha1) VolumeSnapshotContents() v1alpha1.VolumeSnapshotContentInterface { func (c *FakeSnapshotV1beta1) VolumeSnapshotContents() v1beta1.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 *FakeSnapshotV1alpha1) RESTClient() rest.Interface { func (c *FakeSnapshotV1beta1) RESTClient() rest.Interface {
var ret *rest.RESTClient var ret *rest.RESTClient
return ret return ret
} }

View File

@@ -19,7 +19,7 @@ limitations under the License.
package fake package fake
import ( import (
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels" labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema" schema "k8s.io/apimachinery/pkg/runtime/schema"
@@ -30,27 +30,27 @@ import (
// FakeVolumeSnapshotClasses implements VolumeSnapshotClassInterface // FakeVolumeSnapshotClasses implements VolumeSnapshotClassInterface
type FakeVolumeSnapshotClasses struct { type FakeVolumeSnapshotClasses struct {
Fake *FakeSnapshotV1alpha1 Fake *FakeSnapshotV1beta1
} }
var volumesnapshotclassesResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Resource: "volumesnapshotclasses"} var volumesnapshotclassesResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1beta1", Resource: "volumesnapshotclasses"}
var volumesnapshotclassesKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Kind: "VolumeSnapshotClass"} var volumesnapshotclassesKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1beta1", 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 *v1beta1.VolumeSnapshotClass, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootGetAction(volumesnapshotclassesResource, name), &v1alpha1.VolumeSnapshotClass{}) Invokes(testing.NewRootGetAction(volumesnapshotclassesResource, name), &v1beta1.VolumeSnapshotClass{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshotClass), err return obj.(*v1beta1.VolumeSnapshotClass), err
} }
// List takes label and field selectors, and returns the list of VolumeSnapshotClasses that match those selectors. // List takes label and field selectors, and returns the list of VolumeSnapshotClasses that match those selectors.
func (c *FakeVolumeSnapshotClasses) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotClassList, err error) { func (c *FakeVolumeSnapshotClasses) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotClassList, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootListAction(volumesnapshotclassesResource, volumesnapshotclassesKind, opts), &v1alpha1.VolumeSnapshotClassList{}) Invokes(testing.NewRootListAction(volumesnapshotclassesResource, volumesnapshotclassesKind, opts), &v1beta1.VolumeSnapshotClassList{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
@@ -59,8 +59,8 @@ func (c *FakeVolumeSnapshotClasses) List(opts v1.ListOptions) (result *v1alpha1.
if label == nil { if label == nil {
label = labels.Everything() label = labels.Everything()
} }
list := &v1alpha1.VolumeSnapshotClassList{ListMeta: obj.(*v1alpha1.VolumeSnapshotClassList).ListMeta} list := &v1beta1.VolumeSnapshotClassList{ListMeta: obj.(*v1beta1.VolumeSnapshotClassList).ListMeta}
for _, item := range obj.(*v1alpha1.VolumeSnapshotClassList).Items { for _, item := range obj.(*v1beta1.VolumeSnapshotClassList).Items {
if label.Matches(labels.Set(item.Labels)) { if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item) list.Items = append(list.Items, item)
} }
@@ -75,29 +75,29 @@ func (c *FakeVolumeSnapshotClasses) Watch(opts v1.ListOptions) (watch.Interface,
} }
// Create takes the representation of a volumeSnapshotClass and creates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any. // Create takes the representation of a volumeSnapshotClass and creates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any.
func (c *FakeVolumeSnapshotClasses) Create(volumeSnapshotClass *v1alpha1.VolumeSnapshotClass) (result *v1alpha1.VolumeSnapshotClass, err error) { func (c *FakeVolumeSnapshotClasses) Create(volumeSnapshotClass *v1beta1.VolumeSnapshotClass) (result *v1beta1.VolumeSnapshotClass, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(volumesnapshotclassesResource, volumeSnapshotClass), &v1alpha1.VolumeSnapshotClass{}) Invokes(testing.NewRootCreateAction(volumesnapshotclassesResource, volumeSnapshotClass), &v1beta1.VolumeSnapshotClass{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshotClass), err return obj.(*v1beta1.VolumeSnapshotClass), err
} }
// Update takes the representation of a volumeSnapshotClass and updates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any. // Update takes the representation of a volumeSnapshotClass and updates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any.
func (c *FakeVolumeSnapshotClasses) Update(volumeSnapshotClass *v1alpha1.VolumeSnapshotClass) (result *v1alpha1.VolumeSnapshotClass, err error) { func (c *FakeVolumeSnapshotClasses) Update(volumeSnapshotClass *v1beta1.VolumeSnapshotClass) (result *v1beta1.VolumeSnapshotClass, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(volumesnapshotclassesResource, volumeSnapshotClass), &v1alpha1.VolumeSnapshotClass{}) Invokes(testing.NewRootUpdateAction(volumesnapshotclassesResource, volumeSnapshotClass), &v1beta1.VolumeSnapshotClass{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshotClass), err return obj.(*v1beta1.VolumeSnapshotClass), err
} }
// Delete takes name of the volumeSnapshotClass and deletes it. Returns an error if one occurs. // Delete takes name of the volumeSnapshotClass and deletes it. Returns an error if one occurs.
func (c *FakeVolumeSnapshotClasses) Delete(name string, options *v1.DeleteOptions) error { func (c *FakeVolumeSnapshotClasses) Delete(name string, options *v1.DeleteOptions) error {
_, err := c.Fake. _, err := c.Fake.
Invokes(testing.NewRootDeleteAction(volumesnapshotclassesResource, name), &v1alpha1.VolumeSnapshotClass{}) Invokes(testing.NewRootDeleteAction(volumesnapshotclassesResource, name), &v1beta1.VolumeSnapshotClass{})
return err return err
} }
@@ -105,16 +105,16 @@ func (c *FakeVolumeSnapshotClasses) Delete(name string, options *v1.DeleteOption
func (c *FakeVolumeSnapshotClasses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { func (c *FakeVolumeSnapshotClasses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(volumesnapshotclassesResource, listOptions) action := testing.NewRootDeleteCollectionAction(volumesnapshotclassesResource, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha1.VolumeSnapshotClassList{}) _, err := c.Fake.Invokes(action, &v1beta1.VolumeSnapshotClassList{})
return err return err
} }
// Patch applies the patch and returns the patched volumeSnapshotClass. // Patch applies the patch and returns the patched volumeSnapshotClass.
func (c *FakeVolumeSnapshotClasses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshotClass, err error) { func (c *FakeVolumeSnapshotClasses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotClass, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(volumesnapshotclassesResource, name, pt, data, subresources...), &v1alpha1.VolumeSnapshotClass{}) Invokes(testing.NewRootPatchSubresourceAction(volumesnapshotclassesResource, name, pt, data, subresources...), &v1beta1.VolumeSnapshotClass{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshotClass), err return obj.(*v1beta1.VolumeSnapshotClass), err
} }

View File

@@ -19,7 +19,7 @@ limitations under the License.
package fake package fake
import ( import (
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels" labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema" schema "k8s.io/apimachinery/pkg/runtime/schema"
@@ -30,27 +30,27 @@ import (
// FakeVolumeSnapshotContents implements VolumeSnapshotContentInterface // FakeVolumeSnapshotContents implements VolumeSnapshotContentInterface
type FakeVolumeSnapshotContents struct { type FakeVolumeSnapshotContents struct {
Fake *FakeSnapshotV1alpha1 Fake *FakeSnapshotV1beta1
} }
var volumesnapshotcontentsResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Resource: "volumesnapshotcontents"} var volumesnapshotcontentsResource = schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1beta1", Resource: "volumesnapshotcontents"}
var volumesnapshotcontentsKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1alpha1", Kind: "VolumeSnapshotContent"} var volumesnapshotcontentsKind = schema.GroupVersionKind{Group: "snapshot.storage.k8s.io", Version: "v1beta1", 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 *v1beta1.VolumeSnapshotContent, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootGetAction(volumesnapshotcontentsResource, name), &v1alpha1.VolumeSnapshotContent{}) Invokes(testing.NewRootGetAction(volumesnapshotcontentsResource, name), &v1beta1.VolumeSnapshotContent{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshotContent), err return obj.(*v1beta1.VolumeSnapshotContent), err
} }
// List takes label and field selectors, and returns the list of VolumeSnapshotContents that match those selectors. // List takes label and field selectors, and returns the list of VolumeSnapshotContents that match those selectors.
func (c *FakeVolumeSnapshotContents) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotContentList, err error) { func (c *FakeVolumeSnapshotContents) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotContentList, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootListAction(volumesnapshotcontentsResource, volumesnapshotcontentsKind, opts), &v1alpha1.VolumeSnapshotContentList{}) Invokes(testing.NewRootListAction(volumesnapshotcontentsResource, volumesnapshotcontentsKind, opts), &v1beta1.VolumeSnapshotContentList{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
@@ -59,8 +59,8 @@ func (c *FakeVolumeSnapshotContents) List(opts v1.ListOptions) (result *v1alpha1
if label == nil { if label == nil {
label = labels.Everything() label = labels.Everything()
} }
list := &v1alpha1.VolumeSnapshotContentList{ListMeta: obj.(*v1alpha1.VolumeSnapshotContentList).ListMeta} list := &v1beta1.VolumeSnapshotContentList{ListMeta: obj.(*v1beta1.VolumeSnapshotContentList).ListMeta}
for _, item := range obj.(*v1alpha1.VolumeSnapshotContentList).Items { for _, item := range obj.(*v1beta1.VolumeSnapshotContentList).Items {
if label.Matches(labels.Set(item.Labels)) { if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item) list.Items = append(list.Items, item)
} }
@@ -75,29 +75,40 @@ func (c *FakeVolumeSnapshotContents) Watch(opts v1.ListOptions) (watch.Interface
} }
// Create takes the representation of a volumeSnapshotContent and creates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any. // Create takes the representation of a volumeSnapshotContent and creates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any.
func (c *FakeVolumeSnapshotContents) Create(volumeSnapshotContent *v1alpha1.VolumeSnapshotContent) (result *v1alpha1.VolumeSnapshotContent, err error) { func (c *FakeVolumeSnapshotContents) Create(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (result *v1beta1.VolumeSnapshotContent, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(volumesnapshotcontentsResource, volumeSnapshotContent), &v1alpha1.VolumeSnapshotContent{}) Invokes(testing.NewRootCreateAction(volumesnapshotcontentsResource, volumeSnapshotContent), &v1beta1.VolumeSnapshotContent{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshotContent), err return obj.(*v1beta1.VolumeSnapshotContent), err
} }
// Update takes the representation of a volumeSnapshotContent and updates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any. // Update takes the representation of a volumeSnapshotContent and updates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any.
func (c *FakeVolumeSnapshotContents) Update(volumeSnapshotContent *v1alpha1.VolumeSnapshotContent) (result *v1alpha1.VolumeSnapshotContent, err error) { func (c *FakeVolumeSnapshotContents) Update(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (result *v1beta1.VolumeSnapshotContent, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(volumesnapshotcontentsResource, volumeSnapshotContent), &v1alpha1.VolumeSnapshotContent{}) Invokes(testing.NewRootUpdateAction(volumesnapshotcontentsResource, volumeSnapshotContent), &v1beta1.VolumeSnapshotContent{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshotContent), err return obj.(*v1beta1.VolumeSnapshotContent), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeVolumeSnapshotContents) UpdateStatus(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (*v1beta1.VolumeSnapshotContent, error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateSubresourceAction(volumesnapshotcontentsResource, "status", volumeSnapshotContent), &v1beta1.VolumeSnapshotContent{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.VolumeSnapshotContent), err
} }
// Delete takes name of the volumeSnapshotContent and deletes it. Returns an error if one occurs. // Delete takes name of the volumeSnapshotContent and deletes it. Returns an error if one occurs.
func (c *FakeVolumeSnapshotContents) Delete(name string, options *v1.DeleteOptions) error { func (c *FakeVolumeSnapshotContents) Delete(name string, options *v1.DeleteOptions) error {
_, err := c.Fake. _, err := c.Fake.
Invokes(testing.NewRootDeleteAction(volumesnapshotcontentsResource, name), &v1alpha1.VolumeSnapshotContent{}) Invokes(testing.NewRootDeleteAction(volumesnapshotcontentsResource, name), &v1beta1.VolumeSnapshotContent{})
return err return err
} }
@@ -105,16 +116,16 @@ func (c *FakeVolumeSnapshotContents) Delete(name string, options *v1.DeleteOptio
func (c *FakeVolumeSnapshotContents) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { func (c *FakeVolumeSnapshotContents) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(volumesnapshotcontentsResource, listOptions) action := testing.NewRootDeleteCollectionAction(volumesnapshotcontentsResource, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha1.VolumeSnapshotContentList{}) _, err := c.Fake.Invokes(action, &v1beta1.VolumeSnapshotContentList{})
return err return err
} }
// Patch applies the patch and returns the patched volumeSnapshotContent. // Patch applies the patch and returns the patched volumeSnapshotContent.
func (c *FakeVolumeSnapshotContents) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshotContent, err error) { func (c *FakeVolumeSnapshotContents) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotContent, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(volumesnapshotcontentsResource, name, pt, data, subresources...), &v1alpha1.VolumeSnapshotContent{}) Invokes(testing.NewRootPatchSubresourceAction(volumesnapshotcontentsResource, name, pt, data, subresources...), &v1beta1.VolumeSnapshotContent{})
if obj == nil { if obj == nil {
return nil, err return nil, err
} }
return obj.(*v1alpha1.VolumeSnapshotContent), err return obj.(*v1beta1.VolumeSnapshotContent), err
} }

View File

@@ -16,7 +16,7 @@ limitations under the License.
// Code generated by client-gen. DO NOT EDIT. // Code generated by client-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
type VolumeSnapshotExpansion interface{} type VolumeSnapshotExpansion interface{}

View File

@@ -16,12 +16,12 @@ limitations under the License.
// Code generated by client-gen. DO NOT EDIT. // Code generated by client-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
"time" "time"
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types" types "k8s.io/apimachinery/pkg/types"
@@ -37,15 +37,15 @@ type VolumeSnapshotsGetter interface {
// VolumeSnapshotInterface has methods to work with VolumeSnapshot resources. // VolumeSnapshotInterface has methods to work with VolumeSnapshot resources.
type VolumeSnapshotInterface interface { type VolumeSnapshotInterface interface {
Create(*v1alpha1.VolumeSnapshot) (*v1alpha1.VolumeSnapshot, error) Create(*v1beta1.VolumeSnapshot) (*v1beta1.VolumeSnapshot, error)
Update(*v1alpha1.VolumeSnapshot) (*v1alpha1.VolumeSnapshot, error) Update(*v1beta1.VolumeSnapshot) (*v1beta1.VolumeSnapshot, error)
UpdateStatus(*v1alpha1.VolumeSnapshot) (*v1alpha1.VolumeSnapshot, error) UpdateStatus(*v1beta1.VolumeSnapshot) (*v1beta1.VolumeSnapshot, error)
Delete(name string, options *v1.DeleteOptions) error Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options v1.GetOptions) (*v1alpha1.VolumeSnapshot, error) Get(name string, options v1.GetOptions) (*v1beta1.VolumeSnapshot, error)
List(opts v1.ListOptions) (*v1alpha1.VolumeSnapshotList, error) List(opts v1.ListOptions) (*v1beta1.VolumeSnapshotList, error)
Watch(opts v1.ListOptions) (watch.Interface, error) Watch(opts v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshot, err error) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshot, err error)
VolumeSnapshotExpansion VolumeSnapshotExpansion
} }
@@ -56,7 +56,7 @@ type volumeSnapshots struct {
} }
// newVolumeSnapshots returns a VolumeSnapshots // newVolumeSnapshots returns a VolumeSnapshots
func newVolumeSnapshots(c *SnapshotV1alpha1Client, namespace string) *volumeSnapshots { func newVolumeSnapshots(c *SnapshotV1beta1Client, namespace string) *volumeSnapshots {
return &volumeSnapshots{ return &volumeSnapshots{
client: c.RESTClient(), client: c.RESTClient(),
ns: namespace, ns: namespace,
@@ -64,8 +64,8 @@ func newVolumeSnapshots(c *SnapshotV1alpha1Client, namespace string) *volumeSnap
} }
// 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 *volumeSnapshots) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshot, err error) { func (c *volumeSnapshots) Get(name string, options v1.GetOptions) (result *v1beta1.VolumeSnapshot, err error) {
result = &v1alpha1.VolumeSnapshot{} result = &v1beta1.VolumeSnapshot{}
err = c.client.Get(). err = c.client.Get().
Namespace(c.ns). Namespace(c.ns).
Resource("volumesnapshots"). Resource("volumesnapshots").
@@ -77,12 +77,12 @@ func (c *volumeSnapshots) Get(name string, options v1.GetOptions) (result *v1alp
} }
// List takes label and field selectors, and returns the list of VolumeSnapshots that match those selectors. // List takes label and field selectors, and returns the list of VolumeSnapshots that match those selectors.
func (c *volumeSnapshots) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotList, err error) { func (c *volumeSnapshots) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotList, err error) {
var timeout time.Duration var timeout time.Duration
if opts.TimeoutSeconds != nil { if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
} }
result = &v1alpha1.VolumeSnapshotList{} result = &v1beta1.VolumeSnapshotList{}
err = c.client.Get(). err = c.client.Get().
Namespace(c.ns). Namespace(c.ns).
Resource("volumesnapshots"). Resource("volumesnapshots").
@@ -109,8 +109,8 @@ func (c *volumeSnapshots) Watch(opts v1.ListOptions) (watch.Interface, error) {
} }
// Create takes the representation of a volumeSnapshot and creates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any. // Create takes the representation of a volumeSnapshot and creates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any.
func (c *volumeSnapshots) Create(volumeSnapshot *v1alpha1.VolumeSnapshot) (result *v1alpha1.VolumeSnapshot, err error) { func (c *volumeSnapshots) Create(volumeSnapshot *v1beta1.VolumeSnapshot) (result *v1beta1.VolumeSnapshot, err error) {
result = &v1alpha1.VolumeSnapshot{} result = &v1beta1.VolumeSnapshot{}
err = c.client.Post(). err = c.client.Post().
Namespace(c.ns). Namespace(c.ns).
Resource("volumesnapshots"). Resource("volumesnapshots").
@@ -121,8 +121,8 @@ func (c *volumeSnapshots) Create(volumeSnapshot *v1alpha1.VolumeSnapshot) (resul
} }
// Update takes the representation of a volumeSnapshot and updates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any. // Update takes the representation of a volumeSnapshot and updates it. Returns the server's representation of the volumeSnapshot, and an error, if there is any.
func (c *volumeSnapshots) Update(volumeSnapshot *v1alpha1.VolumeSnapshot) (result *v1alpha1.VolumeSnapshot, err error) { func (c *volumeSnapshots) Update(volumeSnapshot *v1beta1.VolumeSnapshot) (result *v1beta1.VolumeSnapshot, err error) {
result = &v1alpha1.VolumeSnapshot{} result = &v1beta1.VolumeSnapshot{}
err = c.client.Put(). err = c.client.Put().
Namespace(c.ns). Namespace(c.ns).
Resource("volumesnapshots"). Resource("volumesnapshots").
@@ -136,8 +136,8 @@ func (c *volumeSnapshots) Update(volumeSnapshot *v1alpha1.VolumeSnapshot) (resul
// UpdateStatus was generated because the type contains a Status member. // UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *volumeSnapshots) UpdateStatus(volumeSnapshot *v1alpha1.VolumeSnapshot) (result *v1alpha1.VolumeSnapshot, err error) { func (c *volumeSnapshots) UpdateStatus(volumeSnapshot *v1beta1.VolumeSnapshot) (result *v1beta1.VolumeSnapshot, err error) {
result = &v1alpha1.VolumeSnapshot{} result = &v1beta1.VolumeSnapshot{}
err = c.client.Put(). err = c.client.Put().
Namespace(c.ns). Namespace(c.ns).
Resource("volumesnapshots"). Resource("volumesnapshots").
@@ -177,8 +177,8 @@ func (c *volumeSnapshots) DeleteCollection(options *v1.DeleteOptions, listOption
} }
// Patch applies the patch and returns the patched volumeSnapshot. // Patch applies the patch and returns the patched volumeSnapshot.
func (c *volumeSnapshots) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshot, err error) { func (c *volumeSnapshots) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshot, err error) {
result = &v1alpha1.VolumeSnapshot{} result = &v1beta1.VolumeSnapshot{}
err = c.client.Patch(pt). err = c.client.Patch(pt).
Namespace(c.ns). Namespace(c.ns).
Resource("volumesnapshots"). Resource("volumesnapshots").

View File

@@ -16,41 +16,41 @@ limitations under the License.
// Code generated by client-gen. DO NOT EDIT. // Code generated by client-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme"
serializer "k8s.io/apimachinery/pkg/runtime/serializer" serializer "k8s.io/apimachinery/pkg/runtime/serializer"
rest "k8s.io/client-go/rest" rest "k8s.io/client-go/rest"
) )
type SnapshotV1alpha1Interface interface { type SnapshotV1beta1Interface interface {
RESTClient() rest.Interface RESTClient() rest.Interface
VolumeSnapshotsGetter VolumeSnapshotsGetter
VolumeSnapshotClassesGetter VolumeSnapshotClassesGetter
VolumeSnapshotContentsGetter VolumeSnapshotContentsGetter
} }
// SnapshotV1alpha1Client is used to interact with features provided by the snapshot.storage.k8s.io group. // SnapshotV1beta1Client is used to interact with features provided by the snapshot.storage.k8s.io group.
type SnapshotV1alpha1Client struct { type SnapshotV1beta1Client struct {
restClient rest.Interface restClient rest.Interface
} }
func (c *SnapshotV1alpha1Client) VolumeSnapshots(namespace string) VolumeSnapshotInterface { func (c *SnapshotV1beta1Client) VolumeSnapshots(namespace string) VolumeSnapshotInterface {
return newVolumeSnapshots(c, namespace) return newVolumeSnapshots(c, namespace)
} }
func (c *SnapshotV1alpha1Client) VolumeSnapshotClasses() VolumeSnapshotClassInterface { func (c *SnapshotV1beta1Client) VolumeSnapshotClasses() VolumeSnapshotClassInterface {
return newVolumeSnapshotClasses(c) return newVolumeSnapshotClasses(c)
} }
func (c *SnapshotV1alpha1Client) VolumeSnapshotContents() VolumeSnapshotContentInterface { func (c *SnapshotV1beta1Client) VolumeSnapshotContents() VolumeSnapshotContentInterface {
return newVolumeSnapshotContents(c) return newVolumeSnapshotContents(c)
} }
// NewForConfig creates a new SnapshotV1alpha1Client for the given config. // NewForConfig creates a new SnapshotV1beta1Client for the given config.
func NewForConfig(c *rest.Config) (*SnapshotV1alpha1Client, error) { func NewForConfig(c *rest.Config) (*SnapshotV1beta1Client, 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) (*SnapshotV1alpha1Client, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &SnapshotV1alpha1Client{client}, nil return &SnapshotV1beta1Client{client}, nil
} }
// NewForConfigOrDie creates a new SnapshotV1alpha1Client for the given config and // NewForConfigOrDie creates a new SnapshotV1beta1Client 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) *SnapshotV1alpha1Client { func NewForConfigOrDie(c *rest.Config) *SnapshotV1beta1Client {
client, err := NewForConfig(c) client, err := NewForConfig(c)
if err != nil { if err != nil {
panic(err) panic(err)
@@ -72,13 +72,13 @@ func NewForConfigOrDie(c *rest.Config) *SnapshotV1alpha1Client {
return client return client
} }
// New creates a new SnapshotV1alpha1Client for the given RESTClient. // New creates a new SnapshotV1beta1Client for the given RESTClient.
func New(c rest.Interface) *SnapshotV1alpha1Client { func New(c rest.Interface) *SnapshotV1beta1Client {
return &SnapshotV1alpha1Client{c} return &SnapshotV1beta1Client{c}
} }
func setConfigDefaults(config *rest.Config) error { func setConfigDefaults(config *rest.Config) error {
gv := v1alpha1.SchemeGroupVersion gv := v1beta1.SchemeGroupVersion
config.GroupVersion = &gv config.GroupVersion = &gv
config.APIPath = "/apis" config.APIPath = "/apis"
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
@@ -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 *SnapshotV1alpha1Client) RESTClient() rest.Interface { func (c *SnapshotV1beta1Client) RESTClient() rest.Interface {
if c == nil { if c == nil {
return nil return nil
} }

View File

@@ -16,12 +16,12 @@ limitations under the License.
// Code generated by client-gen. DO NOT EDIT. // Code generated by client-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
"time" "time"
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types" types "k8s.io/apimachinery/pkg/types"
@@ -37,14 +37,14 @@ type VolumeSnapshotClassesGetter interface {
// VolumeSnapshotClassInterface has methods to work with VolumeSnapshotClass resources. // VolumeSnapshotClassInterface has methods to work with VolumeSnapshotClass resources.
type VolumeSnapshotClassInterface interface { type VolumeSnapshotClassInterface interface {
Create(*v1alpha1.VolumeSnapshotClass) (*v1alpha1.VolumeSnapshotClass, error) Create(*v1beta1.VolumeSnapshotClass) (*v1beta1.VolumeSnapshotClass, error)
Update(*v1alpha1.VolumeSnapshotClass) (*v1alpha1.VolumeSnapshotClass, error) Update(*v1beta1.VolumeSnapshotClass) (*v1beta1.VolumeSnapshotClass, error)
Delete(name string, options *v1.DeleteOptions) error Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options v1.GetOptions) (*v1alpha1.VolumeSnapshotClass, error) Get(name string, options v1.GetOptions) (*v1beta1.VolumeSnapshotClass, error)
List(opts v1.ListOptions) (*v1alpha1.VolumeSnapshotClassList, error) List(opts v1.ListOptions) (*v1beta1.VolumeSnapshotClassList, error)
Watch(opts v1.ListOptions) (watch.Interface, error) Watch(opts v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshotClass, err error) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotClass, err error)
VolumeSnapshotClassExpansion VolumeSnapshotClassExpansion
} }
@@ -54,15 +54,15 @@ type volumeSnapshotClasses struct {
} }
// newVolumeSnapshotClasses returns a VolumeSnapshotClasses // newVolumeSnapshotClasses returns a VolumeSnapshotClasses
func newVolumeSnapshotClasses(c *SnapshotV1alpha1Client) *volumeSnapshotClasses { func newVolumeSnapshotClasses(c *SnapshotV1beta1Client) *volumeSnapshotClasses {
return &volumeSnapshotClasses{ return &volumeSnapshotClasses{
client: c.RESTClient(), client: c.RESTClient(),
} }
} }
// 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 *volumeSnapshotClasses) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshotClass, err error) { func (c *volumeSnapshotClasses) Get(name string, options v1.GetOptions) (result *v1beta1.VolumeSnapshotClass, err error) {
result = &v1alpha1.VolumeSnapshotClass{} result = &v1beta1.VolumeSnapshotClass{}
err = c.client.Get(). err = c.client.Get().
Resource("volumesnapshotclasses"). Resource("volumesnapshotclasses").
Name(name). Name(name).
@@ -73,12 +73,12 @@ func (c *volumeSnapshotClasses) Get(name string, options v1.GetOptions) (result
} }
// List takes label and field selectors, and returns the list of VolumeSnapshotClasses that match those selectors. // List takes label and field selectors, and returns the list of VolumeSnapshotClasses that match those selectors.
func (c *volumeSnapshotClasses) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotClassList, err error) { func (c *volumeSnapshotClasses) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotClassList, err error) {
var timeout time.Duration var timeout time.Duration
if opts.TimeoutSeconds != nil { if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
} }
result = &v1alpha1.VolumeSnapshotClassList{} result = &v1beta1.VolumeSnapshotClassList{}
err = c.client.Get(). err = c.client.Get().
Resource("volumesnapshotclasses"). Resource("volumesnapshotclasses").
VersionedParams(&opts, scheme.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
@@ -103,8 +103,8 @@ func (c *volumeSnapshotClasses) Watch(opts v1.ListOptions) (watch.Interface, err
} }
// Create takes the representation of a volumeSnapshotClass and creates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any. // Create takes the representation of a volumeSnapshotClass and creates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any.
func (c *volumeSnapshotClasses) Create(volumeSnapshotClass *v1alpha1.VolumeSnapshotClass) (result *v1alpha1.VolumeSnapshotClass, err error) { func (c *volumeSnapshotClasses) Create(volumeSnapshotClass *v1beta1.VolumeSnapshotClass) (result *v1beta1.VolumeSnapshotClass, err error) {
result = &v1alpha1.VolumeSnapshotClass{} result = &v1beta1.VolumeSnapshotClass{}
err = c.client.Post(). err = c.client.Post().
Resource("volumesnapshotclasses"). Resource("volumesnapshotclasses").
Body(volumeSnapshotClass). Body(volumeSnapshotClass).
@@ -114,8 +114,8 @@ func (c *volumeSnapshotClasses) Create(volumeSnapshotClass *v1alpha1.VolumeSnaps
} }
// Update takes the representation of a volumeSnapshotClass and updates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any. // Update takes the representation of a volumeSnapshotClass and updates it. Returns the server's representation of the volumeSnapshotClass, and an error, if there is any.
func (c *volumeSnapshotClasses) Update(volumeSnapshotClass *v1alpha1.VolumeSnapshotClass) (result *v1alpha1.VolumeSnapshotClass, err error) { func (c *volumeSnapshotClasses) Update(volumeSnapshotClass *v1beta1.VolumeSnapshotClass) (result *v1beta1.VolumeSnapshotClass, err error) {
result = &v1alpha1.VolumeSnapshotClass{} result = &v1beta1.VolumeSnapshotClass{}
err = c.client.Put(). err = c.client.Put().
Resource("volumesnapshotclasses"). Resource("volumesnapshotclasses").
Name(volumeSnapshotClass.Name). Name(volumeSnapshotClass.Name).
@@ -151,8 +151,8 @@ func (c *volumeSnapshotClasses) DeleteCollection(options *v1.DeleteOptions, list
} }
// Patch applies the patch and returns the patched volumeSnapshotClass. // Patch applies the patch and returns the patched volumeSnapshotClass.
func (c *volumeSnapshotClasses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshotClass, err error) { func (c *volumeSnapshotClasses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotClass, err error) {
result = &v1alpha1.VolumeSnapshotClass{} result = &v1beta1.VolumeSnapshotClass{}
err = c.client.Patch(pt). err = c.client.Patch(pt).
Resource("volumesnapshotclasses"). Resource("volumesnapshotclasses").
SubResource(subresources...). SubResource(subresources...).

View File

@@ -16,12 +16,12 @@ limitations under the License.
// Code generated by client-gen. DO NOT EDIT. // Code generated by client-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
"time" "time"
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types" types "k8s.io/apimachinery/pkg/types"
@@ -37,14 +37,15 @@ type VolumeSnapshotContentsGetter interface {
// VolumeSnapshotContentInterface has methods to work with VolumeSnapshotContent resources. // VolumeSnapshotContentInterface has methods to work with VolumeSnapshotContent resources.
type VolumeSnapshotContentInterface interface { type VolumeSnapshotContentInterface interface {
Create(*v1alpha1.VolumeSnapshotContent) (*v1alpha1.VolumeSnapshotContent, error) Create(*v1beta1.VolumeSnapshotContent) (*v1beta1.VolumeSnapshotContent, error)
Update(*v1alpha1.VolumeSnapshotContent) (*v1alpha1.VolumeSnapshotContent, error) Update(*v1beta1.VolumeSnapshotContent) (*v1beta1.VolumeSnapshotContent, error)
UpdateStatus(*v1beta1.VolumeSnapshotContent) (*v1beta1.VolumeSnapshotContent, error)
Delete(name string, options *v1.DeleteOptions) error Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options v1.GetOptions) (*v1alpha1.VolumeSnapshotContent, error) Get(name string, options v1.GetOptions) (*v1beta1.VolumeSnapshotContent, error)
List(opts v1.ListOptions) (*v1alpha1.VolumeSnapshotContentList, error) List(opts v1.ListOptions) (*v1beta1.VolumeSnapshotContentList, error)
Watch(opts v1.ListOptions) (watch.Interface, error) Watch(opts v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshotContent, err error) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotContent, err error)
VolumeSnapshotContentExpansion VolumeSnapshotContentExpansion
} }
@@ -54,15 +55,15 @@ type volumeSnapshotContents struct {
} }
// newVolumeSnapshotContents returns a VolumeSnapshotContents // newVolumeSnapshotContents returns a VolumeSnapshotContents
func newVolumeSnapshotContents(c *SnapshotV1alpha1Client) *volumeSnapshotContents { func newVolumeSnapshotContents(c *SnapshotV1beta1Client) *volumeSnapshotContents {
return &volumeSnapshotContents{ return &volumeSnapshotContents{
client: c.RESTClient(), client: c.RESTClient(),
} }
} }
// 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 *volumeSnapshotContents) Get(name string, options v1.GetOptions) (result *v1alpha1.VolumeSnapshotContent, err error) { func (c *volumeSnapshotContents) Get(name string, options v1.GetOptions) (result *v1beta1.VolumeSnapshotContent, err error) {
result = &v1alpha1.VolumeSnapshotContent{} result = &v1beta1.VolumeSnapshotContent{}
err = c.client.Get(). err = c.client.Get().
Resource("volumesnapshotcontents"). Resource("volumesnapshotcontents").
Name(name). Name(name).
@@ -73,12 +74,12 @@ func (c *volumeSnapshotContents) Get(name string, options v1.GetOptions) (result
} }
// List takes label and field selectors, and returns the list of VolumeSnapshotContents that match those selectors. // List takes label and field selectors, and returns the list of VolumeSnapshotContents that match those selectors.
func (c *volumeSnapshotContents) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotContentList, err error) { func (c *volumeSnapshotContents) List(opts v1.ListOptions) (result *v1beta1.VolumeSnapshotContentList, err error) {
var timeout time.Duration var timeout time.Duration
if opts.TimeoutSeconds != nil { if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
} }
result = &v1alpha1.VolumeSnapshotContentList{} result = &v1beta1.VolumeSnapshotContentList{}
err = c.client.Get(). err = c.client.Get().
Resource("volumesnapshotcontents"). Resource("volumesnapshotcontents").
VersionedParams(&opts, scheme.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
@@ -103,8 +104,8 @@ func (c *volumeSnapshotContents) Watch(opts v1.ListOptions) (watch.Interface, er
} }
// Create takes the representation of a volumeSnapshotContent and creates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any. // Create takes the representation of a volumeSnapshotContent and creates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any.
func (c *volumeSnapshotContents) Create(volumeSnapshotContent *v1alpha1.VolumeSnapshotContent) (result *v1alpha1.VolumeSnapshotContent, err error) { func (c *volumeSnapshotContents) Create(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (result *v1beta1.VolumeSnapshotContent, err error) {
result = &v1alpha1.VolumeSnapshotContent{} result = &v1beta1.VolumeSnapshotContent{}
err = c.client.Post(). err = c.client.Post().
Resource("volumesnapshotcontents"). Resource("volumesnapshotcontents").
Body(volumeSnapshotContent). Body(volumeSnapshotContent).
@@ -114,8 +115,8 @@ func (c *volumeSnapshotContents) Create(volumeSnapshotContent *v1alpha1.VolumeSn
} }
// Update takes the representation of a volumeSnapshotContent and updates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any. // Update takes the representation of a volumeSnapshotContent and updates it. Returns the server's representation of the volumeSnapshotContent, and an error, if there is any.
func (c *volumeSnapshotContents) Update(volumeSnapshotContent *v1alpha1.VolumeSnapshotContent) (result *v1alpha1.VolumeSnapshotContent, err error) { func (c *volumeSnapshotContents) Update(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (result *v1beta1.VolumeSnapshotContent, err error) {
result = &v1alpha1.VolumeSnapshotContent{} result = &v1beta1.VolumeSnapshotContent{}
err = c.client.Put(). err = c.client.Put().
Resource("volumesnapshotcontents"). Resource("volumesnapshotcontents").
Name(volumeSnapshotContent.Name). Name(volumeSnapshotContent.Name).
@@ -125,6 +126,21 @@ func (c *volumeSnapshotContents) Update(volumeSnapshotContent *v1alpha1.VolumeSn
return return
} }
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *volumeSnapshotContents) UpdateStatus(volumeSnapshotContent *v1beta1.VolumeSnapshotContent) (result *v1beta1.VolumeSnapshotContent, err error) {
result = &v1beta1.VolumeSnapshotContent{}
err = c.client.Put().
Resource("volumesnapshotcontents").
Name(volumeSnapshotContent.Name).
SubResource("status").
Body(volumeSnapshotContent).
Do().
Into(result)
return
}
// Delete takes name of the volumeSnapshotContent and deletes it. Returns an error if one occurs. // Delete takes name of the volumeSnapshotContent and deletes it. Returns an error if one occurs.
func (c *volumeSnapshotContents) Delete(name string, options *v1.DeleteOptions) error { func (c *volumeSnapshotContents) Delete(name string, options *v1.DeleteOptions) error {
return c.client.Delete(). return c.client.Delete().
@@ -151,8 +167,8 @@ func (c *volumeSnapshotContents) DeleteCollection(options *v1.DeleteOptions, lis
} }
// Patch applies the patch and returns the patched volumeSnapshotContent. // Patch applies the patch and returns the patched volumeSnapshotContent.
func (c *volumeSnapshotContents) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.VolumeSnapshotContent, err error) { func (c *volumeSnapshotContents) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.VolumeSnapshotContent, err error) {
result = &v1alpha1.VolumeSnapshotContent{} result = &v1beta1.VolumeSnapshotContent{}
err = c.client.Patch(pt). err = c.client.Patch(pt).
Resource("volumesnapshotcontents"). Resource("volumesnapshotcontents").
SubResource(subresources...). SubResource(subresources...).

View File

@@ -21,7 +21,7 @@ package externalversions
import ( import (
"fmt" "fmt"
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
schema "k8s.io/apimachinery/pkg/runtime/schema" schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache" cache "k8s.io/client-go/tools/cache"
) )
@@ -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=snapshot.storage.k8s.io, Version=v1alpha1 // Group=snapshot.storage.k8s.io, Version=v1beta1
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshots"): case v1beta1.SchemeGroupVersion.WithResource("volumesnapshots"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1alpha1().VolumeSnapshots().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1beta1().VolumeSnapshots().Informer()}, nil
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshotclasses"): case v1beta1.SchemeGroupVersion.WithResource("volumesnapshotclasses"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1alpha1().VolumeSnapshotClasses().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1beta1().VolumeSnapshotClasses().Informer()}, nil
case v1alpha1.SchemeGroupVersion.WithResource("volumesnapshotcontents"): case v1beta1.SchemeGroupVersion.WithResource("volumesnapshotcontents"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1alpha1().VolumeSnapshotContents().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.Snapshot().V1beta1().VolumeSnapshotContents().Informer()}, nil
} }

View File

@@ -20,13 +20,13 @@ 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"
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/volumesnapshot/v1beta1"
) )
// Interface provides access to each of this group's versions. // Interface provides access to each of this group's versions.
type Interface interface { type Interface interface {
// V1alpha1 provides access to shared informers for resources in V1alpha1. // V1beta1 provides access to shared informers for resources in V1beta1.
V1alpha1() v1alpha1.Interface V1beta1() v1beta1.Interface
} }
type group struct { type group struct {
@@ -40,7 +40,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
} }
// V1alpha1 returns a new v1alpha1.Interface. // V1beta1 returns a new v1beta1.Interface.
func (g *group) V1alpha1() v1alpha1.Interface { func (g *group) V1beta1() v1beta1.Interface {
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
} }

View File

@@ -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 v1alpha1 package v1beta1
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"

View File

@@ -16,15 +16,15 @@ limitations under the License.
// Code generated by informer-gen. DO NOT EDIT. // Code generated by informer-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
time "time" time "time"
volumesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" volumesnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
versioned "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned" versioned "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/internalinterfaces" internalinterfaces "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/internalinterfaces"
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1beta1"
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"
watch "k8s.io/apimachinery/pkg/watch" watch "k8s.io/apimachinery/pkg/watch"
@@ -35,7 +35,7 @@ import (
// VolumeSnapshots. // VolumeSnapshots.
type VolumeSnapshotInformer interface { type VolumeSnapshotInformer interface {
Informer() cache.SharedIndexInformer Informer() cache.SharedIndexInformer
Lister() v1alpha1.VolumeSnapshotLister Lister() v1beta1.VolumeSnapshotLister
} }
type volumeSnapshotInformer struct { type volumeSnapshotInformer struct {
@@ -61,16 +61,16 @@ func NewFilteredVolumeSnapshotInformer(client versioned.Interface, namespace str
if tweakListOptions != nil { if tweakListOptions != nil {
tweakListOptions(&options) tweakListOptions(&options)
} }
return client.SnapshotV1alpha1().VolumeSnapshots(namespace).List(options) return client.SnapshotV1beta1().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.SnapshotV1alpha1().VolumeSnapshots(namespace).Watch(options) return client.SnapshotV1beta1().VolumeSnapshots(namespace).Watch(options)
}, },
}, },
&volumesnapshotv1alpha1.VolumeSnapshot{}, &volumesnapshotv1beta1.VolumeSnapshot{},
resyncPeriod, resyncPeriod,
indexers, indexers,
) )
@@ -81,9 +81,9 @@ func (f *volumeSnapshotInformer) defaultInformer(client versioned.Interface, res
} }
func (f *volumeSnapshotInformer) Informer() cache.SharedIndexInformer { func (f *volumeSnapshotInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&volumesnapshotv1alpha1.VolumeSnapshot{}, f.defaultInformer) return f.factory.InformerFor(&volumesnapshotv1beta1.VolumeSnapshot{}, f.defaultInformer)
} }
func (f *volumeSnapshotInformer) Lister() v1alpha1.VolumeSnapshotLister { func (f *volumeSnapshotInformer) Lister() v1beta1.VolumeSnapshotLister {
return v1alpha1.NewVolumeSnapshotLister(f.Informer().GetIndexer()) return v1beta1.NewVolumeSnapshotLister(f.Informer().GetIndexer())
} }

View File

@@ -16,15 +16,15 @@ limitations under the License.
// Code generated by informer-gen. DO NOT EDIT. // Code generated by informer-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
time "time" time "time"
volumesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" volumesnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
versioned "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned" versioned "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/internalinterfaces" internalinterfaces "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/internalinterfaces"
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1beta1"
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"
watch "k8s.io/apimachinery/pkg/watch" watch "k8s.io/apimachinery/pkg/watch"
@@ -35,7 +35,7 @@ import (
// VolumeSnapshotClasses. // VolumeSnapshotClasses.
type VolumeSnapshotClassInformer interface { type VolumeSnapshotClassInformer interface {
Informer() cache.SharedIndexInformer Informer() cache.SharedIndexInformer
Lister() v1alpha1.VolumeSnapshotClassLister Lister() v1beta1.VolumeSnapshotClassLister
} }
type volumeSnapshotClassInformer struct { type volumeSnapshotClassInformer struct {
@@ -60,16 +60,16 @@ func NewFilteredVolumeSnapshotClassInformer(client versioned.Interface, resyncPe
if tweakListOptions != nil { if tweakListOptions != nil {
tweakListOptions(&options) tweakListOptions(&options)
} }
return client.SnapshotV1alpha1().VolumeSnapshotClasses().List(options) return client.SnapshotV1beta1().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.SnapshotV1alpha1().VolumeSnapshotClasses().Watch(options) return client.SnapshotV1beta1().VolumeSnapshotClasses().Watch(options)
}, },
}, },
&volumesnapshotv1alpha1.VolumeSnapshotClass{}, &volumesnapshotv1beta1.VolumeSnapshotClass{},
resyncPeriod, resyncPeriod,
indexers, indexers,
) )
@@ -80,9 +80,9 @@ func (f *volumeSnapshotClassInformer) defaultInformer(client versioned.Interface
} }
func (f *volumeSnapshotClassInformer) Informer() cache.SharedIndexInformer { func (f *volumeSnapshotClassInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&volumesnapshotv1alpha1.VolumeSnapshotClass{}, f.defaultInformer) return f.factory.InformerFor(&volumesnapshotv1beta1.VolumeSnapshotClass{}, f.defaultInformer)
} }
func (f *volumeSnapshotClassInformer) Lister() v1alpha1.VolumeSnapshotClassLister { func (f *volumeSnapshotClassInformer) Lister() v1beta1.VolumeSnapshotClassLister {
return v1alpha1.NewVolumeSnapshotClassLister(f.Informer().GetIndexer()) return v1beta1.NewVolumeSnapshotClassLister(f.Informer().GetIndexer())
} }

View File

@@ -16,15 +16,15 @@ limitations under the License.
// Code generated by informer-gen. DO NOT EDIT. // Code generated by informer-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
time "time" time "time"
volumesnapshotv1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" volumesnapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
versioned "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned" versioned "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
internalinterfaces "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/internalinterfaces" internalinterfaces "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/internalinterfaces"
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1beta1"
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"
watch "k8s.io/apimachinery/pkg/watch" watch "k8s.io/apimachinery/pkg/watch"
@@ -35,7 +35,7 @@ import (
// VolumeSnapshotContents. // VolumeSnapshotContents.
type VolumeSnapshotContentInformer interface { type VolumeSnapshotContentInformer interface {
Informer() cache.SharedIndexInformer Informer() cache.SharedIndexInformer
Lister() v1alpha1.VolumeSnapshotContentLister Lister() v1beta1.VolumeSnapshotContentLister
} }
type volumeSnapshotContentInformer struct { type volumeSnapshotContentInformer struct {
@@ -60,16 +60,16 @@ func NewFilteredVolumeSnapshotContentInformer(client versioned.Interface, resync
if tweakListOptions != nil { if tweakListOptions != nil {
tweakListOptions(&options) tweakListOptions(&options)
} }
return client.SnapshotV1alpha1().VolumeSnapshotContents().List(options) return client.SnapshotV1beta1().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.SnapshotV1alpha1().VolumeSnapshotContents().Watch(options) return client.SnapshotV1beta1().VolumeSnapshotContents().Watch(options)
}, },
}, },
&volumesnapshotv1alpha1.VolumeSnapshotContent{}, &volumesnapshotv1beta1.VolumeSnapshotContent{},
resyncPeriod, resyncPeriod,
indexers, indexers,
) )
@@ -80,9 +80,9 @@ func (f *volumeSnapshotContentInformer) defaultInformer(client versioned.Interfa
} }
func (f *volumeSnapshotContentInformer) Informer() cache.SharedIndexInformer { func (f *volumeSnapshotContentInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&volumesnapshotv1alpha1.VolumeSnapshotContent{}, f.defaultInformer) return f.factory.InformerFor(&volumesnapshotv1beta1.VolumeSnapshotContent{}, f.defaultInformer)
} }
func (f *volumeSnapshotContentInformer) Lister() v1alpha1.VolumeSnapshotContentLister { func (f *volumeSnapshotContentInformer) Lister() v1beta1.VolumeSnapshotContentLister {
return v1alpha1.NewVolumeSnapshotContentLister(f.Informer().GetIndexer()) return v1beta1.NewVolumeSnapshotContentLister(f.Informer().GetIndexer())
} }

View File

@@ -16,7 +16,7 @@ limitations under the License.
// Code generated by lister-gen. DO NOT EDIT. // Code generated by lister-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
// VolumeSnapshotListerExpansion allows custom methods to be added to // VolumeSnapshotListerExpansion allows custom methods to be added to
// VolumeSnapshotLister. // VolumeSnapshotLister.

View File

@@ -16,10 +16,10 @@ limitations under the License.
// Code generated by lister-gen. DO NOT EDIT. // Code generated by lister-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
@@ -28,7 +28,7 @@ import (
// VolumeSnapshotLister helps list VolumeSnapshots. // VolumeSnapshotLister helps list VolumeSnapshots.
type VolumeSnapshotLister interface { type VolumeSnapshotLister interface {
// List lists all VolumeSnapshots in the indexer. // List lists all VolumeSnapshots in the indexer.
List(selector labels.Selector) (ret []*v1alpha1.VolumeSnapshot, err error) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshot, err error)
// VolumeSnapshots returns an object that can list and get VolumeSnapshots. // VolumeSnapshots returns an object that can list and get VolumeSnapshots.
VolumeSnapshots(namespace string) VolumeSnapshotNamespaceLister VolumeSnapshots(namespace string) VolumeSnapshotNamespaceLister
VolumeSnapshotListerExpansion VolumeSnapshotListerExpansion
@@ -45,9 +45,9 @@ func NewVolumeSnapshotLister(indexer cache.Indexer) VolumeSnapshotLister {
} }
// List lists all VolumeSnapshots in the indexer. // List lists all VolumeSnapshots in the indexer.
func (s *volumeSnapshotLister) List(selector labels.Selector) (ret []*v1alpha1.VolumeSnapshot, err error) { func (s *volumeSnapshotLister) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshot, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) { err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.VolumeSnapshot)) ret = append(ret, m.(*v1beta1.VolumeSnapshot))
}) })
return ret, err return ret, err
} }
@@ -60,9 +60,9 @@ func (s *volumeSnapshotLister) VolumeSnapshots(namespace string) VolumeSnapshotN
// VolumeSnapshotNamespaceLister helps list and get VolumeSnapshots. // VolumeSnapshotNamespaceLister helps list and get VolumeSnapshots.
type VolumeSnapshotNamespaceLister interface { type VolumeSnapshotNamespaceLister interface {
// List lists all VolumeSnapshots in the indexer for a given namespace. // List lists all VolumeSnapshots in the indexer for a given namespace.
List(selector labels.Selector) (ret []*v1alpha1.VolumeSnapshot, err error) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshot, err error)
// Get retrieves the VolumeSnapshot from the indexer for a given namespace and name. // Get retrieves the VolumeSnapshot from the indexer for a given namespace and name.
Get(name string) (*v1alpha1.VolumeSnapshot, error) Get(name string) (*v1beta1.VolumeSnapshot, error)
VolumeSnapshotNamespaceListerExpansion VolumeSnapshotNamespaceListerExpansion
} }
@@ -74,21 +74,21 @@ type volumeSnapshotNamespaceLister struct {
} }
// List lists all VolumeSnapshots in the indexer for a given namespace. // List lists all VolumeSnapshots in the indexer for a given namespace.
func (s volumeSnapshotNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.VolumeSnapshot, err error) { func (s volumeSnapshotNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshot, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.VolumeSnapshot)) ret = append(ret, m.(*v1beta1.VolumeSnapshot))
}) })
return ret, err return ret, err
} }
// Get retrieves the VolumeSnapshot from the indexer for a given namespace and name. // Get retrieves the VolumeSnapshot from the indexer for a given namespace and name.
func (s volumeSnapshotNamespaceLister) Get(name string) (*v1alpha1.VolumeSnapshot, error) { func (s volumeSnapshotNamespaceLister) Get(name string) (*v1beta1.VolumeSnapshot, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !exists { if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("volumesnapshot"), name) return nil, errors.NewNotFound(v1beta1.Resource("volumesnapshot"), name)
} }
return obj.(*v1alpha1.VolumeSnapshot), nil return obj.(*v1beta1.VolumeSnapshot), nil
} }

View File

@@ -16,10 +16,10 @@ limitations under the License.
// Code generated by lister-gen. DO NOT EDIT. // Code generated by lister-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
@@ -28,9 +28,9 @@ import (
// VolumeSnapshotClassLister helps list VolumeSnapshotClasses. // VolumeSnapshotClassLister helps list VolumeSnapshotClasses.
type VolumeSnapshotClassLister interface { type VolumeSnapshotClassLister interface {
// List lists all VolumeSnapshotClasses in the indexer. // List lists all VolumeSnapshotClasses in the indexer.
List(selector labels.Selector) (ret []*v1alpha1.VolumeSnapshotClass, err error) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshotClass, err error)
// Get retrieves the VolumeSnapshotClass from the index for a given name. // Get retrieves the VolumeSnapshotClass from the index for a given name.
Get(name string) (*v1alpha1.VolumeSnapshotClass, error) Get(name string) (*v1beta1.VolumeSnapshotClass, error)
VolumeSnapshotClassListerExpansion VolumeSnapshotClassListerExpansion
} }
@@ -45,21 +45,21 @@ func NewVolumeSnapshotClassLister(indexer cache.Indexer) VolumeSnapshotClassList
} }
// List lists all VolumeSnapshotClasses in the indexer. // List lists all VolumeSnapshotClasses in the indexer.
func (s *volumeSnapshotClassLister) List(selector labels.Selector) (ret []*v1alpha1.VolumeSnapshotClass, err error) { func (s *volumeSnapshotClassLister) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshotClass, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) { err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.VolumeSnapshotClass)) ret = append(ret, m.(*v1beta1.VolumeSnapshotClass))
}) })
return ret, err return ret, err
} }
// Get retrieves the VolumeSnapshotClass from the index for a given name. // Get retrieves the VolumeSnapshotClass from the index for a given name.
func (s *volumeSnapshotClassLister) Get(name string) (*v1alpha1.VolumeSnapshotClass, error) { func (s *volumeSnapshotClassLister) Get(name string) (*v1beta1.VolumeSnapshotClass, error) {
obj, exists, err := s.indexer.GetByKey(name) obj, exists, err := s.indexer.GetByKey(name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !exists { if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("volumesnapshotclass"), name) return nil, errors.NewNotFound(v1beta1.Resource("volumesnapshotclass"), name)
} }
return obj.(*v1alpha1.VolumeSnapshotClass), nil return obj.(*v1beta1.VolumeSnapshotClass), nil
} }

View File

@@ -16,10 +16,10 @@ limitations under the License.
// Code generated by lister-gen. DO NOT EDIT. // Code generated by lister-gen. DO NOT EDIT.
package v1alpha1 package v1beta1
import ( import (
v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" v1beta1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
@@ -28,9 +28,9 @@ import (
// VolumeSnapshotContentLister helps list VolumeSnapshotContents. // VolumeSnapshotContentLister helps list VolumeSnapshotContents.
type VolumeSnapshotContentLister interface { type VolumeSnapshotContentLister interface {
// List lists all VolumeSnapshotContents in the indexer. // List lists all VolumeSnapshotContents in the indexer.
List(selector labels.Selector) (ret []*v1alpha1.VolumeSnapshotContent, err error) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshotContent, err error)
// Get retrieves the VolumeSnapshotContent from the index for a given name. // Get retrieves the VolumeSnapshotContent from the index for a given name.
Get(name string) (*v1alpha1.VolumeSnapshotContent, error) Get(name string) (*v1beta1.VolumeSnapshotContent, error)
VolumeSnapshotContentListerExpansion VolumeSnapshotContentListerExpansion
} }
@@ -45,21 +45,21 @@ func NewVolumeSnapshotContentLister(indexer cache.Indexer) VolumeSnapshotContent
} }
// List lists all VolumeSnapshotContents in the indexer. // List lists all VolumeSnapshotContents in the indexer.
func (s *volumeSnapshotContentLister) List(selector labels.Selector) (ret []*v1alpha1.VolumeSnapshotContent, err error) { func (s *volumeSnapshotContentLister) List(selector labels.Selector) (ret []*v1beta1.VolumeSnapshotContent, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) { err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.VolumeSnapshotContent)) ret = append(ret, m.(*v1beta1.VolumeSnapshotContent))
}) })
return ret, err return ret, err
} }
// Get retrieves the VolumeSnapshotContent from the index for a given name. // Get retrieves the VolumeSnapshotContent from the index for a given name.
func (s *volumeSnapshotContentLister) Get(name string) (*v1alpha1.VolumeSnapshotContent, error) { func (s *volumeSnapshotContentLister) Get(name string) (*v1beta1.VolumeSnapshotContent, error) {
obj, exists, err := s.indexer.GetByKey(name) obj, exists, err := s.indexer.GetByKey(name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !exists { if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("volumesnapshotcontent"), name) return nil, errors.NewNotFound(v1beta1.Resource("volumesnapshotcontent"), name)
} }
return obj.(*v1alpha1.VolumeSnapshotContent), nil return obj.(*v1beta1.VolumeSnapshotContent), nil
} }

View File

@@ -22,10 +22,10 @@ import (
"strings" "strings"
"time" "time"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"github.com/kubernetes-csi/external-snapshotter/pkg/snapshotter" "github.com/kubernetes-csi/external-snapshotter/pkg/snapshotter"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
) )
// Handler is responsible for handling VolumeSnapshot events from informer. // Handler is responsible for handling VolumeSnapshot events from informer.
@@ -75,13 +75,10 @@ func (handler *csiHandler) CreateSnapshot(snapshot *crdv1.VolumeSnapshot, volume
} }
func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) error { func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) error {
if content.Spec.CSI == nil {
return 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()
err := handler.snapshotter.DeleteSnapshot(ctx, content.Spec.CSI.SnapshotHandle, snapshotterCredentials) err := handler.snapshotter.DeleteSnapshot(ctx, *content.Status.SnapshotHandle, snapshotterCredentials)
if err != nil { if err != nil {
return fmt.Errorf("failed to delete snapshot content %s: %q", content.Name, err) return fmt.Errorf("failed to delete snapshot content %s: %q", content.Name, err)
} }
@@ -90,13 +87,10 @@ func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent,
} }
func (handler *csiHandler) GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (bool, time.Time, int64, error) { func (handler *csiHandler) GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (bool, time.Time, int64, error) {
if content.Spec.CSI == nil {
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.Status.SnapshotHandle)
if err != nil { if err != nil {
return false, time.Time{}, 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)
} }

View File

@@ -29,15 +29,14 @@ import (
"testing" "testing"
"time" "time"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned" clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
"github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/fake" "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/fake"
snapshotscheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" snapshotscheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme"
informers "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions" informers "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions"
storagelisters "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1alpha1" storagelisters "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1beta1"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1" storagev1 "k8s.io/api/storage/v1"
storagev1beta1 "k8s.io/api/storage/v1beta1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
@@ -423,15 +422,8 @@ func (r *snapshotReactor) checkContents(expectedContents []*crdv1.VolumeSnapshot
// Don't modify the existing object // Don't modify the existing object
v := v.DeepCopy() v := v.DeepCopy()
v.ResourceVersion = "" v.ResourceVersion = ""
if v.Spec.VolumeSnapshotRef != nil { v.Spec.VolumeSnapshotRef.ResourceVersion = ""
v.Spec.VolumeSnapshotRef.ResourceVersion = "" v.Status.CreationTime = nil
}
if v.Spec.PersistentVolumeRef != nil {
v.Spec.PersistentVolumeRef.ResourceVersion = ""
}
if v.Spec.CSI != nil {
v.Spec.CSI.CreationTime = nil
}
expectedMap[v.Name] = v expectedMap[v.Name] = v
} }
for _, v := range r.contents { for _, v := range r.contents {
@@ -439,15 +431,8 @@ func (r *snapshotReactor) checkContents(expectedContents []*crdv1.VolumeSnapshot
// written by the controller without any locks on it. // written by the controller without any locks on it.
v := v.DeepCopy() v := v.DeepCopy()
v.ResourceVersion = "" v.ResourceVersion = ""
if v.Spec.VolumeSnapshotRef != nil { v.Spec.VolumeSnapshotRef.ResourceVersion = ""
v.Spec.VolumeSnapshotRef.ResourceVersion = "" v.Status.CreationTime = nil
}
if v.Spec.PersistentVolumeRef != nil {
v.Spec.PersistentVolumeRef.ResourceVersion = ""
}
if v.Spec.CSI != nil {
v.Spec.CSI.CreationTime = nil
}
gotMap[v.Name] = v gotMap[v.Name] = v
} }
if !reflect.DeepEqual(expectedMap, gotMap) { if !reflect.DeepEqual(expectedMap, gotMap) {
@@ -471,7 +456,7 @@ func (r *snapshotReactor) checkSnapshots(expectedSnapshots []*crdv1.VolumeSnapsh
c = c.DeepCopy() c = c.DeepCopy()
c.ResourceVersion = "" c.ResourceVersion = ""
if c.Status.Error != nil { if c.Status.Error != nil {
c.Status.Error.Time = metav1.Time{} c.Status.Error.Time = &metav1.Time{}
} }
expectedMap[c.Name] = c expectedMap[c.Name] = c
} }
@@ -481,7 +466,7 @@ func (r *snapshotReactor) checkSnapshots(expectedSnapshots []*crdv1.VolumeSnapsh
c = c.DeepCopy() c = c.DeepCopy()
c.ResourceVersion = "" c.ResourceVersion = ""
if c.Status.Error != nil { if c.Status.Error != nil {
c.Status.Error.Time = metav1.Time{} c.Status.Error.Time = &metav1.Time{}
} }
gotMap[c.Name] = c gotMap[c.Name] = c
} }
@@ -766,9 +751,9 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte
clientset, clientset,
kubeClient, kubeClient,
mockDriverName, mockDriverName,
informerFactory.Snapshot().V1alpha1().VolumeSnapshots(), informerFactory.Snapshot().V1beta1().VolumeSnapshots(),
informerFactory.Snapshot().V1alpha1().VolumeSnapshotContents(), informerFactory.Snapshot().V1beta1().VolumeSnapshotContents(),
informerFactory.Snapshot().V1alpha1().VolumeSnapshotClasses(), informerFactory.Snapshot().V1beta1().VolumeSnapshotClasses(),
coreFactory.Core().V1().PersistentVolumeClaims(), coreFactory.Core().V1().PersistentVolumeClaims(),
3, 3,
5*time.Millisecond, 5*time.Millisecond,
@@ -789,39 +774,46 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte
return ctrl, nil return ctrl, nil
} }
// newContent returns a new content with given attributes func newContent(contentName, boundToSnapshotUID, boundToSnapshotName, snapshotHandle, snapshotClassName, desiredSnapshotHandle, volumeHandle string,
func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64, withFinalizer bool, annotations map[string]string) *crdv1.VolumeSnapshotContent { deletionPolicy crdv1.DeletionPolicy, creationTime, size *int64,
withFinalizer bool) *crdv1.VolumeSnapshotContent {
content := crdv1.VolumeSnapshotContent{ content := crdv1.VolumeSnapshotContent{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: name, Name: contentName,
ResourceVersion: "1", ResourceVersion: "1",
Annotations: annotations,
}, },
Spec: crdv1.VolumeSnapshotContentSpec{ Spec: crdv1.VolumeSnapshotContentSpec{
VolumeSnapshotSource: crdv1.VolumeSnapshotSource{ Driver: mockDriverName,
CSI: &crdv1.CSIVolumeSnapshotSource{ DeletionPolicy: deletionPolicy,
RestoreSize: size, },
Driver: mockDriverName, Status: &crdv1.VolumeSnapshotContentStatus{
SnapshotHandle: snapshotHandle, CreationTime: creationTime,
CreationTime: creationTime, RestoreSize: size,
},
},
VolumeSnapshotClassName: &className,
DeletionPolicy: deletionPolicy,
}, },
} }
if volumeName != noVolume {
content.Spec.PersistentVolumeRef = &v1.ObjectReference{ if snapshotHandle != "" {
Kind: "PersistentVolume", content.Status.SnapshotHandle = &snapshotHandle
APIVersion: "v1", }
UID: types.UID(volumeUID),
Name: volumeName, if snapshotClassName != "" {
content.Spec.VolumeSnapshotClassName = &snapshotClassName
}
if volumeHandle != "" {
content.Spec.Source = crdv1.VolumeSnapshotContentSource{
VolumeHandle: &volumeHandle,
}
} else if desiredSnapshotHandle != "" {
content.Spec.Source = crdv1.VolumeSnapshotContentSource{
SnapshotHandle: &desiredSnapshotHandle,
} }
} }
if boundToSnapshotName != "" { if boundToSnapshotName != "" {
content.Spec.VolumeSnapshotRef = &v1.ObjectReference{ content.Spec.VolumeSnapshotRef = v1.ObjectReference{
Kind: "VolumeSnapshot", Kind: "VolumeSnapshot",
APIVersion: "snapshot.storage.k8s.io/v1alpha1", APIVersion: "snapshot.storage.k8s.io/v1beta1",
UID: types.UID(boundToSnapshotUID), UID: types.UID(boundToSnapshotUID),
Namespace: testNamespace, Namespace: testNamespace,
Name: boundToSnapshotName, Name: boundToSnapshotName,
@@ -834,53 +826,81 @@ func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToS
return &content return &content
} }
func newContentArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64, withFinalizer bool, annotations map[string]string) []*crdv1.VolumeSnapshotContent { func newContentArray(contentName, boundToSnapshotUID, boundToSnapshotName, snapshotHandle, snapshotClassName, desiredSnapshotHandle, volumeHandle string,
deletionPolicy crdv1.DeletionPolicy, size, creationTime *int64,
withFinalizer bool) []*crdv1.VolumeSnapshotContent {
return []*crdv1.VolumeSnapshotContent{ return []*crdv1.VolumeSnapshotContent{
newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, deletionPolicy, size, creationTime, withFinalizer, annotations), newContent(contentName, boundToSnapshotUID, boundToSnapshotName, snapshotHandle, snapshotClassName, desiredSnapshotHandle, volumeHandle, deletionPolicy, creationTime, size, withFinalizer),
} }
} }
func newContentWithUnmatchDriverArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent { func newContentArrayWithReadyToUse(contentName, boundToSnapshotUID, boundToSnapshotName, snapshotHandle, snapshotClassName, desiredSnapshotHandle, volumeHandle string,
content := newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, deletionPolicy, size, creationTime, false, nil) deletionPolicy crdv1.DeletionPolicy, creationTime, size *int64, readyToUse *bool,
content.Spec.VolumeSnapshotSource.CSI.Driver = "fake" withFinalizer bool) []*crdv1.VolumeSnapshotContent {
content := newContent(contentName, boundToSnapshotUID, boundToSnapshotName, snapshotHandle, snapshotClassName, desiredSnapshotHandle, volumeHandle, deletionPolicy, creationTime, size, withFinalizer)
content.Status.ReadyToUse = readyToUse
return []*crdv1.VolumeSnapshotContent{ return []*crdv1.VolumeSnapshotContent{
content, content,
} }
} }
func newSnapshot(name, className, boundToContent, snapshotUID, claimName string, ready bool, err *storagev1beta1.VolumeError, creationTime *metav1.Time, size *resource.Quantity) *crdv1.VolumeSnapshot { func newContentWithUnmatchDriverArray(contentName, boundToSnapshotUID, boundToSnapshotName, snapshotHandle, snapshotClassName, desiredSnapshotHandle, volumeHandle string,
deletionPolicy crdv1.DeletionPolicy, size, creationTime *int64,
withFinalizer bool) []*crdv1.VolumeSnapshotContent {
content := newContent(contentName, boundToSnapshotUID, boundToSnapshotName, snapshotHandle, snapshotClassName, desiredSnapshotHandle, volumeHandle, deletionPolicy, size, creationTime, withFinalizer)
content.Spec.Driver = "fake"
return []*crdv1.VolumeSnapshotContent{
content,
}
}
func newSnapshot(
snapshotName, snapshotUID, pvcName, targetContentName, snapshotClassName, boundContentName string,
readyToUse *bool, creationTime *metav1.Time, restoreSize *resource.Quantity,
err *crdv1.VolumeSnapshotError) *crdv1.VolumeSnapshot {
snapshot := crdv1.VolumeSnapshot{ snapshot := crdv1.VolumeSnapshot{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: name, Name: snapshotName,
Namespace: testNamespace, Namespace: testNamespace,
UID: types.UID(snapshotUID), UID: types.UID(snapshotUID),
ResourceVersion: "1", ResourceVersion: "1",
SelfLink: "/apis/snapshot.storage.k8s.io/v1alpha1/namespaces/" + testNamespace + "/volumesnapshots/" + name, SelfLink: "/apis/snapshot.storage.k8s.io/v1beta1/namespaces/" + testNamespace + "/volumesnapshots/" + snapshotName,
}, },
Spec: crdv1.VolumeSnapshotSpec{ Spec: crdv1.VolumeSnapshotSpec{
VolumeSnapshotClassName: &className, VolumeSnapshotClassName: nil,
SnapshotContentName: boundToContent,
}, },
Status: crdv1.VolumeSnapshotStatus{ Status: &crdv1.VolumeSnapshotStatus{
CreationTime: creationTime, CreationTime: creationTime,
ReadyToUse: ready, ReadyToUse: readyToUse,
Error: err, Error: err,
RestoreSize: size, RestoreSize: restoreSize,
}, },
} }
if claimName != noClaim {
snapshot.Spec.Source = &v1.TypedLocalObjectReference{
Name: claimName,
Kind: "PersistentVolumeClaim",
}
}
if boundContentName != "" {
snapshot.Status.BoundVolumeSnapshotContentName = &boundContentName
}
snapshot.Spec.VolumeSnapshotClassName = &snapshotClassName
if pvcName != "" {
snapshot.Spec.Source = crdv1.VolumeSnapshotSource{
PersistentVolumeClaimName: &pvcName,
}
} else if targetContentName != "" {
snapshot.Spec.Source = crdv1.VolumeSnapshotSource{
VolumeSnapshotContentName: &targetContentName,
}
}
return withSnapshotFinalizer(&snapshot) return withSnapshotFinalizer(&snapshot)
} }
func newSnapshotArray(name, className, boundToContent, snapshotUID, claimName string, ready bool, err *storagev1beta1.VolumeError, creationTime *metav1.Time, size *resource.Quantity) []*crdv1.VolumeSnapshot { func newSnapshotArray(
snapshotName, snapshotUID, pvcName, targetContentName, snapshotClassName, boundContentName string,
readyToUse *bool, creationTime *metav1.Time, restoreSize *resource.Quantity,
err *crdv1.VolumeSnapshotError) []*crdv1.VolumeSnapshot {
return []*crdv1.VolumeSnapshot{ return []*crdv1.VolumeSnapshot{
newSnapshot(name, className, boundToContent, snapshotUID, claimName, ready, err, creationTime, size), newSnapshot(snapshotName, snapshotUID, pvcName, targetContentName, snapshotClassName, boundContentName, readyToUse, creationTime, restoreSize, err),
} }
} }
@@ -940,15 +960,7 @@ func newClaimArrayFinalizer(name, claimUID, capacity, boundToVolume string, phas
} }
// newVolume returns a new volume with given attributes // newVolume returns a new volume with given attributes
func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string, driver string, namespace string, annotations ...string) *v1.PersistentVolume { func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string, annotations ...string) *v1.PersistentVolume {
inDriverName := mockDriverName
if driver != "" {
inDriverName = driver
}
inNamespace := testNamespace
if namespace != "" {
inNamespace = namespace
}
volume := v1.PersistentVolume{ volume := v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: name, Name: name,
@@ -962,7 +974,7 @@ func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundTo
}, },
PersistentVolumeSource: v1.PersistentVolumeSource{ PersistentVolumeSource: v1.PersistentVolumeSource{
CSI: &v1.CSIPersistentVolumeSource{ CSI: &v1.CSIPersistentVolumeSource{
Driver: inDriverName, Driver: mockDriverName,
VolumeHandle: volumeHandle, VolumeHandle: volumeHandle,
}, },
}, },
@@ -980,7 +992,7 @@ func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundTo
Kind: "PersistentVolumeClaim", Kind: "PersistentVolumeClaim",
APIVersion: "v1", APIVersion: "v1",
UID: types.UID(boundToClaimUID), UID: types.UID(boundToClaimUID),
Namespace: inNamespace, Namespace: testNamespace,
Name: boundToClaimName, Name: boundToClaimName,
} }
} }
@@ -990,16 +1002,16 @@ func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundTo
// newVolumeArray returns array with a single volume that would be returned by // newVolumeArray returns array with a single volume that would be returned by
// newVolume() with the same parameters. // newVolume() with the same parameters.
func newVolumeArray(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string, driver string, namespace string) []*v1.PersistentVolume { func newVolumeArray(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string) []*v1.PersistentVolume {
return []*v1.PersistentVolume{ return []*v1.PersistentVolume{
newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName, phase, reclaimPolicy, class, driver, namespace), newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName, phase, reclaimPolicy, class),
} }
} }
func newVolumeError(message string) *storagev1beta1.VolumeError { func newVolumeError(message string) *crdv1.VolumeSnapshotError {
return &storagev1beta1.VolumeError{ return &crdv1.VolumeSnapshotError{
Time: metav1.Time{}, Time: &metav1.Time{},
Message: message, Message: &message,
} }
} }
@@ -1392,7 +1404,6 @@ func (f *fakeSnapshotter) CreateSnapshot(ctx context.Context, snapshotName strin
if err != nil { if err != nil {
return "", "", time.Time{}, 0, false, fmt.Errorf("unexpected call") return "", "", time.Time{}, 0, false, fmt.Errorf("unexpected call")
} }
return call.driverName, call.snapshotId, call.creationTime, call.size, call.readyToUse, call.err return call.driverName, call.snapshotId, call.creationTime, call.size, call.readyToUse, call.err
} }
@@ -1410,10 +1421,10 @@ func (f *fakeSnapshotter) DeleteSnapshot(ctx context.Context, snapshotID string,
err = fmt.Errorf("unexpected Delete snapshot call") err = fmt.Errorf("unexpected Delete snapshot call")
} }
if !reflect.DeepEqual(call.secrets, snapshotterCredentials) { //if !reflect.DeepEqual(call.secrets, snapshotterCredentials) {
f.t.Errorf("Wrong CSI Delete Snapshot call: snapshotID=%s, expected secrets %+v, got %+v", snapshotID, call.secrets, snapshotterCredentials) // f.t.Errorf("Wrong CSI Delete Snapshot call: snapshotID=%s, expected secrets %+v, got %+v", snapshotID, call.secrets, snapshotterCredentials)
err = fmt.Errorf("unexpected Delete Snapshot call") // err = fmt.Errorf("unexpected Delete Snapshot call")
} //}
if err != nil { if err != nil {
return fmt.Errorf("unexpected call") return fmt.Errorf("unexpected call")

View File

@@ -21,10 +21,9 @@ import (
"strings" "strings"
"time" "time"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1" storagev1 "k8s.io/api/storage/v1"
storage "k8s.io/api/storage/v1beta1"
apierrs "k8s.io/apimachinery/pkg/api/errors" apierrs "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -46,7 +45,7 @@ import (
// //
// The fundamental key to this design is the bi-directional "pointer" between // The fundamental key to this design is the bi-directional "pointer" between
// VolumeSnapshots and VolumeSnapshotContents, which is represented here // VolumeSnapshots and VolumeSnapshotContents, which is represented here
// as snapshot.Spec.SnapshotContentName and content.Spec.VolumeSnapshotRef. // as snapshot.Spec.Source.VolumeSnapshotContentName and content.Spec.VolumeSnapshotRef.
// The bi-directionality is complicated to manage in a transactionless system, but // The bi-directionality is complicated to manage in a transactionless system, but
// without it we can't ensure sane behavior in the face of different forms of // without it we can't ensure sane behavior in the face of different forms of
// trouble. For example, a rogue HA controller instance could end up racing // trouble. For example, a rogue HA controller instance could end up racing
@@ -107,7 +106,7 @@ func (ctrl *csiSnapshotController) syncContent(content *crdv1.VolumeSnapshotCont
} }
// VolumeSnapshotContent is not bound to any VolumeSnapshot, in this case we just return err // VolumeSnapshotContent is not bound to any VolumeSnapshot, in this case we just return err
if content.Spec.VolumeSnapshotRef == nil { if content.Spec.VolumeSnapshotRef.Name == "" {
// content is not bound // content is not bound
klog.V(4).Infof("synchronizing VolumeSnapshotContent[%s]: VolumeSnapshotContent is not bound to any VolumeSnapshot", content.Name) klog.V(4).Infof("synchronizing VolumeSnapshotContent[%s]: VolumeSnapshotContent is not bound to any VolumeSnapshot", content.Name)
ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotContentNotBound", "VolumeSnapshotContent is not bound to any VolumeSnapshot") ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotContentNotBound", "VolumeSnapshotContent is not bound to any VolumeSnapshot")
@@ -146,23 +145,18 @@ func (ctrl *csiSnapshotController) syncContent(content *crdv1.VolumeSnapshotCont
snapshot = nil snapshot = nil
} }
if snapshot == nil { if snapshot == nil {
if content.Spec.DeletionPolicy != nil { switch content.Spec.DeletionPolicy {
switch *content.Spec.DeletionPolicy { case crdv1.VolumeSnapshotContentRetain:
case crdv1.VolumeSnapshotContentRetain: klog.V(4).Infof("VolumeSnapshotContent[%s]: policy is Retain, nothing to do", content.Name)
klog.V(4).Infof("VolumeSnapshotContent[%s]: policy is Retain, nothing to do", content.Name)
case crdv1.VolumeSnapshotContentDelete: case crdv1.VolumeSnapshotContentDelete:
klog.V(4).Infof("VolumeSnapshotContent[%s]: policy is Delete", content.Name) klog.V(4).Infof("VolumeSnapshotContent[%s]: policy is Delete", content.Name)
ctrl.deleteSnapshotContent(content) ctrl.deleteSnapshotContent(content)
default: default:
// Unknown VolumeSnapshotDeletionolicy // Unknown VolumeSnapshotDeletionolicy
ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotUnknownDeletionPolicy", "Volume Snapshot Content has unrecognized deletion policy") ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotUnknownDeletionPolicy", "Volume Snapshot Content has unrecognized deletion policy")
}
return nil
} }
// By default, we use Retain policy if it is not set by users return nil
klog.V(4).Infof("VolumeSnapshotContent[%s]: by default the policy is Retain", content.Name)
} }
return nil return nil
} }
@@ -201,7 +195,7 @@ func (ctrl *csiSnapshotController) syncSnapshot(snapshot *crdv1.VolumeSnapshot)
ctrl.eventRecorder.Event(snapshot, v1.EventTypeWarning, "ErrorSnapshotSourceFinalizer", "Error check and remove PVC Finalizer for VolumeSnapshot") ctrl.eventRecorder.Event(snapshot, v1.EventTypeWarning, "ErrorSnapshotSourceFinalizer", "Error check and remove PVC Finalizer for VolumeSnapshot")
} }
if !snapshot.Status.ReadyToUse { if !isSnapshotReadyToUse(snapshot) {
return ctrl.syncUnreadySnapshot(snapshot) return ctrl.syncUnreadySnapshot(snapshot)
} }
return ctrl.syncReadySnapshot(snapshot) return ctrl.syncReadySnapshot(snapshot)
@@ -210,13 +204,13 @@ func (ctrl *csiSnapshotController) syncSnapshot(snapshot *crdv1.VolumeSnapshot)
// 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.
// If there is any problem with the binding (e.g., snapshot points to a non-exist snapshot content), update the snapshot status and emit event. // If there is any problem with the binding (e.g., snapshot points to a non-exist snapshot content), update the snapshot status and emit event.
func (ctrl *csiSnapshotController) syncReadySnapshot(snapshot *crdv1.VolumeSnapshot) error { func (ctrl *csiSnapshotController) syncReadySnapshot(snapshot *crdv1.VolumeSnapshot) error {
if snapshot.Spec.SnapshotContentName == "" { if snapshot.Status.BoundVolumeSnapshotContentName == nil {
if err := ctrl.updateSnapshotErrorStatusWithEvent(snapshot, v1.EventTypeWarning, "SnapshotLost", "Bound snapshot has lost reference to VolumeSnapshotContent"); err != nil { if err := ctrl.updateSnapshotErrorStatusWithEvent(snapshot, v1.EventTypeWarning, "SnapshotLost", "Bound snapshot has lost reference to VolumeSnapshotContent"); err != nil {
return err return err
} }
return nil return nil
} }
obj, found, err := ctrl.contentStore.GetByKey(snapshot.Spec.SnapshotContentName) obj, found, err := ctrl.contentStore.GetByKey(*snapshot.Status.BoundVolumeSnapshotContentName)
if err != nil { if err != nil {
return err return err
} }
@@ -228,7 +222,7 @@ func (ctrl *csiSnapshotController) syncReadySnapshot(snapshot *crdv1.VolumeSnaps
} else { } else {
content, ok := obj.(*crdv1.VolumeSnapshotContent) content, ok := obj.(*crdv1.VolumeSnapshotContent)
if !ok { if !ok {
return fmt.Errorf("Cannot convert object from snapshot content store to VolumeSnapshotContent %q!?: %#v", snapshot.Spec.SnapshotContentName, obj) return fmt.Errorf("Cannot convert object from snapshot content store to VolumeSnapshotContent %q!?: %#v", *snapshot.Status.BoundVolumeSnapshotContentName, obj)
} }
klog.V(5).Infof("syncReadySnapshot[%s]: VolumeSnapshotContent %q found", snapshotKey(snapshot), content.Name) klog.V(5).Infof("syncReadySnapshot[%s]: VolumeSnapshotContent %q found", snapshotKey(snapshot), content.Name)
@@ -249,16 +243,16 @@ func (ctrl *csiSnapshotController) syncUnreadySnapshot(snapshot *crdv1.VolumeSna
uniqueSnapshotName := snapshotKey(snapshot) uniqueSnapshotName := snapshotKey(snapshot)
klog.V(5).Infof("syncUnreadySnapshot %s", uniqueSnapshotName) klog.V(5).Infof("syncUnreadySnapshot %s", uniqueSnapshotName)
if snapshot.Spec.SnapshotContentName != "" { if snapshot.Spec.Source.VolumeSnapshotContentName != nil {
contentObj, found, err := ctrl.contentStore.GetByKey(snapshot.Spec.SnapshotContentName) contentObj, found, err := ctrl.contentStore.GetByKey(*snapshot.Spec.Source.VolumeSnapshotContentName)
if err != nil { if err != nil {
return err return err
} }
if !found { if !found {
// snapshot is bound to a non-existing content. // snapshot is bound to a non-existing content.
ctrl.updateSnapshotErrorStatusWithEvent(snapshot, v1.EventTypeWarning, "SnapshotContentMissing", "VolumeSnapshotContent is missing") ctrl.updateSnapshotErrorStatusWithEvent(snapshot, v1.EventTypeWarning, "SnapshotContentMissing", "VolumeSnapshotContent is missing")
klog.V(4).Infof("synchronizing unready snapshot[%s]: snapshotcontent %q requested and not found, will try again next time", uniqueSnapshotName, snapshot.Spec.SnapshotContentName) klog.V(4).Infof("synchronizing unready snapshot[%s]: snapshotcontent %q requested and not found, will try again next time", uniqueSnapshotName, *snapshot.Spec.Source.VolumeSnapshotContentName)
return fmt.Errorf("snapshot %s is bound to a non-existing content %s", uniqueSnapshotName, snapshot.Spec.SnapshotContentName) return fmt.Errorf("snapshot %s is bound to a non-existing content %s", uniqueSnapshotName, *snapshot.Spec.Source.VolumeSnapshotContentName)
} }
content, ok := contentObj.(*crdv1.VolumeSnapshotContent) content, ok := contentObj.(*crdv1.VolumeSnapshotContent)
if !ok { if !ok {
@@ -276,21 +270,32 @@ func (ctrl *csiSnapshotController) syncUnreadySnapshot(snapshot *crdv1.VolumeSna
return err return err
} }
return nil return nil
} else { // snapshot.Spec.SnapshotContentName == nil } else { // snapshot.Source.Spec.VolumeSnapshotContentName == nil
// find a matching volume snapshot content
if contentObj := ctrl.getMatchSnapshotContent(snapshot); contentObj != nil { if contentObj := ctrl.getMatchSnapshotContent(snapshot); contentObj != nil {
klog.V(5).Infof("Find VolumeSnapshotContent object %s for snapshot %s", contentObj.Name, uniqueSnapshotName) klog.V(5).Infof("Find VolumeSnapshotContent object %s for snapshot %s", contentObj.Name, uniqueSnapshotName)
newSnapshot, err := ctrl.bindandUpdateVolumeSnapshot(contentObj, snapshot) if err := ctrl.checkandUpdateBoundSnapshotStatus(snapshot, contentObj); err != nil {
return err
}
klog.V(5).Infof("checkandUpdateBoundSnapshotStatus %v", snapshot)
} else if snapshot.Status != nil && snapshot.Status.BoundVolumeSnapshotContentName != nil {
contentObj, found, err := ctrl.contentStore.GetByKey(*snapshot.Status.BoundVolumeSnapshotContentName)
if err != nil { if err != nil {
return err return err
} }
klog.V(5).Infof("bindandUpdateVolumeSnapshot %v", newSnapshot) if !found {
return nil ctrl.updateSnapshotErrorStatusWithEvent(snapshot, v1.EventTypeWarning, "SnapshotContentMissing", "VolumeSnapshotContent is missing")
} else if snapshot.Status.Error == nil || isControllerUpdateFailError(snapshot.Status.Error) { // Try to create snapshot if no error status is set return fmt.Errorf("snapshot %s is bound to a non-existing content %s", uniqueSnapshotName, *snapshot.Status.BoundVolumeSnapshotContentName)
} else {
content, _ := contentObj.(*crdv1.VolumeSnapshotContent)
ctrl.updateSnapshotErrorStatusWithEvent(snapshot, v1.EventTypeWarning, "InvalidSnapshotBinding", fmt.Sprintf("Snapshot is bound to a VolumeSnapshotContent which is bound to other Snapshot"))
return fmt.Errorf("snapshot %s is bound, but VolumeSnapshotContent %s is not bound to the VolumeSnapshot correctly", uniqueSnapshotName, content.Name)
}
} else if snapshot.Status == nil || snapshot.Status.Error == nil || isControllerUpdateFailError(snapshot.Status.Error) {
if err := ctrl.createSnapshot(snapshot); err != nil { if err := ctrl.createSnapshot(snapshot); err != nil {
ctrl.updateSnapshotErrorStatusWithEvent(snapshot, v1.EventTypeWarning, "SnapshotCreationFailed", fmt.Sprintf("Failed to create snapshot with error %v", err)) ctrl.updateSnapshotErrorStatusWithEvent(snapshot, v1.EventTypeWarning, "SnapshotCreationFailed", fmt.Sprintf("Failed to create snapshot with error %v", err))
return err return err
} }
return nil
} }
return nil return nil
} }
@@ -304,12 +309,9 @@ func (ctrl *csiSnapshotController) getMatchSnapshotContent(snapshot *crdv1.Volum
objs := ctrl.contentStore.List() objs := ctrl.contentStore.List()
for _, obj := range objs { for _, obj := range objs {
content := obj.(*crdv1.VolumeSnapshotContent) content := obj.(*crdv1.VolumeSnapshotContent)
if content.Spec.VolumeSnapshotRef != nil && if content.Spec.VolumeSnapshotRef.Name == snapshot.Name &&
content.Spec.VolumeSnapshotRef.Name == snapshot.Name &&
content.Spec.VolumeSnapshotRef.Namespace == snapshot.Namespace && content.Spec.VolumeSnapshotRef.Namespace == snapshot.Namespace &&
content.Spec.VolumeSnapshotRef.UID == snapshot.UID && content.Spec.VolumeSnapshotRef.UID == snapshot.UID {
content.Spec.VolumeSnapshotClassName != nil && snapshot.Spec.VolumeSnapshotClassName != nil &&
*(content.Spec.VolumeSnapshotClassName) == *(snapshot.Spec.VolumeSnapshotClassName) {
found = true found = true
snapshotContentObj = content snapshotContentObj = content
break break
@@ -410,20 +412,24 @@ func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatus(snapshot *c
func (ctrl *csiSnapshotController) updateSnapshotErrorStatusWithEvent(snapshot *crdv1.VolumeSnapshot, eventtype, reason, message string) error { func (ctrl *csiSnapshotController) updateSnapshotErrorStatusWithEvent(snapshot *crdv1.VolumeSnapshot, eventtype, reason, message string) error {
klog.V(5).Infof("updateSnapshotStatusWithEvent[%s]", snapshotKey(snapshot)) klog.V(5).Infof("updateSnapshotStatusWithEvent[%s]", snapshotKey(snapshot))
if snapshot.Status.Error != nil && snapshot.Status.Error.Message == message { if snapshot.Status != nil && snapshot.Status.Error != nil && snapshot.Status.Error.Message != nil && *snapshot.Status.Error.Message == message {
klog.V(4).Infof("updateSnapshotStatusWithEvent[%s]: the same error %v is already set", snapshot.Name, snapshot.Status.Error) klog.V(4).Infof("updateSnapshotStatusWithEvent[%s]: the same error %v is already set", snapshot.Name, snapshot.Status.Error)
return nil return nil
} }
snapshotClone := snapshot.DeepCopy() snapshotClone := snapshot.DeepCopy()
statusError := &storage.VolumeError{ statusError := &crdv1.VolumeSnapshotError{
Time: metav1.Time{ Time: &metav1.Time{
Time: time.Now(), Time: time.Now(),
}, },
Message: message, Message: &message,
}
if snapshotClone.Status == nil {
snapshotClone.Status = &crdv1.VolumeSnapshotStatus{}
} }
snapshotClone.Status.Error = statusError snapshotClone.Status.Error = statusError
snapshotClone.Status.ReadyToUse = false ready := false
newSnapshot, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).UpdateStatus(snapshotClone) snapshotClone.Status.ReadyToUse = &ready
newSnapshot, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshots(snapshotClone.Namespace).UpdateStatus(snapshotClone)
if err != nil { if err != nil {
klog.V(4).Infof("updating VolumeSnapshot[%s] error status failed %v", snapshotKey(snapshot), err) klog.V(4).Infof("updating VolumeSnapshot[%s] error status failed %v", snapshotKey(snapshot), err)
@@ -443,12 +449,17 @@ func (ctrl *csiSnapshotController) updateSnapshotErrorStatusWithEvent(snapshot *
// Stateless functions // Stateless functions
func getSnapshotStatusForLogging(snapshot *crdv1.VolumeSnapshot) string { func getSnapshotStatusForLogging(snapshot *crdv1.VolumeSnapshot) string {
return fmt.Sprintf("bound to: %q, Completed: %v", snapshot.Spec.SnapshotContentName, snapshot.Status.ReadyToUse) snapshotContentName := ""
readyToUse := isSnapshotReadyToUse(snapshot)
if snapshot.Status != nil && snapshot.Status.BoundVolumeSnapshotContentName != nil {
snapshotContentName = *snapshot.Status.BoundVolumeSnapshotContentName
}
return fmt.Sprintf("bound to: %q, Completed: %v", snapshotContentName, readyToUse)
} }
// IsSnapshotBound returns true/false if snapshot is bound // IsSnapshotBound returns true/false if snapshot is bound
func IsSnapshotBound(snapshot *crdv1.VolumeSnapshot, content *crdv1.VolumeSnapshotContent) bool { func IsSnapshotBound(snapshot *crdv1.VolumeSnapshot, content *crdv1.VolumeSnapshotContent) bool {
if content.Spec.VolumeSnapshotRef != nil && content.Spec.VolumeSnapshotRef.Name == snapshot.Name && if content.Spec.VolumeSnapshotRef.Name == snapshot.Name &&
content.Spec.VolumeSnapshotRef.UID == snapshot.UID { content.Spec.VolumeSnapshotRef.UID == snapshot.UID {
return true return true
} }
@@ -457,18 +468,16 @@ 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 { snapshotObj, err := ctrl.clientset.SnapshotV1beta1().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 }
}
// Check if the snapshot content is bound to the snapshot // Check if the snapshot content is bound to the snapshot
if IsSnapshotBound(snapshotObj, content) && snapshotObj.Spec.SnapshotContentName == content.Name { if IsSnapshotBound(snapshotObj, content) && snapshotObj.Status != nil && *snapshotObj.Status.BoundVolumeSnapshotContentName == content.Name {
klog.Infof("isSnapshotContentBeingUsed: VolumeSnapshot %s is bound to volumeSnapshotContent [%s]", snapshotObj.Name, content.Name) klog.Infof("isSnapshotContentBeingUsed: VolumeSnapshot %s is bound to volumeSnapshotContent [%s]", snapshotObj.Name, content.Name)
return true return true
}
} }
klog.V(5).Infof("isSnapshotContentBeingUsed: Snapshot content %s is not being used", content.Name) klog.V(5).Infof("isSnapshotContentBeingUsed: Snapshot content %s is not being used", content.Name)
@@ -499,18 +508,16 @@ func (ctrl *csiSnapshotController) isVolumeBeingCreatedFromSnapshot(snapshot *cr
// The function checks whether the volumeSnapshotRef in snapshot content matches the given snapshot. If match, it binds the content with the snapshot // The function checks whether the volumeSnapshotRef in snapshot content matches the given snapshot. If match, it binds the content with the snapshot
func (ctrl *csiSnapshotController) checkandBindSnapshotContent(snapshot *crdv1.VolumeSnapshot, content *crdv1.VolumeSnapshotContent) (*crdv1.VolumeSnapshotContent, error) { func (ctrl *csiSnapshotController) checkandBindSnapshotContent(snapshot *crdv1.VolumeSnapshot, content *crdv1.VolumeSnapshotContent) (*crdv1.VolumeSnapshotContent, error) {
if content.Spec.VolumeSnapshotRef == nil || content.Spec.VolumeSnapshotRef.Name != snapshot.Name { if content.Spec.VolumeSnapshotRef.Name != snapshot.Name {
return nil, fmt.Errorf("Could not bind snapshot %s and content %s, the VolumeSnapshotRef does not match", snapshot.Name, content.Name) return nil, fmt.Errorf("Could not bind snapshot %s and content %s, the VolumeSnapshotRef does not match", snapshot.Name, content.Name)
} else if content.Spec.VolumeSnapshotRef.UID != "" && content.Spec.VolumeSnapshotRef.UID != snapshot.UID { } else if content.Spec.VolumeSnapshotRef.UID != "" && content.Spec.VolumeSnapshotRef.UID != snapshot.UID {
return nil, fmt.Errorf("Could not bind snapshot %s and content %s, the VolumeSnapshotRef does not match", snapshot.Name, content.Name) return nil, fmt.Errorf("Could not bind snapshot %s and content %s, the VolumeSnapshotRef does not match", snapshot.Name, content.Name)
} else if content.Spec.VolumeSnapshotRef.UID != "" && content.Spec.VolumeSnapshotClassName != nil { } else if content.Spec.VolumeSnapshotRef.UID != "" {
return content, nil return content, nil
} }
contentClone := content.DeepCopy() contentClone := content.DeepCopy()
contentClone.Spec.VolumeSnapshotRef.UID = snapshot.UID contentClone.Spec.VolumeSnapshotRef.UID = snapshot.UID
className := *(snapshot.Spec.VolumeSnapshotClassName) newContent, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Update(contentClone)
contentClone.Spec.VolumeSnapshotClassName = &className
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
@@ -525,7 +532,6 @@ func (ctrl *csiSnapshotController) checkandBindSnapshotContent(snapshot *crdv1.V
func (ctrl *csiSnapshotController) getCreateSnapshotInput(snapshot *crdv1.VolumeSnapshot) (*crdv1.VolumeSnapshotClass, *v1.PersistentVolume, string, *v1.SecretReference, error) { func (ctrl *csiSnapshotController) getCreateSnapshotInput(snapshot *crdv1.VolumeSnapshot) (*crdv1.VolumeSnapshotClass, *v1.PersistentVolume, string, *v1.SecretReference, error) {
className := snapshot.Spec.VolumeSnapshotClassName className := snapshot.Spec.VolumeSnapshotClassName
klog.V(5).Infof("getCreateSnapshotInput [%s]: VolumeSnapshotClassName [%s]", snapshot.Name, *className)
var class *crdv1.VolumeSnapshotClass var class *crdv1.VolumeSnapshotClass
var err error var err error
if className != nil { if className != nil {
@@ -565,16 +571,14 @@ func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(sn
var driverName string var driverName string
var snapshotID string var snapshotID string
if snapshot.Spec.Source == nil { if snapshot.Spec.Source.VolumeSnapshotContentName != 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, creationTime, 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
} }
if content.Spec.CSI != nil { driverName, snapshotID = content.Spec.Driver, *content.Status.SnapshotHandle
driverName, snapshotID = content.Spec.CSI.Driver, content.Spec.CSI.SnapshotHandle
}
} else { } else {
class, volume, _, snapshotterSecretRef, err := ctrl.getCreateSnapshotInput(snapshot) class, volume, _, snapshotterSecretRef, err := ctrl.getCreateSnapshotInput(snapshot)
if err != nil { if err != nil {
@@ -595,11 +599,18 @@ func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(sn
if creationTime.IsZero() { if creationTime.IsZero() {
creationTime = time.Now() creationTime = time.Now()
} }
newSnapshot, err := ctrl.updateSnapshotStatus(snapshot, readyToUse, creationTime, size, IsSnapshotBound(snapshot, content)) newSnapshot, err := ctrl.updateSnapshotStatus(snapshot, content.Name, readyToUse, creationTime, size)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = ctrl.updateSnapshotContentSize(content, size) // get the latest version of snapshot content before update status
latestContent, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Get(content.Name, metav1.GetOptions{})
err = ctrl.updateSnapshotContentStatus(latestContent, snapshotID, readyToUse, creationTime.UnixNano(), size)
if err != nil {
return nil, err
}
// store latest content
_, err = ctrl.storeContentUpdate(latestContent)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -614,8 +625,8 @@ func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(sn
func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.VolumeSnapshot) (*crdv1.VolumeSnapshot, error) { func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.VolumeSnapshot) (*crdv1.VolumeSnapshot, error) {
klog.Infof("createSnapshot: Creating snapshot %s through the plugin ...", snapshotKey(snapshot)) klog.Infof("createSnapshot: Creating snapshot %s through the plugin ...", snapshotKey(snapshot))
if snapshot.Status.Error != nil && !isControllerUpdateFailError(snapshot.Status.Error) { if snapshot.Status != nil && snapshot.Status.Error != nil && snapshot.Status.Error.Message != nil && !isControllerUpdateFailError(snapshot.Status.Error) {
klog.V(4).Infof("error is already set in snapshot, do not retry to create: %s", snapshot.Status.Error.Message) klog.V(4).Infof("error is already set in snapshot, do not retry to create: %s", *snapshot.Status.Error.Message)
return snapshot, nil return snapshot, nil
} }
@@ -648,7 +659,7 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
// Update snapshot status with creationTime // 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, creationTime, size, false) newSnapshot, err = ctrl.updateSnapshotStatus(snapshot, contentName, readyToUse, creationTime, size)
if err == nil { if err == nil {
break break
} }
@@ -659,37 +670,24 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
return nil, err return nil, err
} }
// Create VolumeSnapshotContent in the database // Create VolumeSnapshotContent in the database
volumeRef, err := ref.GetReference(scheme.Scheme, volume)
if err != nil {
return nil, err
}
snapshotRef, err := ref.GetReference(scheme.Scheme, snapshot) snapshotRef, err := ref.GetReference(scheme.Scheme, snapshot)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if class.DeletionPolicy == nil {
class.DeletionPolicy = new(crdv1.DeletionPolicy)
*class.DeletionPolicy = crdv1.VolumeSnapshotContentDelete
}
timestamp := creationTime.UnixNano() timestamp := creationTime.UnixNano()
snapshotContent := &crdv1.VolumeSnapshotContent{ snapshotContent := &crdv1.VolumeSnapshotContent{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: contentName, Name: contentName,
}, },
Spec: crdv1.VolumeSnapshotContentSpec{ Spec: crdv1.VolumeSnapshotContentSpec{
VolumeSnapshotRef: snapshotRef, VolumeSnapshotRef: *snapshotRef,
PersistentVolumeRef: volumeRef,
VolumeSnapshotSource: crdv1.VolumeSnapshotSource{
CSI: &crdv1.CSIVolumeSnapshotSource{
Driver: driverName,
SnapshotHandle: snapshotID,
CreationTime: &timestamp,
RestoreSize: &size,
},
},
VolumeSnapshotClassName: &(class.Name),
DeletionPolicy: class.DeletionPolicy, DeletionPolicy: class.DeletionPolicy,
Driver: driverName,
VolumeSnapshotClassName: &class.Name,
Source: crdv1.VolumeSnapshotContentSource{
VolumeHandle: &volume.Spec.CSI.VolumeHandle,
},
}, },
} }
@@ -706,14 +704,18 @@ 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.SnapshotV1alpha1().VolumeSnapshotContents().Create(snapshotContent); err == nil || apierrs.IsAlreadyExists(err) { if _, err = ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Create(snapshotContent); err == nil || apierrs.IsAlreadyExists(err) {
// Save succeeded. // creation 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))
err = nil err = nil
} else { } else {
klog.V(3).Infof("volume snapshot content %q for snapshot %q saved, %v", snapshotContent.Name, snapshotKey(snapshot), snapshotContent) klog.V(3).Infof("volume snapshot content %q for snapshot %q saved, %v", snapshotContent.Name, snapshotKey(snapshot), snapshotContent)
} }
newContent, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Get(snapshotContent.Name, metav1.GetOptions{})
if err == nil {
err = ctrl.updateSnapshotContentStatus(newContent, snapshotID, readyToUse, timestamp, size)
}
break break
} }
// Save failed, try again after a while. // Save failed, try again after a while.
@@ -730,13 +732,7 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
ctrl.eventRecorder.Event(newSnapshot, v1.EventTypeWarning, "CreateSnapshotContentFailed", strerr) ctrl.eventRecorder.Event(newSnapshot, v1.EventTypeWarning, "CreateSnapshotContentFailed", strerr)
return nil, newControllerUpdateError(snapshotKey(snapshot), err.Error()) return nil, newControllerUpdateError(snapshotKey(snapshot), err.Error())
} }
return newSnapshot, nil
// save succeeded, bind and update status for snapshot.
result, err := ctrl.bindandUpdateVolumeSnapshot(snapshotContent, newSnapshot)
if err != nil {
return nil, err
}
return result, nil
} }
// Delete a snapshot // Delete a snapshot
@@ -751,36 +747,30 @@ func (ctrl *csiSnapshotController) deleteSnapshotContentOperation(content *crdv1
// get secrets if VolumeSnapshotClass specifies it // get secrets if VolumeSnapshotClass specifies it
var snapshotterCredentials map[string]string var snapshotterCredentials map[string]string
var err error /* TODO(@Xing-yang): secrete ref retrivial needs to be implemented here
snapshotClassName := content.Spec.VolumeSnapshotClassName
if snapshotClassName != nil {
if snapshotClass, err := ctrl.classLister.Get(*snapshotClassName); err == nil {
// Resolve snapshotting secret credentials.
// No VolumeSnapshot is provided when resolving delete secret names, since the VolumeSnapshot may or may not exist at delete time.
snapshotterSecretRef, err := getSecretReference(snapshotClass.Parameters, content.Name, nil)
if err != nil {
return err
}
snapshotterCredentials, err = getCredentials(ctrl.client, snapshotterSecretRef)
if err != nil {
return err
}
}
}*/
// Check if annotation exists err := ctrl.handler.DeleteSnapshot(content, snapshotterCredentials)
if metav1.HasAnnotation(content.ObjectMeta, AnnDeletionSecretRefName) && metav1.HasAnnotation(content.ObjectMeta, AnnDeletionSecretRefNamespace) {
annDeletionSecretName := content.Annotations[AnnDeletionSecretRefName]
annDeletionSecretNamespace := content.Annotations[AnnDeletionSecretRefNamespace]
snapshotterSecretRef := &v1.SecretReference{}
if annDeletionSecretName == "" || annDeletionSecretNamespace == "" {
return fmt.Errorf("cannot delete snapshot %#v, err: secret name or namespace not specified", content.Name)
}
snapshotterSecretRef.Name = annDeletionSecretName
snapshotterSecretRef.Namespace = annDeletionSecretNamespace
snapshotterCredentials, err = getCredentials(ctrl.client, snapshotterSecretRef)
if err != nil {
// Continue with deletion, as the secret may have already been deleted.
klog.Errorf("Failed to get credentials for snapshot %s: %s", content.Name, err.Error())
}
}
err = ctrl.handler.DeleteSnapshot(content, snapshotterCredentials)
if err != nil { if err != nil {
ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotDeleteError", "Failed to delete snapshot") ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotDeleteError", "Failed to delete snapshot")
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.SnapshotV1alpha1().VolumeSnapshotContents().Delete(content.Name, &metav1.DeleteOptions{}) err = ctrl.clientset.SnapshotV1beta1().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)
@@ -789,93 +779,108 @@ func (ctrl *csiSnapshotController) deleteSnapshotContentOperation(content *crdv1
return nil return nil
} }
func (ctrl *csiSnapshotController) bindandUpdateVolumeSnapshot(snapshotContent *crdv1.VolumeSnapshotContent, snapshot *crdv1.VolumeSnapshot) (*crdv1.VolumeSnapshot, error) { // TODO(xiangqian) This is a temp implementation to make sure the test cases pass
klog.V(5).Infof("bindandUpdateVolumeSnapshot for snapshot [%s]: snapshotContent [%s]", snapshot.Name, snapshotContent.Name) // updateSnapshotContentStatus updates status of a content object
snapshotObj, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshot.Namespace).Get(snapshot.Name, metav1.GetOptions{}) func (ctrl *csiSnapshotController) updateSnapshotContentStatus(
if err != nil { content *crdv1.VolumeSnapshotContent,
return nil, fmt.Errorf("error get snapshot %s from api server: %v", snapshotKey(snapshot), err) snapshotHandle string,
} readyToUse bool,
createdAt int64,
// Copy the snapshot object before updating it size int64) error {
snapshotCopy := snapshotObj.DeepCopy() var newStatus *crdv1.VolumeSnapshotContentStatus
updated := false
if snapshotObj.Spec.SnapshotContentName == snapshotContent.Name { if content.Status == nil {
klog.Infof("bindVolumeSnapshotContentToVolumeSnapshot: VolumeSnapshot %s already bind to volumeSnapshotContent [%s]", snapshot.Name, snapshotContent.Name) newStatus = &crdv1.VolumeSnapshotContentStatus{
SnapshotHandle: &snapshotHandle,
ReadyToUse: &readyToUse,
CreationTime: &createdAt,
RestoreSize: &size,
}
updated = true
} else { } else {
klog.Infof("bindVolumeSnapshotContentToVolumeSnapshot: before bind VolumeSnapshot %s to volumeSnapshotContent [%s]", snapshot.Name, snapshotContent.Name) newStatus = content.Status.DeepCopy()
snapshotCopy.Spec.SnapshotContentName = snapshotContent.Name if newStatus.SnapshotHandle == nil {
updateSnapshot, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshot.Namespace).Update(snapshotCopy) newStatus.SnapshotHandle = &snapshotHandle
if err != nil { updated = true
klog.Infof("bindVolumeSnapshotContentToVolumeSnapshot: Error binding VolumeSnapshot %s to volumeSnapshotContent [%s]. Error [%#v]", snapshot.Name, snapshotContent.Name, err)
return nil, newControllerUpdateError(snapshotKey(snapshot), err.Error())
} }
snapshotCopy = updateSnapshot if newStatus.ReadyToUse == nil || *newStatus.ReadyToUse != readyToUse {
_, err = ctrl.storeSnapshotUpdate(snapshotCopy) newStatus.ReadyToUse = &readyToUse
if err != nil { updated = true
klog.Errorf("%v", err) if readyToUse && newStatus.Error != nil {
newStatus.Error = nil
}
}
if newStatus.CreationTime == nil {
newStatus.CreationTime = &createdAt
updated = true
}
if newStatus.RestoreSize == nil {
newStatus.RestoreSize = &size
updated = true
} }
} }
klog.V(5).Infof("bindandUpdateVolumeSnapshot for snapshot completed [%#v]", snapshotCopy) if updated {
return snapshotCopy, nil contentClone := content.DeepCopy()
} contentClone.Status = newStatus
_, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().UpdateStatus(contentClone)
// updateSnapshotContentSize update the restore size for snapshot content if err != nil {
func (ctrl *csiSnapshotController) updateSnapshotContentSize(content *crdv1.VolumeSnapshotContent, size int64) error { return newControllerUpdateError(content.Name, err.Error())
if content.Spec.VolumeSnapshotSource.CSI == nil || size <= 0 { }
return nil
}
if content.Spec.VolumeSnapshotSource.CSI.RestoreSize != nil && *content.Spec.VolumeSnapshotSource.CSI.RestoreSize == size {
return nil
}
contentClone := content.DeepCopy()
contentClone.Spec.VolumeSnapshotSource.CSI.RestoreSize = &size
_, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone)
if err != nil {
return newControllerUpdateError(content.Name, err.Error())
}
_, err = ctrl.storeContentUpdate(contentClone)
if err != nil {
klog.Errorf("failed to update content store %v", err)
} }
return nil return nil
} }
// UpdateSnapshotStatus converts snapshot status to crdv1.VolumeSnapshotCondition // UpdateSnapshotStatus converts snapshot status to crdv1.VolumeSnapshotCondition
func (ctrl *csiSnapshotController) updateSnapshotStatus(snapshot *crdv1.VolumeSnapshot, readyToUse bool, createdAt time.Time, size int64, bound bool) (*crdv1.VolumeSnapshot, error) { func (ctrl *csiSnapshotController) updateSnapshotStatus(
snapshot *crdv1.VolumeSnapshot,
boundContentName string,
readyToUse bool,
createdAt time.Time,
size int64) (*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
change := false
timeAt := &metav1.Time{
Time: createdAt,
}
snapshotClone := snapshot.DeepCopy() var newStatus *crdv1.VolumeSnapshotStatus
if readyToUse { updated := false
if bound { if snapshot.Status == nil {
status.ReadyToUse = true newStatus = &crdv1.VolumeSnapshotStatus{
// Remove the error if checking snapshot is already bound and ready BoundVolumeSnapshotContentName: &boundContentName,
status.Error = nil CreationTime: &metav1.Time{Time: createdAt},
change = true ReadyToUse: &readyToUse,
RestoreSize: resource.NewQuantity(size, resource.BinarySI),
}
updated = true
} else {
newStatus = snapshot.Status.DeepCopy()
if newStatus.BoundVolumeSnapshotContentName == nil {
newStatus.BoundVolumeSnapshotContentName = &boundContentName
updated = true
}
if newStatus.CreationTime == nil {
newStatus.CreationTime = &metav1.Time{Time: createdAt}
updated = true
}
if newStatus.ReadyToUse == nil || *newStatus.ReadyToUse != readyToUse {
newStatus.ReadyToUse = &readyToUse
updated = true
if readyToUse && newStatus.Error != nil {
newStatus.Error = nil
}
}
if newStatus.RestoreSize == nil {
newStatus.RestoreSize = resource.NewQuantity(size, resource.BinarySI)
updated = true
} }
} }
if status.CreationTime == nil {
status.CreationTime = timeAt
change = true
}
if change { if updated {
if size > 0 { snapshotClone := snapshot.DeepCopy()
status.RestoreSize = resource.NewQuantity(size, resource.BinarySI) snapshotClone.Status = newStatus
} newSnapshotObj, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshots(snapshotClone.Namespace).UpdateStatus(snapshotClone)
snapshotClone.Status = status
newSnapshotObj, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).UpdateStatus(snapshotClone)
if err != nil { if err != nil {
return nil, newControllerUpdateError(snapshotKey(snapshot), err.Error()) return nil, newControllerUpdateError(snapshotKey(snapshot), err.Error())
} }
return newSnapshotObj, nil return newSnapshotObj, nil
} }
return snapshot, nil return snapshot, nil
} }
@@ -897,40 +902,11 @@ func (ctrl *csiSnapshotController) getVolumeFromVolumeSnapshot(snapshot *crdv1.V
return nil, fmt.Errorf("failed to retrieve PV %s from the API server: %q", pvName, err) return nil, fmt.Errorf("failed to retrieve PV %s from the API server: %q", pvName, err)
} }
// Verify binding between PV/PVC is still valid
bound := ctrl.IsVolumeBoundToClaim(pv, pvc)
if bound == false {
klog.Warningf("binding between PV %s and PVC %s is broken", pvName, pvc.Name)
return nil, fmt.Errorf("claim in dataSource not bound or invalid")
}
// Verify driver for PVC is the same as driver for VolumeSnapshot
if pv.Spec.PersistentVolumeSource.CSI == nil || pv.Spec.PersistentVolumeSource.CSI.Driver != ctrl.snapshotterName {
klog.Warningf("driver for PV %s is different from driver %s for snapshot %s", pvName, ctrl.snapshotterName, snapshot.Name)
return nil, fmt.Errorf("claim in dataSource not bound or invalid")
}
klog.V(5).Infof("getVolumeFromVolumeSnapshot: snapshot [%s] PV name [%s]", snapshot.Name, pvName) klog.V(5).Infof("getVolumeFromVolumeSnapshot: snapshot [%s] PV name [%s]", snapshot.Name, pvName)
return pv, nil return pv, nil
} }
// IsVolumeBoundToClaim returns true, if given volume is pre-bound or bound
// to specific claim. Both claim.Name and claim.Namespace must be equal.
// If claim.UID is present in volume.Spec.ClaimRef, it must be equal too.
func (ctrl *csiSnapshotController) IsVolumeBoundToClaim(volume *v1.PersistentVolume, claim *v1.PersistentVolumeClaim) bool {
if volume.Spec.ClaimRef == nil {
return false
}
if claim.Name != volume.Spec.ClaimRef.Name || claim.Namespace != volume.Spec.ClaimRef.Namespace {
return false
}
if volume.Spec.ClaimRef.UID != "" && claim.UID != volume.Spec.ClaimRef.UID {
return false
}
return true
}
func (ctrl *csiSnapshotController) getStorageClassFromVolumeSnapshot(snapshot *crdv1.VolumeSnapshot) (*storagev1.StorageClass, error) { func (ctrl *csiSnapshotController) getStorageClassFromVolumeSnapshot(snapshot *crdv1.VolumeSnapshot) (*storagev1.StorageClass, error) {
// Get storage class from PVC or PV // Get storage class from PVC or PV
pvc, err := ctrl.getClaimFromVolumeSnapshot(snapshot) pvc, err := ctrl.getClaimFromVolumeSnapshot(snapshot)
@@ -985,7 +961,7 @@ func (ctrl *csiSnapshotController) SetDefaultSnapshotClass(snapshot *crdv1.Volum
defaultClasses := []*crdv1.VolumeSnapshotClass{} defaultClasses := []*crdv1.VolumeSnapshotClass{}
for _, class := range list { for _, class := range list {
if IsDefaultAnnotation(class.ObjectMeta) && storageclass.Provisioner == class.Snapshotter && ctrl.snapshotterName == class.Snapshotter { if IsDefaultAnnotation(class.ObjectMeta) && storageclass.Provisioner == class.Driver && ctrl.driverName == class.Driver {
defaultClasses = append(defaultClasses, class) defaultClasses = append(defaultClasses, class)
klog.V(5).Infof("get defaultClass added: %s", class.Name) klog.V(5).Infof("get defaultClass added: %s", class.Name)
} }
@@ -1000,7 +976,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.SnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone) newSnapshot, err := ctrl.clientset.SnapshotV1beta1().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)
} }
@@ -1015,19 +991,13 @@ func (ctrl *csiSnapshotController) SetDefaultSnapshotClass(snapshot *crdv1.Volum
// getClaimFromVolumeSnapshot is a helper function to get PVC from VolumeSnapshot. // getClaimFromVolumeSnapshot is a helper function to get PVC from VolumeSnapshot.
func (ctrl *csiSnapshotController) getClaimFromVolumeSnapshot(snapshot *crdv1.VolumeSnapshot) (*v1.PersistentVolumeClaim, error) { func (ctrl *csiSnapshotController) getClaimFromVolumeSnapshot(snapshot *crdv1.VolumeSnapshot) (*v1.PersistentVolumeClaim, error) {
if snapshot.Spec.Source == nil { if snapshot.Spec.Source.PersistentVolumeClaimName == nil {
return nil, fmt.Errorf("the snapshot source is not specified") return nil, fmt.Errorf("the snapshot source is not the right type. Expected PersistentVolumeClaimName to be valid")
} }
if snapshot.Spec.Source.Kind != pvcKind { pvcName := *snapshot.Spec.Source.PersistentVolumeClaimName
return nil, fmt.Errorf("the snapshot source is not the right type. Expected %s, Got %v", pvcKind, snapshot.Spec.Source.Kind)
}
pvcName := snapshot.Spec.Source.Name
if pvcName == "" { if pvcName == "" {
return nil, fmt.Errorf("the PVC name is not specified in snapshot %s", snapshotKey(snapshot)) return nil, fmt.Errorf("the PVC name is not specified in snapshot %s", snapshotKey(snapshot))
} }
if snapshot.Spec.Source.APIGroup != nil && *(snapshot.Spec.Source.APIGroup) != apiGroup {
return nil, fmt.Errorf("the snapshot source does not have the right APIGroup. Expected empty string, Got %s", *(snapshot.Spec.Source.APIGroup))
}
pvc, err := ctrl.pvcLister.PersistentVolumeClaims(snapshot.Namespace).Get(pvcName) pvc, err := ctrl.pvcLister.PersistentVolumeClaims(snapshot.Namespace).Get(pvcName)
if err != nil { if err != nil {
@@ -1053,9 +1023,9 @@ func (e controllerUpdateError) Error() string {
return e.message return e.message
} }
func isControllerUpdateFailError(err *storage.VolumeError) bool { func isControllerUpdateFailError(err *crdv1.VolumeSnapshotError) bool {
if err != nil { if err != nil && err.Message != nil {
if strings.Contains(err.Message, controllerUpdateFailMsg) { if strings.Contains(*err.Message, controllerUpdateFailMsg) {
return true return true
} }
} }
@@ -1067,7 +1037,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.SnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone) _, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Update(contentClone)
if err != nil { if err != nil {
return newControllerUpdateError(content.Name, err.Error()) return newControllerUpdateError(content.Name, err.Error())
} }
@@ -1086,7 +1056,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.SnapshotV1alpha1().VolumeSnapshotContents().Update(contentClone) _, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshotContents().Update(contentClone)
if err != nil { if err != nil {
return newControllerUpdateError(content.Name, err.Error()) return newControllerUpdateError(content.Name, err.Error())
} }
@@ -1104,7 +1074,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.SnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone) _, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone)
if err != nil { if err != nil {
return newControllerUpdateError(snapshot.Name, err.Error()) return newControllerUpdateError(snapshot.Name, err.Error())
} }
@@ -1123,7 +1093,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.SnapshotV1alpha1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone) _, err := ctrl.clientset.SnapshotV1beta1().VolumeSnapshots(snapshotClone.Namespace).Update(snapshotClone)
if err != nil { if err != nil {
return newControllerUpdateError(snapshot.Name, err.Error()) return newControllerUpdateError(snapshot.Name, err.Error())
} }
@@ -1203,11 +1173,11 @@ func (ctrl *csiSnapshotController) isSnapshotSourceBeingUsed(snapshot *crdv1.Vol
} }
for _, snap := range snapshots { for _, snap := range snapshots {
// Skip static bound snapshot without a PVC source // Skip static bound snapshot without a PVC source
if snap.Spec.Source == nil { if snap.Spec.Source.PersistentVolumeClaimName == nil {
klog.V(4).Infof("Skipping static bound snapshot %s when checking PVC %s/%s", snap.Name, pvc.Namespace, pvc.Name) klog.V(4).Infof("Skipping static bound snapshot %s when checking PVC %s/%s", snap.Name, pvc.Namespace, pvc.Name)
continue continue
} }
if pvc.Name == snap.Spec.Source.Name && snap.Status.ReadyToUse == false { if pvc.Name == *snap.Spec.Source.PersistentVolumeClaimName && !isSnapshotReadyToUse(snap) {
klog.V(2).Infof("Keeping PVC %s/%s, it is used by snapshot %s/%s", pvc.Namespace, pvc.Name, snap.Namespace, snap.Name) 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 return true
} }
@@ -1246,3 +1216,11 @@ func (ctrl *csiSnapshotController) checkandRemoveSnapshotSourceFinalizer(snapsho
return nil return nil
} }
// isSnapshotReadyToUse checks if a snapshot object has ReadyToUse in Status set to true
func isSnapshotReadyToUse(snapshot *crdv1.VolumeSnapshot) bool {
if snapshot.Status == nil || snapshot.Status.ReadyToUse == nil {
return false
}
return *snapshot.Status.ReadyToUse
}

View File

@@ -20,13 +20,13 @@ import (
"fmt" "fmt"
"time" "time"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned" clientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
storageinformers "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/volumesnapshot/v1alpha1" storageinformers "github.com/kubernetes-csi/external-snapshotter/pkg/client/informers/externalversions/volumesnapshot/v1beta1"
storagelisters "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1alpha1" storagelisters "github.com/kubernetes-csi/external-snapshotter/pkg/client/listers/volumesnapshot/v1beta1"
"github.com/kubernetes-csi/external-snapshotter/pkg/snapshotter" "github.com/kubernetes-csi/external-snapshotter/pkg/snapshotter"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
@@ -43,12 +43,12 @@ import (
) )
type csiSnapshotController struct { type csiSnapshotController struct {
clientset clientset.Interface clientset clientset.Interface
client kubernetes.Interface client kubernetes.Interface
snapshotterName string driverName string
eventRecorder record.EventRecorder eventRecorder record.EventRecorder
snapshotQueue workqueue.RateLimitingInterface snapshotQueue workqueue.RateLimitingInterface
contentQueue workqueue.RateLimitingInterface contentQueue workqueue.RateLimitingInterface
snapshotLister storagelisters.VolumeSnapshotLister snapshotLister storagelisters.VolumeSnapshotLister
snapshotListerSynced cache.InformerSynced snapshotListerSynced cache.InformerSynced
@@ -75,7 +75,7 @@ type csiSnapshotController struct {
func NewCSISnapshotController( func NewCSISnapshotController(
clientset clientset.Interface, clientset clientset.Interface,
client kubernetes.Interface, client kubernetes.Interface,
snapshotterName string, driverName string,
volumeSnapshotInformer storageinformers.VolumeSnapshotInformer, volumeSnapshotInformer storageinformers.VolumeSnapshotInformer,
volumeSnapshotContentInformer storageinformers.VolumeSnapshotContentInformer, volumeSnapshotContentInformer storageinformers.VolumeSnapshotContentInformer,
volumeSnapshotClassInformer storageinformers.VolumeSnapshotClassInformer, volumeSnapshotClassInformer storageinformers.VolumeSnapshotClassInformer,
@@ -92,12 +92,12 @@ func NewCSISnapshotController(
broadcaster.StartLogging(klog.Infof) broadcaster.StartLogging(klog.Infof)
broadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: client.CoreV1().Events(v1.NamespaceAll)}) broadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: client.CoreV1().Events(v1.NamespaceAll)})
var eventRecorder record.EventRecorder var eventRecorder record.EventRecorder
eventRecorder = broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: fmt.Sprintf("csi-snapshotter %s", snapshotterName)}) eventRecorder = broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: fmt.Sprintf("csi-snapshotter %s", driverName)})
ctrl := &csiSnapshotController{ ctrl := &csiSnapshotController{
clientset: clientset, clientset: clientset,
client: client, client: client,
snapshotterName: snapshotterName, driverName: driverName,
eventRecorder: eventRecorder, eventRecorder: eventRecorder,
handler: NewCSIHandler(snapshotter, timeout, snapshotNamePrefix, snapshotNameUUIDLength), handler: NewCSIHandler(snapshotter, timeout, snapshotNamePrefix, snapshotNameUUIDLength),
runningOperations: goroutinemap.NewGoRoutineMap(true), runningOperations: goroutinemap.NewGoRoutineMap(true),
@@ -325,23 +325,7 @@ func (ctrl *csiSnapshotController) contentWorker() {
// verify whether the driver specified in VolumeSnapshotContent matches the controller's driver name // verify whether the driver specified in VolumeSnapshotContent matches the controller's driver name
func (ctrl *csiSnapshotController) isDriverMatch(content *crdv1.VolumeSnapshotContent) bool { func (ctrl *csiSnapshotController) isDriverMatch(content *crdv1.VolumeSnapshotContent) bool {
if content.Spec.VolumeSnapshotSource.CSI == nil { return content.Spec.Driver == ctrl.driverName
// Skip this snapshot content if it not a CSI snapshot
return false
}
if content.Spec.VolumeSnapshotSource.CSI.Driver != ctrl.snapshotterName {
// Skip this snapshot content if the driver does not match
return false
}
snapshotClassName := content.Spec.VolumeSnapshotClassName
if snapshotClassName != nil {
if snapshotClass, err := ctrl.classLister.Get(*snapshotClassName); err == nil {
if snapshotClass.Snapshotter != ctrl.snapshotterName {
return false
}
}
}
return true
} }
// checkAndUpdateSnapshotClass gets the VolumeSnapshotClass from VolumeSnapshot. If it is not set, // checkAndUpdateSnapshotClass gets the VolumeSnapshotClass from VolumeSnapshot. If it is not set,
@@ -370,9 +354,9 @@ func (ctrl *csiSnapshotController) checkAndUpdateSnapshotClass(snapshot *crdv1.V
} }
} }
klog.V(5).Infof("VolumeSnapshotClass Snapshotter [%s] Snapshot Controller snapshotterName [%s]", class.Snapshotter, ctrl.snapshotterName) klog.V(5).Infof("VolumeSnapshotClass Driver [%s] Snapshot Controller driverName [%s]", class.Driver, ctrl.driverName)
if class.Snapshotter != ctrl.snapshotterName { if class.Driver != ctrl.driverName {
klog.V(4).Infof("Skipping VolumeSnapshot %s for snapshotter [%s] in VolumeSnapshotClass because it does not match with the snapshotter for controller [%s]", snapshotKey(snapshot), class.Snapshotter, ctrl.snapshotterName) klog.V(4).Infof("Skipping VolumeSnapshot %s for snapshotter [%s] in VolumeSnapshotClass because it does not match with the snapshotter for controller [%s]", snapshotKey(snapshot), class.Driver, ctrl.driverName)
return nil, fmt.Errorf("volumeSnapshotClass does not match with the snapshotter for controller") return nil, fmt.Errorf("volumeSnapshotClass does not match with the snapshotter for controller")
} }
return newSnapshot, nil return newSnapshot, nil
@@ -432,11 +416,11 @@ func (ctrl *csiSnapshotController) deleteSnapshot(snapshot *crdv1.VolumeSnapshot
_ = ctrl.snapshotStore.Delete(snapshot) _ = ctrl.snapshotStore.Delete(snapshot)
klog.V(4).Infof("snapshot %q deleted", snapshotKey(snapshot)) klog.V(4).Infof("snapshot %q deleted", snapshotKey(snapshot))
snapshotContentName := snapshot.Spec.SnapshotContentName if snapshot.Status.BoundVolumeSnapshotContentName == nil {
if snapshotContentName == "" {
klog.V(5).Infof("deleteSnapshot[%q]: content not bound", snapshotKey(snapshot)) klog.V(5).Infof("deleteSnapshot[%q]: content not bound", snapshotKey(snapshot))
return return
} }
snapshotContentName := *snapshot.Status.BoundVolumeSnapshotContentName
// sync the content when its snapshot is deleted. Explicitly sync'ing the // sync the content when its snapshot is deleted. Explicitly sync'ing the
// content here in response to snapshot deletion prevents the content from // content here in response to snapshot deletion prevents the content from
// waiting until the next sync period for its Release. // waiting until the next sync period for its Release.

View File

@@ -17,13 +17,16 @@ limitations under the License.
package controller package controller
import ( import (
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1"
"k8s.io/client-go/tools/cache"
"testing" "testing"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"k8s.io/client-go/tools/cache"
) )
var deletionPolicy = crdv1.VolumeSnapshotContentDelete
func storeVersion(t *testing.T, prefix string, c cache.Store, version string, expectedReturn bool) { func storeVersion(t *testing.T, prefix string, c cache.Store, version string, expectedReturn bool) {
content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil, false, nil) content := newContent("contentName", "snapuid1-1", "snap1-1", "sid1-1", classGold, "", "pv-handle-1-1", deletionPolicy, nil, nil, false)
content.ResourceVersion = version content.ResourceVersion = version
ret, err := storeObjectUpdate(c, content, "content") ret, err := storeObjectUpdate(c, content, "content")
if err != nil { if err != nil {
@@ -81,8 +84,7 @@ func TestControllerCacheParsingError(t *testing.T) {
c := cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc) c := cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc)
// There must be something in the cache to compare with // There must be something in the cache to compare with
storeVersion(t, "Step1", c, "1", true) storeVersion(t, "Step1", c, "1", true)
content := newContent("contentName", "snapuid1-1", "snap1-1", "sid1-1", classGold, "", "pv-handle-1-1", deletionPolicy, nil, nil, false)
content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil, false, nil)
content.ResourceVersion = "xxx" content.ResourceVersion = "xxx"
_, err := storeObjectUpdate(c, content, "content") _, err := storeObjectUpdate(c, content, "content")
if err == nil { if err == nil {

View File

@@ -21,14 +21,16 @@ import (
"testing" "testing"
"time" "time"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
var timeNow = time.Now() var timeNow = time.Now()
var timeNowStamp = timeNow.UnixNano() var timeNowStamp = timeNow.UnixNano()
var False = false
var True = true
var metaTimeNowUnix = &metav1.Time{ var metaTimeNowUnix = &metav1.Time{
Time: timeNow, Time: timeNow,
@@ -69,22 +71,22 @@ 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, &timeNowStamp, false, nil), expectedContents: newContentArrayWithReadyToUse("snapcontent-snapuid6-1", "snapuid6-1", "snap6-1", "sid6-1", classGold, "", "pv-handle6-1", deletionPolicy, &timeNowStamp, &defaultSize, &True, false),
initialSnapshots: newSnapshotArray("snap6-1", classGold, "", "snapuid6-1", "claim6-1", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-1", "snapuid6-1", "claim6-1", "", classGold, "", &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", "snapuid6-1", "claim6-1", "", classGold, "snapcontent-snapuid6-1", &True, metaTimeNowUnix, getSize(defaultSize), nil),
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),
initialVolumes: newVolumeArray("volume6-1", "pv-uid6-1", "pv-handle6-1", "1Gi", "pvc-uid6-1", "claim6-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume6-1", "pv-uid6-1", "pv-handle6-1", "1Gi", "pvc-uid6-1", "claim6-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid6-1", snapshotName: "snapshot-snapuid6-1",
volume: newVolume("volume6-1", "pv-uid6-1", "pv-handle6-1", "1Gi", "pvc-uid6-1", "claim6-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), 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",
creationTime: timeNow, creationTime: timeNow,
readyToUse: true, readyToUse: True,
}, },
}, },
errors: noerrors, errors: noerrors,
@@ -93,74 +95,22 @@ 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, &timeNowStamp, false, nil), expectedContents: newContentArrayWithReadyToUse("snapcontent-snapuid6-2", "snapuid6-2", "snap6-2", "sid6-2", classSilver, "", "pv-handle6-2", deletionPolicy, &timeNowStamp, &defaultSize, &True, false),
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &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", "snapuid6-2", "claim6-2", "", classSilver, "snapcontent-snapuid6-2", &True, metaTimeNowUnix, getSize(defaultSize), nil),
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),
initialVolumes: newVolumeArray("volume6-2", "pv-uid6-2", "pv-handle6-2", "1Gi", "pvc-uid6-2", "claim6-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume6-2", "pv-uid6-2", "pv-handle6-2", "1Gi", "pvc-uid6-2", "claim6-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid6-2", snapshotName: "snapshot-snapuid6-2",
volume: newVolume("volume6-2", "pv-uid6-2", "pv-handle6-2", "1Gi", "pvc-uid6-2", "claim6-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), 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",
creationTime: timeNow, creationTime: timeNow,
readyToUse: true, readyToUse: True,
},
},
errors: noerrors,
test: testSyncSnapshot,
},
{
name: "6-3 - successful create snapshot with snapshot class valid-secret-class",
initialContents: nocontents,
expectedContents: newContentArray("snapcontent-snapuid6-3", validSecretClass, "sid6-3", "pv-uid6-3", "volume6-3", "snapuid6-3", "snap6-3", &deletePolicy, &defaultSize, &timeNowStamp, false, secretAnnotations()),
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)),
initialClaims: newClaimArray("claim6-3", "pvc-uid6-3", "1Gi", "volume6-3", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume6-3", "pv-uid6-3", "pv-handle6-3", "1Gi", "pvc-uid6-3", "claim6-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace),
initialSecrets: []*v1.Secret{secret()},
expectedCreateCalls: []createCall{
{
snapshotName: "snapshot-snapuid6-3",
volume: newVolume("volume6-3", "pv-uid6-3", "pv-handle6-3", "1Gi", "pvc-uid6-3", "claim6-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace),
parameters: class5Parameters,
secrets: map[string]string{"foo": "bar"},
// information to return
driverName: mockDriverName,
size: defaultSize,
snapshotId: "sid6-3",
creationTime: timeNow,
readyToUse: true,
},
},
errors: noerrors,
test: testSyncSnapshot,
},
{
name: "6-4 - successful create snapshot with snapshot class empty-secret-class",
initialContents: nocontents,
expectedContents: newContentArray("snapcontent-snapuid6-4", emptySecretClass, "sid6-4", "pv-uid6-4", "volume6-4", "snapuid6-4", "snap6-4", &deletePolicy, &defaultSize, &timeNowStamp, false, emptyDataSecretAnnotations()),
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)),
initialClaims: newClaimArray("claim6-4", "pvc-uid6-4", "1Gi", "volume6-4", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume6-4", "pv-uid6-4", "pv-handle6-4", "1Gi", "pvc-uid6-4", "claim6-4", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace),
initialSecrets: []*v1.Secret{emptySecret()},
expectedCreateCalls: []createCall{
{
snapshotName: "snapshot-snapuid6-4",
volume: newVolume("volume6-4", "pv-uid6-4", "pv-handle6-4", "1Gi", "pvc-uid6-4", "claim6-4", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace),
parameters: class4Parameters,
secrets: map[string]string{},
// information to return
driverName: mockDriverName,
size: defaultSize,
snapshotId: "sid6-4",
creationTime: timeNow,
readyToUse: true,
}, },
}, },
errors: noerrors, errors: noerrors,
@@ -169,83 +119,84 @@ 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, &timeNowStamp, false, nil), expectedContents: newContentArrayWithReadyToUse("snapcontent-snapuid6-5", "snapuid6-5", "snap6-5", "sid6-5", classGold, "", "pv-handle6-5", deletionPolicy, &timeNowStamp, &defaultSize, &False, false),
initialSnapshots: newSnapshotArray("snap6-5", classGold, "", "snapuid6-5", "claim6-5", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-5", "snapuid6-5", "claim6-5", "", classGold, "", &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", "snapuid6-5", "claim6-5", "", classGold, "snapcontent-snapuid6-5", &False, metaTimeNowUnix, getSize(defaultSize), nil),
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),
initialVolumes: newVolumeArray("volume6-5", "pv-uid6-5", "pv-handle6-5", "1Gi", "pvc-uid6-5", "claim6-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume6-5", "pv-uid6-5", "pv-handle6-5", "1Gi", "pvc-uid6-5", "claim6-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid6-5", snapshotName: "snapshot-snapuid6-5",
volume: newVolume("volume6-5", "pv-uid6-5", "pv-handle6-5", "1Gi", "pvc-uid6-5", "claim6-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), 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",
creationTime: timeNow, creationTime: timeNow,
readyToUse: true, readyToUse: False,
}, },
}, },
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
// TODO(xiangqian): this test does not match its name
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, &timeNowStamp, false, nil), expectedContents: newContentArrayWithReadyToUse("snapcontent-snapuid6-6", "snapuid6-6", "snap6-6", "sid6-6", classGold, "", "pv-handle6-6", deletionPolicy, &timeNowStamp, &defaultSize, &False, false),
initialSnapshots: newSnapshotArray("snap6-6", classGold, "", "snapuid6-6", "claim6-6", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-6", "snapuid6-6", "claim6-6", "", classGold, "", &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", "snapuid6-6", "claim6-6", "", classGold, "snapcontent-snapuid6-6", &False, metaTimeNowUnix, getSize(defaultSize), nil),
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),
initialVolumes: newVolumeArray("volume6-6", "pv-uid6-6", "pv-handle6-6", "1Gi", "pvc-uid6-6", "claim6-6", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume6-6", "pv-uid6-6", "pv-handle6-6", "1Gi", "pvc-uid6-6", "claim6-6", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid6-6", snapshotName: "snapshot-snapuid6-6",
volume: newVolume("volume6-6", "pv-uid6-6", "pv-handle6-6", "1Gi", "pvc-uid6-6", "claim6-6", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), 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",
creationTime: timeNow, creationTime: timeNow,
readyToUse: true, readyToUse: False,
}, },
}, },
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "7-1 - fail create snapshot with snapshot class non-existing", name: "7-1 - fail to create snapshot with non-existing snapshot class",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-1", classNonExisting, "", "snapuid7-1", "claim7-1", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-1", "snapuid7-1", "claim7-1", "", classNonExisting, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-1", classNonExisting, "", "snapuid7-1", "claim7-1", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-1: \"failed to retrieve snapshot class non-existing from the informer: \\\"volumesnapshotclass.snapshot.storage.k8s.io \\\\\\\"non-existing\\\\\\\" not found\\\"\""), nil, nil), expectedSnapshots: newSnapshotArray("snap7-1", "snapuid7-1", "claim7-1", "", classNonExisting, "", &False, nil, nil, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-1: \"failed to retrieve snapshot class non-existing from the informer: \\\"volumesnapshotclass.snapshot.storage.k8s.io \\\\\\\"non-existing\\\\\\\" not found\\\"\"")),
initialClaims: newClaimArray("claim7-1", "pvc-uid7-1", "1Gi", "volume7-1", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim7-1", "pvc-uid7-1", "1Gi", "volume7-1", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume7-1", "pv-uid7-1", "pv-handle7-1", "1Gi", "pvc-uid7-1", "claim7-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume7-1", "pv-uid7-1", "pv-handle7-1", "1Gi", "pvc-uid7-1", "claim7-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedEvents: []string{"Warning SnapshotCreationFailed"}, expectedEvents: []string{"Warning SnapshotCreationFailed"},
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "7-2 - fail create snapshot with snapshot class invalid-secret-class", name: "7-2 - fail to create snapshot with snapshot class invalid-secret-class",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-2", invalidSecretClass, "", "snapuid7-2", "claim7-2", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-2", "snapuid7-2", "claim7-2", "", invalidSecretClass, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-2", invalidSecretClass, "", "snapuid7-2", "claim7-2", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-2: \"failed to get name and namespace template from params: either name and namespace for Snapshotter secrets specified, Both must be specified\""), nil, nil), expectedSnapshots: newSnapshotArray("snap7-2", "snapuid7-2", "claim7-2", "", invalidSecretClass, "", &False, nil, nil, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-2: \"failed to get name and namespace template from params: either name and namespace for Snapshotter secrets specified, Both must be specified\"")),
initialClaims: newClaimArray("claim7-2", "pvc-uid7-2", "1Gi", "volume7-2", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim7-2", "pvc-uid7-2", "1Gi", "volume7-2", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume7-2", "pv-uid7-2", "pv-handle7-2", "1Gi", "pvc-uid7-2", "claim7-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume7-2", "pv-uid7-2", "pv-handle7-2", "1Gi", "pvc-uid7-2", "claim7-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedEvents: []string{"Warning SnapshotCreationFailed"}, expectedEvents: []string{"Warning SnapshotCreationFailed"},
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "7-3 - fail create snapshot with none snapshot class ", name: "7-3 - fail to create snapshot without snapshot class ",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-3", "", "", "snapuid7-3", "claim7-3", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-3", "snapuid7-3", "claim7-3", "", "", "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-3", "", "", "snapuid7-3", "claim7-3", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-3: \"failed to retrieve snapshot class from the informer: \\\"volumesnapshotclass.snapshot.storage.k8s.io \\\\\\\"\\\\\\\" not found\\\"\""), nil, nil), expectedSnapshots: newSnapshotArray("snap7-3", "snapuid7-3", "claim7-3", "", "", "", &False, nil, nil, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-3: \"failed to retrieve snapshot class from the informer: \\\"volumesnapshotclass.snapshot.storage.k8s.io \\\\\\\"\\\\\\\" not found\\\"\"")),
initialClaims: newClaimArray("claim7-3", "pvc-uid7-3", "1Gi", "volume7-3", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim7-3", "pvc-uid7-3", "1Gi", "volume7-3", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume7-3", "pv-uid7-3", "pv-handle7-3", "1Gi", "pvc-uid7-3", "claim7-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume7-3", "pv-uid7-3", "pv-handle7-3", "1Gi", "pvc-uid7-3", "claim7-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
initialStorageClasses: []*storage.StorageClass{diffDriverStorageClass}, initialStorageClasses: []*storage.StorageClass{diffDriverStorageClass},
expectedEvents: []string{"Warning SnapshotCreationFailed"}, expectedEvents: []string{"Warning SnapshotCreationFailed"},
errors: noerrors, errors: noerrors,
@@ -255,9 +206,9 @@ func TestCreateSnapshotSync(t *testing.T) {
name: "7-4 - fail create snapshot with no-existing claim", name: "7-4 - fail create snapshot with no-existing claim",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-4", classGold, "", "snapuid7-4", "claim7-4", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-4", "snapuid7-4", "claim7-4", "", classGold, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-4", classGold, "", "snapuid7-4", "claim7-4", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-4: \"failed to retrieve PVC claim7-4 from the lister: \\\"persistentvolumeclaim \\\\\\\"claim7-4\\\\\\\" not found\\\"\""), nil, nil), expectedSnapshots: newSnapshotArray("snap7-4", "snapuid7-4", "claim7-4", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-4: \"failed to retrieve PVC claim7-4 from the lister: \\\"persistentvolumeclaim \\\\\\\"claim7-4\\\\\\\" not found\\\"\"")),
initialVolumes: newVolumeArray("volume7-4", "pv-uid7-4", "pv-handle7-4", "1Gi", "pvc-uid7-4", "claim7-4", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume7-4", "pv-uid7-4", "pv-handle7-4", "1Gi", "pvc-uid7-4", "claim7-4", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedEvents: []string{"Warning SnapshotCreationFailed"}, expectedEvents: []string{"Warning SnapshotCreationFailed"},
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
@@ -266,8 +217,8 @@ func TestCreateSnapshotSync(t *testing.T) {
name: "7-5 - fail create snapshot with no-existing volume", name: "7-5 - fail create snapshot with no-existing volume",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-5", classGold, "", "snapuid7-5", "claim7-5", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-5", "snapuid7-5", "claim7-5", "", classGold, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-5", classGold, "", "snapuid7-5", "claim7-5", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-5: \"failed to retrieve PV volume7-5 from the API server: \\\"cannot find volume volume7-5\\\"\""), nil, nil), expectedSnapshots: newSnapshotArray("snap7-5", "snapuid7-5", "claim7-5", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-5: \"failed to retrieve PV volume7-5 from the API server: \\\"cannot find volume volume7-5\\\"\"")),
initialClaims: newClaimArray("claim7-5", "pvc-uid7-5", "1Gi", "volume7-5", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim7-5", "pvc-uid7-5", "1Gi", "volume7-5", v1.ClaimBound, &classEmpty),
expectedEvents: []string{"Warning SnapshotCreationFailed"}, expectedEvents: []string{"Warning SnapshotCreationFailed"},
errors: noerrors, errors: noerrors,
@@ -277,8 +228,8 @@ func TestCreateSnapshotSync(t *testing.T) {
name: "7-6 - fail create snapshot with claim that is not yet bound", name: "7-6 - fail create snapshot with claim that is not yet bound",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-6", classGold, "", "snapuid7-6", "claim7-6", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-6", "snapuid7-6", "claim7-6", "", classGold, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-6", classGold, "", "snapuid7-6", "claim7-6", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-6: \"the PVC claim7-6 is not yet bound to a PV, will not attempt to take a snapshot\""), nil, nil), expectedSnapshots: newSnapshotArray("snap7-6", "snapuid7-6", "claim7-6", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-6: \"the PVC claim7-6 is not yet bound to a PV, will not attempt to take a snapshot\"")),
initialClaims: newClaimArray("claim7-6", "pvc-uid7-6", "1Gi", "", v1.ClaimPending, &classEmpty), initialClaims: newClaimArray("claim7-6", "pvc-uid7-6", "1Gi", "", v1.ClaimPending, &classEmpty),
expectedEvents: []string{"Warning SnapshotCreationFailed"}, expectedEvents: []string{"Warning SnapshotCreationFailed"},
errors: noerrors, errors: noerrors,
@@ -288,14 +239,14 @@ func TestCreateSnapshotSync(t *testing.T) {
name: "7-7 - fail create snapshot due to csi driver error", name: "7-7 - fail create snapshot due to csi driver error",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-7", classGold, "", "snapuid7-7", "claim7-7", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-7", "snapuid7-7", "claim7-7", "", classGold, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-7", classGold, "", "snapuid7-7", "claim7-7", false, newVolumeError("Failed to create snapshot: failed to take snapshot of the volume, volume7-7: \"mock create snapshot error\""), nil, nil), expectedSnapshots: newSnapshotArray("snap7-7", "snapuid7-7", "claim7-7", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot: failed to take snapshot of the volume, volume7-7: \"mock create snapshot error\"")),
initialClaims: newClaimArray("claim7-7", "pvc-uid7-7", "1Gi", "volume7-7", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim7-7", "pvc-uid7-7", "1Gi", "volume7-7", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume7-7", "pv-uid7-7", "pv-handle7-7", "1Gi", "pvc-uid7-7", "claim7-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume7-7", "pv-uid7-7", "pv-handle7-7", "1Gi", "pvc-uid7-7", "claim7-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid7-7", snapshotName: "snapshot-snapuid7-7",
volume: newVolume("volume7-7", "pv-uid7-7", "pv-handle7-7", "1Gi", "pvc-uid7-7", "claim7-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), volume: newVolume("volume7-7", "pv-uid7-7", "pv-handle7-7", "1Gi", "pvc-uid7-7", "claim7-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
parameters: map[string]string{"param1": "value1"}, parameters: map[string]string{"param1": "value1"},
// information to return // information to return
err: errors.New("mock create snapshot error"), err: errors.New("mock create snapshot error"),
@@ -309,25 +260,25 @@ func TestCreateSnapshotSync(t *testing.T) {
name: "7-8 - fail create snapshot due to cannot update snapshot status", name: "7-8 - fail create snapshot due to cannot update snapshot status",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-8", classGold, "", "snapuid7-8", "claim7-8", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-8", "snapuid7-8", "claim7-8", "", classGold, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-8", classGold, "", "snapuid7-8", "claim7-8", false, newVolumeError("Failed to create snapshot: snapshot controller failed to update default/snap7-8 on API server: mock update error"), nil, nil), expectedSnapshots: newSnapshotArray("snap7-8", "snapuid7-8", "claim7-8", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot: snapshot controller failed to update default/snap7-8 on API server: mock update error")),
initialClaims: newClaimArray("claim7-8", "pvc-uid7-8", "1Gi", "volume7-8", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim7-8", "pvc-uid7-8", "1Gi", "volume7-8", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid7-8", snapshotName: "snapshot-snapuid7-8",
volume: newVolume("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), 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",
creationTime: timeNow, creationTime: timeNow,
readyToUse: true, readyToUse: True,
}, },
}, },
errors: []reactorError{ errors: []reactorError{
// Inject error to the forth client.VolumesnapshotV1alpha1().VolumeSnapshots().Update call. // Inject error to the forth client.VolumesnapshotV1beta1().VolumeSnapshots().Update call.
// All other calls will succeed. // All other calls will succeed.
{"update", "volumesnapshots", errors.New("mock update error")}, {"update", "volumesnapshots", errors.New("mock update error")},
{"update", "volumesnapshots", errors.New("mock update error")}, {"update", "volumesnapshots", errors.New("mock update error")},
@@ -337,24 +288,27 @@ func TestCreateSnapshotSync(t *testing.T) {
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
// TODO(xiangqian): this test case needs to be revisited the scenario
// of VolumeSnapshotContent saving failure. Since there will be no content object
// in API server, it could potentially cause leaking issue
name: "7-9 - fail create snapshot due to cannot save snapshot content", name: "7-9 - fail create snapshot due to cannot save snapshot content",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-9", classGold, "", "snapuid7-9", "claim7-9", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-9", "snapuid7-9", "claim7-9", "", classGold, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-9", classGold, "", "snapuid7-9", "claim7-9", false, nil, metaTimeNowUnix, getSize(defaultSize)), expectedSnapshots: newSnapshotArray("snap7-9", "snapuid7-9", "claim7-9", "", classGold, "snapcontent-snapuid7-9", &True, metaTimeNowUnix, getSize(defaultSize), nil),
initialClaims: newClaimArray("claim7-9", "pvc-uid7-9", "1Gi", "volume7-9", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim7-9", "pvc-uid7-9", "1Gi", "volume7-9", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid7-9", snapshotName: "snapshot-snapuid7-9",
volume: newVolume("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), 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",
creationTime: timeNow, creationTime: timeNow,
readyToUse: true, readyToUse: True,
}, },
}, },
errors: []reactorError{ errors: []reactorError{
@@ -369,74 +323,14 @@ func TestCreateSnapshotSync(t *testing.T) {
name: "7-10 - fail create snapshot with secret not found", name: "7-10 - fail create snapshot with secret not found",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap7-10", validSecretClass, "", "snapuid7-10", "claim7-10", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap7-10", "snapuid7-10", "claim7-10", "", validSecretClass, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap7-10", validSecretClass, "", "snapuid7-10", "claim7-10", false, newVolumeError("Failed to create snapshot: error getting secret secret in namespace default: cannot find secret secret"), nil, nil), expectedSnapshots: newSnapshotArray("snap7-10", "snapuid7-10", "claim7-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("Failed to create snapshot: error getting secret secret in namespace default: cannot find secret secret")),
initialClaims: newClaimArray("claim7-10", "pvc-uid7-10", "1Gi", "volume7-10", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim7-10", "pvc-uid7-10", "1Gi", "volume7-10", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume7-10", "pv-uid7-10", "pv-handle7-10", "1Gi", "pvc-uid7-10", "claim7-10", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume7-10", "pv-uid7-10", "pv-handle7-10", "1Gi", "pvc-uid7-10", "claim7-10", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
initialSecrets: []*v1.Secret{}, // no initial secret created initialSecrets: []*v1.Secret{}, // no initial secret created
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{
name: "8-1 - fail create snapshot with PVC using unbound PV",
initialContents: nocontents,
expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap8-1", classGold, "", "snapuid8-1", "claim8-1", false, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap8-1", classGold, "", "snapuid8-1", "claim8-1", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap8-1: \"claim in dataSource not bound or invalid\""), nil, nil),
initialClaims: newClaimArray("claim8-1", "pvc-uid8-1", "1Gi", "volume8-1", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume8-1", "pv-uid8-1", "pv-handle8-1", "1Gi", "pvc-uid8-1", "", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace),
errors: noerrors,
expectedEvents: []string{"Warning SnapshotCreationFailed"},
test: testSyncSnapshot,
},
{
name: "8-2 - fail create snapshot with PVC using PV bound to another PVC (with wrong UID)",
initialContents: nocontents,
expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap8-2", classGold, "", "snapuid8-2", "claim8-2", false, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap8-2", classGold, "", "snapuid8-2", "claim8-2", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap8-2: \"claim in dataSource not bound or invalid\""), nil, nil),
initialClaims: newClaimArray("claim8-2", "pvc-uid8-2", "1Gi", "volume8-2", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume8-2", "pv-uid8-2", "pv-handle8-2", "1Gi", "pvc-uid8-2-wrong-UID", "claim8-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace),
errors: noerrors,
expectedEvents: []string{"Warning SnapshotCreationFailed"},
test: testSyncSnapshot,
},
{
name: "8-3 - fail create snapshot with PVC using PV bound to another PVC (with wrong namespace)",
initialContents: nocontents,
expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap8-3", classGold, "", "snapuid8-3", "claim8-3", false, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap8-3", classGold, "", "snapuid8-3", "claim8-3", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap8-3: \"claim in dataSource not bound or invalid\""), nil, nil),
initialClaims: newClaimArray("claim8-3", "pvc-uid8-3", "1Gi", "volume8-3", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume8-3", "pv-uid8-3", "pv-handle8-3", "1Gi", "pvc-uid8-3", "claim8-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, "wrong-namespace"),
errors: noerrors,
expectedEvents: []string{"Warning SnapshotCreationFailed"},
test: testSyncSnapshot,
},
{
name: "8-4 - fail create snapshot with PVC using PV bound to another PVC (with wrong name)",
initialContents: nocontents,
expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap8-4", classGold, "", "snapuid8-4", "claim8-4", false, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap8-4", classGold, "", "snapuid8-4", "claim8-4", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap8-4: \"claim in dataSource not bound or invalid\""), nil, nil),
initialClaims: newClaimArray("claim8-4", "pvc-uid8-4", "1Gi", "volume8-4", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume8-4", "pv-uid8-4", "pv-handle8-4", "1Gi", "pvc-uid8-4", "claim8-4-wrong-name", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace),
errors: noerrors,
expectedEvents: []string{"Warning SnapshotCreationFailed"},
test: testSyncSnapshot,
},
{
name: "8-5 - fail create snapshot with PVC bound to PV with wrong provisioner",
initialContents: nocontents,
expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap8-5", classGold, "", "snapuid8-5", "claim8-5", false, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap8-5", classGold, "", "snapuid8-5", "claim8-5", false, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap8-5: \"claim in dataSource not bound or invalid\""), nil, nil),
initialClaims: newClaimArray("claim8-5", "pvc-uid8-5", "1Gi", "volume8-5", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume8-5", "pv-uid8-5", "pv-handle8-5", "1Gi", "pvc-uid8-5", "claim8-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, "wrong-driver", testNamespace),
errors: noerrors,
expectedEvents: []string{"Warning SnapshotCreationFailed"},
test: testSyncSnapshot,
},
} }
runSyncTests(t, tests, snapshotClasses) runSyncTests(t, tests, snapshotClasses)
} }

View File

@@ -20,8 +20,8 @@ import (
"errors" "errors"
"testing" "testing"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
@@ -56,8 +56,9 @@ var snapshotClasses = []*crdv1.VolumeSnapshotClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: classGold, Name: classGold,
}, },
Snapshotter: mockDriverName, Driver: mockDriverName,
Parameters: class1Parameters, Parameters: class1Parameters,
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
@@ -66,8 +67,9 @@ var snapshotClasses = []*crdv1.VolumeSnapshotClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: classSilver, Name: classSilver,
}, },
Snapshotter: mockDriverName, Driver: mockDriverName,
Parameters: class2Parameters, Parameters: class2Parameters,
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
@@ -76,8 +78,9 @@ var snapshotClasses = []*crdv1.VolumeSnapshotClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: emptySecretClass, Name: emptySecretClass,
}, },
Snapshotter: mockDriverName, Driver: mockDriverName,
Parameters: class4Parameters, Parameters: class4Parameters,
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
@@ -86,8 +89,9 @@ var snapshotClasses = []*crdv1.VolumeSnapshotClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: invalidSecretClass, Name: invalidSecretClass,
}, },
Snapshotter: mockDriverName, Driver: mockDriverName,
Parameters: class3Parameters, Parameters: class3Parameters,
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
@@ -96,8 +100,9 @@ var snapshotClasses = []*crdv1.VolumeSnapshotClass{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: validSecretClass, Name: validSecretClass,
}, },
Snapshotter: mockDriverName, Driver: mockDriverName,
Parameters: class5Parameters, Parameters: class5Parameters,
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
}, },
{ {
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
@@ -107,7 +112,8 @@ var snapshotClasses = []*crdv1.VolumeSnapshotClass{
Name: defaultClass, Name: defaultClass,
Annotations: map[string]string{IsDefaultSnapshotClassAnnotation: "true"}, Annotations: map[string]string{IsDefaultSnapshotClassAnnotation: "true"},
}, },
Snapshotter: mockDriverName, Driver: mockDriverName,
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
}, },
} }
@@ -119,7 +125,7 @@ func TestDeleteSync(t *testing.T) {
tests := []controllerTest{ tests := []controllerTest{
{ {
name: "1-1 - content with empty snapshot class is deleted if it is bound to a non-exist snapshot and also has a snapshot uid specified", name: "1-1 - content with empty snapshot class is deleted if it is bound to a non-exist snapshot and also has a snapshot uid specified",
initialContents: newContentArray("content1-1", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", &deletePolicy, nil, nil, true, nil), initialContents: newContentArray("content1-1", "snapuid1-1", "snap1-1", "sid1-1", classGold, "", "", deletionPolicy, nil, nil, true),
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
@@ -130,8 +136,8 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "2-1 - content with empty snapshot class will not be deleted if it is bound to a non-exist snapshot but it does not have a snapshot uid specified", name: "2-1 - content with empty snapshot class will not be deleted if it is bound to a non-exist snapshot but it does not have a snapshot uid specified",
initialContents: newContentArray("content2-1", classEmpty, "sid2-1", "vuid2-1", "volume2-1", "", "snap2-1", &deletePolicy, nil, nil, true, nil), initialContents: newContentArray("content2-1", "", "snap2-1", "sid2-1", "", "", "", deletionPolicy, nil, nil, true),
expectedContents: newContentArray("content2-1", classEmpty, "sid2-1", "vuid2-1", "volume2-1", "", "snap2-1", &deletePolicy, nil, nil, true, nil), expectedContents: newContentArray("content2-1", "", "snap2-1", "sid2-1", "", "", "", deletionPolicy, nil, nil, true),
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
expectedEvents: noevents, expectedEvents: noevents,
@@ -141,7 +147,7 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-2 - successful delete with snapshot class that has empty secret parameter", name: "1-2 - successful delete with snapshot class that has empty secret parameter",
initialContents: newContentArray("content1-2", emptySecretClass, "sid1-2", "vuid1-2", "volume1-2", "snapuid1-2", "snap1-2", &deletePolicy, nil, nil, true, emptyDataSecretAnnotations()), initialContents: newContentArray("content1-2", "sid1-2", "snap1-2", "sid1-2", emptySecretClass, "", "", deletionPolicy, nil, nil, true),
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
@@ -153,7 +159,7 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-3 - successful delete with snapshot class that has valid secret parameter", name: "1-3 - successful delete with snapshot class that has valid secret parameter",
initialContents: newContentArray("content1-3", validSecretClass, "sid1-3", "vuid1-3", "volume1-3", "snapuid1-3", "snap1-3", &deletePolicy, nil, nil, true, secretAnnotations()), initialContents: newContentArray("content1-3", "sid1-3", "snap1-3", "sid1-3", validSecretClass, "", "", deletionPolicy, nil, nil, true),
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
@@ -163,20 +169,20 @@ func TestDeleteSync(t *testing.T) {
expectedDeleteCalls: []deleteCall{{"sid1-3", map[string]string{"foo": "bar"}, nil}}, expectedDeleteCalls: []deleteCall{{"sid1-3", map[string]string{"foo": "bar"}, nil}},
test: testSyncContent, test: testSyncContent,
}, },
{ /*{
name: "1-4 - fail delete with snapshot class that has invalid secret parameter", name: "1-4 - fail delete with snapshot class that has invalid secret parameter",
initialContents: newContentArray("content1-4", invalidSecretClass, "sid1-4", "vuid1-4", "volume1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil, true, emptyNamespaceSecretAnnotations()), initialContents: newContentArray("content1-4", "sid1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil, true),
expectedContents: newContentArray("content1-4", invalidSecretClass, "sid1-4", "vuid1-4", "volume1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil, true, emptyNamespaceSecretAnnotations()), expectedContents: newContentArray("content1-4", "sid1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil, true),
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
expectedEvents: noevents, expectedEvents: noevents,
errors: noerrors, errors: noerrors,
test: testSyncContent, test: testSyncContent,
}, },*/
{ {
name: "1-5 - csi driver delete snapshot returns error", name: "1-5 - csi driver delete snapshot returns error",
initialContents: newContentArray("content1-5", validSecretClass, "sid1-5", "vuid1-5", "volume1-5", "snapuid1-5", "snap1-5", &deletePolicy, nil, nil, true, secretAnnotations()), initialContents: newContentArray("content1-5", "sid1-5", "snap1-5", "sid1-5", validSecretClass, "", "", deletionPolicy, nil, nil, true),
expectedContents: newContentArray("content1-5", validSecretClass, "sid1-5", "vuid1-5", "volume1-5", "snapuid1-5", "snap1-5", &deletePolicy, nil, nil, true, secretAnnotations()), expectedContents: newContentArray("content1-5", "sid1-5", "snap1-5", "sid1-5", validSecretClass, "", "", deletionPolicy, nil, nil, true),
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
@@ -187,15 +193,15 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-6 - api server delete content returns error", name: "1-6 - api server delete content returns error",
initialContents: newContentArray("content1-6", validSecretClass, "sid1-6", "vuid1-6", "volume1-6", "snapuid1-6", "snap1-6", &deletePolicy, nil, nil, true, secretAnnotations()), initialContents: newContentArray("content1-6", "sid1-6", "snap1-6", "sid1-6", validSecretClass, "", "", deletionPolicy, nil, nil, true),
expectedContents: newContentArray("content1-6", validSecretClass, "sid1-6", "vuid1-6", "volume1-6", "snapuid1-6", "snap1-6", &deletePolicy, nil, nil, true, secretAnnotations()), expectedContents: newContentArray("content1-6", "sid1-6", "snap1-6", "sid1-6", validSecretClass, "", "", deletionPolicy, nil, nil, true),
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
expectedDeleteCalls: []deleteCall{{"sid1-6", map[string]string{"foo": "bar"}, nil}}, expectedDeleteCalls: []deleteCall{{"sid1-6", map[string]string{"foo": "bar"}, nil}},
expectedEvents: []string{"Warning SnapshotContentObjectDeleteError"}, expectedEvents: []string{"Warning SnapshotContentObjectDeleteError"},
errors: []reactorError{ errors: []reactorError{
// Inject error to the first client.VolumesnapshotV1alpha1().VolumeSnapshotContents().Delete call. // Inject error to the first client.VolumesnapshotV1beta1().VolumeSnapshotContents().Delete call.
// All other calls will succeed. // All other calls will succeed.
{"delete", "volumesnapshotcontents", errors.New("mock delete error")}, {"delete", "volumesnapshotcontents", errors.New("mock delete error")},
}, },
@@ -205,10 +211,10 @@ func TestDeleteSync(t *testing.T) {
// delete success - snapshot that the content was pointing to was deleted, and another // delete success - snapshot that the content was pointing to was deleted, and another
// with the same name created. // with the same name created.
name: "1-7 - prebound content is deleted while the snapshot exists", name: "1-7 - prebound content is deleted while the snapshot exists",
initialContents: newContentArray("content1-7", validSecretClass, "sid1-7", "vuid1-7", "volume1-7", "snapuid1-7", "snap1-7", &deletePolicy, nil, nil, true, secretAnnotations()), initialContents: newContentArray("content1-7", "sid1-7", "snap1-7", "sid1-7", emptySecretClass, "", "", deletionPolicy, nil, nil, true),
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap1-7", validSecretClass, "content1-7", "snapuid1-7-x", "claim1-7", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap1-7", "snapuid1-7-x", "claim1-7", "", validSecretClass, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap1-7", validSecretClass, "content1-7", "snapuid1-7-x", "claim1-7", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-7", "snapuid1-7-x", "claim1-7", "", validSecretClass, "", &False, nil, nil, nil),
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
expectedDeleteCalls: []deleteCall{{"sid1-7", map[string]string{"foo": "bar"}, nil}}, expectedDeleteCalls: []deleteCall{{"sid1-7", map[string]string{"foo": "bar"}, nil}},
expectedEvents: noevents, expectedEvents: noevents,
@@ -218,7 +224,7 @@ func TestDeleteSync(t *testing.T) {
{ {
// delete success(?) - content is deleted before doDelete() starts // delete success(?) - content is deleted before doDelete() starts
name: "1-8 - content is deleted before deleting", name: "1-8 - content is deleted before deleting",
initialContents: newContentArray("content1-8", validSecretClass, "sid1-8", "vuid1-8", "volume1-8", "snapuid1-8", "snap1-8", &deletePolicy, nil, nil, true, secretAnnotations()), initialContents: newContentArray("content1-8", "sid1-8", "snap1-8", "sid1-8", validSecretClass, "", "", deletionPolicy, nil, nil, true),
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
@@ -235,33 +241,21 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-9 - content will not be deleted if it is bound to a snapshot correctly, snapshot uid is specified", name: "1-9 - content will not be deleted if it is bound to a snapshot correctly, snapshot uid is specified",
initialContents: newContentArray("content1-9", validSecretClass, "sid1-9", "vuid1-9", "volume1-9", "snapuid1-9", "snap1-9", &deletePolicy, nil, nil, true, nil), initialContents: newContentArray("content1-9", "snapuid1-9", "snap1-9", "sid1-9", validSecretClass, "", "", deletionPolicy, nil, nil, true),
expectedContents: newContentArray("content1-9", validSecretClass, "sid1-9", "vuid1-9", "volume1-9", "snapuid1-9", "snap1-9", &deletePolicy, nil, nil, true, nil), expectedContents: newContentArray("content1-9", "snapuid1-9", "snap1-9", "sid1-9", validSecretClass, "", "", deletionPolicy, nil, nil, true),
initialSnapshots: newSnapshotArray("snap1-9", validSecretClass, "content1-9", "snapuid1-9", "claim1-9", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap1-9", "snapuid1-9", "claim1-9", "", validSecretClass, "content1-9", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap1-9", validSecretClass, "content1-9", "snapuid1-9", "claim1-9", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-9", "snapuid1-9", "claim1-9", "", validSecretClass, "content1-9", &False, nil, nil, nil),
expectedEvents: noevents, expectedEvents: noevents,
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
errors: noerrors, errors: noerrors,
test: testSyncContent, test: testSyncContent,
}, },
{
name: "1-10 - should delete content which is bound to a snapshot incorrectly",
initialContents: newContentArray("content1-10", validSecretClass, "sid1-10", "vuid1-10", "volume1-10", "snapuid1-10-x", "snap1-10", &deletePolicy, nil, nil, true, secretAnnotations()),
expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-10", "snapuid1-10", "claim1-10", false, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-10", "snapuid1-10", "claim1-10", false, nil, nil, nil),
expectedEvents: noevents,
initialSecrets: []*v1.Secret{secret()},
errors: noerrors,
expectedDeleteCalls: []deleteCall{{"sid1-10", map[string]string{"foo": "bar"}, nil}},
test: testSyncContent,
},
{ {
name: "1-10 - will not delete content with retain policy set which is bound to a snapshot incorrectly", name: "1-10 - will not delete content with retain policy set which is bound to a snapshot incorrectly",
initialContents: newContentArray("content1-10", validSecretClass, "sid1-10", "vuid1-10", "volume1-10", "snapuid1-10-x", "snap1-10", &retainPolicy, nil, nil, true, nil), initialContents: newContentArray("content1-10", "snapuid1-10-x", "snap1-10", "sid1-10", validSecretClass, "", "", retainPolicy, nil, nil, true),
expectedContents: newContentArray("content1-10", validSecretClass, "sid1-10", "vuid1-10", "volume1-10", "snapuid1-10-x", "snap1-10", &retainPolicy, nil, nil, true, nil), expectedContents: newContentArray("content1-10", "snapuid1-10-x", "snap1-10", "sid1-10", validSecretClass, "", "", retainPolicy, nil, nil, true),
initialSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-10", "snapuid1-10", "claim1-10", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap1-10", "snapuid1-10", "claim1-10", "", validSecretClass, "content1-10", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-10", "snapuid1-10", "claim1-10", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-10", "snapuid1-10", "claim1-10", "", validSecretClass, "content1-10", &False, nil, nil, nil),
expectedEvents: noevents, expectedEvents: noevents,
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
errors: noerrors, errors: noerrors,
@@ -269,10 +263,10 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-11 - content will not be deleted if it is bound to a snapshot correctly, snapsht uid is not specified", name: "1-11 - content will not be deleted if it is bound to a snapshot correctly, snapsht uid is not specified",
initialContents: newContentArray("content1-11", validSecretClass, "sid1-11", "vuid1-11", "volume1-11", "", "snap1-11", &deletePolicy, nil, nil, true, nil), initialContents: newContentArray("content1-11", "", "snap1-11", "sid1-11", validSecretClass, "", "", deletePolicy, nil, nil, true),
expectedContents: newContentArray("content1-11", validSecretClass, "sid1-11", "vuid1-11", "volume1-11", "", "snap1-11", &deletePolicy, nil, nil, true, nil), expectedContents: newContentArray("content1-11", "", "snap1-11", "sid1-11", validSecretClass, "", "", deletePolicy, nil, nil, true),
initialSnapshots: newSnapshotArray("snap1-11", validSecretClass, "content1-11", "snapuid1-11", "claim1-11", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap1-11", "snapuid1-11", "claim1-11", "", validSecretClass, "content1-11", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap1-11", validSecretClass, "content1-11", "snapuid1-11", "claim1-11", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-11", "snapuid1-11", "claim1-11", "", validSecretClass, "content1-11", &False, nil, nil, nil),
expectedEvents: noevents, expectedEvents: noevents,
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
errors: noerrors, errors: noerrors,
@@ -280,8 +274,8 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-12 - content with retain policy will not be deleted if it is bound to a non-exist snapshot and also has a snapshot uid specified", name: "1-12 - content with retain policy will not be deleted if it is bound to a non-exist snapshot and also has a snapshot uid specified",
initialContents: newContentArray("content1-12", classEmpty, "sid1-12", "vuid1-12", "volume1-12", "snapuid1-12", "snap1-12", &retainPolicy, nil, nil, true, nil), initialContents: newContentArray("content1-12", "sid1-12", "snap1-11", "sid1-11", validSecretClass, "", "", retainPolicy, nil, nil, true),
expectedContents: newContentArray("content1-12", classEmpty, "sid1-12", "vuid1-12", "volume1-12", "snapuid1-12", "snap1-12", &retainPolicy, nil, nil, true, nil), expectedContents: newContentArray("content1-12", "sid1-12", "snap1-11", "sid1-11", validSecretClass, "", "", retainPolicy, nil, nil, true),
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
expectedEvents: noevents, expectedEvents: noevents,
@@ -290,8 +284,8 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-13 - content with empty snapshot class is not deleted when Deletion policy is not set even if it is bound to a non-exist snapshot and also has a snapshot uid specified", name: "1-13 - content with empty snapshot class is not deleted when Deletion policy is not set even if it is bound to a non-exist snapshot and also has a snapshot uid specified",
initialContents: newContentArray("content1-1", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil, true, nil), initialContents: newContentArray("content1-13", "sid1-13", "snap1-13", "sid1-13", validSecretClass, "", "", retainPolicy, nil, nil, true),
expectedContents: newContentArray("content1-1", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil, true, nil), expectedContents: newContentArray("content1-13", "sid1-13", "snap1-13", "sid1-13", validSecretClass, "", "", retainPolicy, nil, nil, true),
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,
expectedEvents: noevents, expectedEvents: noevents,
@@ -300,21 +294,10 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-14 - content will not be deleted if it is bound to a snapshot correctly, snapshot uid is specified", name: "1-14 - content will not be deleted if it is bound to a snapshot correctly, snapshot uid is specified",
initialContents: newContentArray("content1-14", validSecretClass, "sid1-14", "vuid1-14", "volume1-14", "snapuid1-14", "snap1-14", &retainPolicy, nil, nil, true, nil), initialContents: newContentArray("content1-14", "snapuid1-14", "snap1-14", "sid1-14", validSecretClass, "", "", retainPolicy, nil, nil, true),
expectedContents: newContentArray("content1-14", validSecretClass, "sid1-14", "vuid1-14", "volume1-14", "snapuid1-14", "snap1-14", &retainPolicy, nil, nil, true, nil), expectedContents: newContentArray("content1-14", "snapuid1-14", "snap1-14", "sid1-14", validSecretClass, "", "", retainPolicy, nil, nil, true),
initialSnapshots: newSnapshotArray("snap1-14", validSecretClass, "content1-14", "snapuid1-14", "claim1-14", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap1-14", "snapuid1-14", "claim1-14", "", validSecretClass, "content1-14", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap1-14", validSecretClass, "content1-14", "snapuid1-14", "claim1-14", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-14", "snapuid1-14", "claim1-14", "", validSecretClass, "content1-14", &False, nil, nil, nil),
expectedEvents: noevents,
initialSecrets: []*v1.Secret{secret()},
errors: noerrors,
test: testSyncContent,
},
{
name: "1-15 - content will not be deleted which is bound to a snapshot incorrectly if Deletion policy is not set",
initialContents: newContentArray("content1-10", validSecretClass, "sid1-15", "vuid1-15", "volume1-15", "snapuid1-15-x", "snap1-15", nil, nil, nil, true, nil),
expectedContents: newContentArray("content1-10", validSecretClass, "sid1-15", "vuid1-15", "volume1-15", "snapuid1-15-x", "snap1-15", nil, nil, nil, true, nil),
initialSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-15", "snapuid1-15", "claim1-15", false, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-15", "snapuid1-15", "claim1-15", false, nil, nil, nil),
expectedEvents: noevents, expectedEvents: noevents,
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
errors: noerrors, errors: noerrors,
@@ -322,7 +305,7 @@ func TestDeleteSync(t *testing.T) {
}, },
{ {
name: "1-16 - continue delete with snapshot class that has nonexistent secret", name: "1-16 - continue delete with snapshot class that has nonexistent secret",
initialContents: newContentArray("content1-16", validSecretClass, "sid1-16", "vuid1-16", "volume1-16", "snapuid1-16", "snap1-16", &deletePolicy, nil, nil, true, secretAnnotations()), initialContents: newContentArray("content1-16", "sid1-16", "snap1-16", "sid1-16", emptySecretClass, "", "", deletePolicy, nil, nil, true),
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: nosnapshots, initialSnapshots: nosnapshots,
expectedSnapshots: nosnapshots, expectedSnapshots: nosnapshots,

View File

@@ -19,7 +19,7 @@ package controller
import ( import (
"testing" "testing"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
) )
// Test single call to ensureSnapshotSourceFinalizer and checkandRemoveSnapshotSourceFinalizer, // Test single call to ensureSnapshotSourceFinalizer and checkandRemoveSnapshotSourceFinalizer,
@@ -29,35 +29,35 @@ func TestPVCFinalizer(t *testing.T) {
tests := []controllerTest{ tests := []controllerTest{
{ {
name: "1-1 - successful add PVC finalizer", name: "1-1 - successful add PVC finalizer",
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil),
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),
test: testAddPVCFinalizer, test: testAddPVCFinalizer,
expectSuccess: true, expectSuccess: true,
}, },
{ {
name: "1-2 - won't add PVC finalizer; already added", name: "1-2 - won't add PVC finalizer; already added",
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil),
initialClaims: newClaimArrayFinalizer("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), initialClaims: newClaimArrayFinalizer("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
test: testAddPVCFinalizer, test: testAddPVCFinalizer,
expectSuccess: false, expectSuccess: false,
}, },
{ {
name: "1-3 - successful remove PVC finalizer", name: "1-3 - successful remove PVC finalizer",
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil),
initialClaims: newClaimArrayFinalizer("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), initialClaims: newClaimArrayFinalizer("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty),
test: testRemovePVCFinalizer, test: testRemovePVCFinalizer,
expectSuccess: true, expectSuccess: true,
}, },
{ {
name: "1-4 - won't remove PVC finalizer; already removed", name: "1-4 - won't remove PVC finalizer; already removed",
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil),
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),
test: testRemovePVCFinalizer, test: testRemovePVCFinalizer,
expectSuccess: false, expectSuccess: false,
}, },
{ {
name: "1-5 - won't remove PVC finalizer; PVC in-use", name: "1-5 - won't remove PVC finalizer; PVC in-use",
initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil),
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),
test: testRemovePVCFinalizer, test: testRemovePVCFinalizer,
expectSuccess: false, expectSuccess: false,

View File

@@ -21,7 +21,7 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storagev1beta1 "k8s.io/api/storage/v1beta1" storagev1beta1 "k8s.io/api/storage/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
@@ -47,42 +47,43 @@ func TestSync(t *testing.T) {
name: "2-1 - snapshot is bound to a non-existing content", name: "2-1 - snapshot is bound to a non-existing content",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap2-1", validSecretClass, "content2-1", "snapuid2-1", "claim2-1", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap2-1", "snapuid2-1", "claim2-1", "", validSecretClass, "content2-1", &True, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-1", validSecretClass, "content2-1", "snapuid2-1", "claim2-1", false, newVolumeError("VolumeSnapshotContent is missing"), nil, nil), expectedSnapshots: newSnapshotArray("snap2-1", "snapuid2-1", "claim2-1", "", validSecretClass, "content2-1", &False, nil, nil, newVolumeError("VolumeSnapshotContent is missing")),
expectedEvents: []string{"Warning SnapshotContentMissing"}, expectedEvents: []string{"Warning SnapshotContentMissing"},
errors: noerrors, errors: noerrors,
test: testSyncSnapshotError, test: testSyncSnapshot,
}, },
{ {
name: "2-2 - could not bind snapshot and content, the VolumeSnapshotRef does not match", name: "2-2 - snapshot points to a content but content does not point to snapshot(VolumeSnapshotRef does not match)",
initialContents: newContentArray("content2-2", validSecretClass, "sid2-2", "vuid2-2", "volume2-2", "snapuid2-2-x", "snap2-2", &deletePolicy, nil, nil, false, nil), initialContents: newContentArray("content2-2", "snapuid2-2-x", "snap2-2", "sid2-2", validSecretClass, "", "", deletionPolicy, nil, nil, false),
expectedContents: newContentArray("content2-2", validSecretClass, "sid2-2", "vuid2-2", "volume2-2", "snapuid2-2-x", "snap2-2", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArray("content2-2", "snapuid2-2-x", "snap2-2", "sid2-2", validSecretClass, "", "", deletionPolicy, nil, nil, false),
initialSnapshots: newSnapshotArray("snap2-2", validSecretClass, "content2-2", "snapuid2-2", "claim2-2", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap2-2", "snapuid2-2", "claim2-2", "", validSecretClass, "content2-2", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-2", validSecretClass, "content2-2", "snapuid2-2", "claim2-2", false, newVolumeError("Snapshot failed to bind VolumeSnapshotContent, Could not bind snapshot snap2-2 and content content2-2, the VolumeSnapshotRef does not match"), nil, nil), expectedSnapshots: newSnapshotArray("snap2-2", "snapuid2-2", "claim2-2", "", validSecretClass, "content2-2", &False, nil, nil, newVolumeError("Snapshot is bound to a VolumeSnapshotContent which is bound to other Snapshot")),
expectedEvents: []string{"Warning SnapshotBindFailed"}, expectedEvents: []string{"Warning InvalidSnapshotBinding"},
errors: noerrors, errors: noerrors,
test: testSyncSnapshotError, test: testSyncSnapshotError,
}, },
{ {
name: "2-3 - success bind snapshot and content but not ready, no status changed", name: "2-3 - success bind snapshot and content but not ready, no status changed",
initialContents: newContentArray("content2-3", validSecretClass, "sid2-3", "vuid2-3", "volume2-3", "", "snap2-3", &deletePolicy, nil, nil, false, nil), initialContents: newContentArray("content2-3", "snapuid2-3", "snap2-3", "sid2-3", validSecretClass, "", "", deletionPolicy, nil, nil, false),
expectedContents: newContentArray("content2-3", validSecretClass, "sid2-3", "vuid2-3", "volume2-3", "snapuid2-3", "snap2-3", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArrayWithReadyToUse("content2-3", "snapuid2-3", "snap2-3", "sid2-3", validSecretClass, "", "", deletionPolicy, &timeNowStamp, &defaultSize, &False, false),
initialSnapshots: newSnapshotArray("snap2-3", validSecretClass, "content2-3", "snapuid2-3", "claim2-3", false, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap2-3", "snapuid2-3", "claim2-3", "", validSecretClass, "content2-3", &False, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-3", validSecretClass, "content2-3", "snapuid2-3", "claim2-3", false, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-3", "snapuid2-3", "claim2-3", "", validSecretClass, "content2-3", &False, metaTimeNow, getSize(defaultSize), nil),
initialClaims: newClaimArray("claim2-3", "pvc-uid2-3", "1Gi", "volume2-3", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim2-3", "pvc-uid2-3", "1Gi", "volume2-3", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume2-3", "pv-uid2-3", "pv-handle2-3", "1Gi", "pvc-uid2-3", "claim2-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume2-3", "pv-uid2-3", "pv-handle2-3", "1Gi", "pvc-uid2-3", "claim2-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid2-3", snapshotName: "snapshot-snapuid2-3",
volume: newVolume("volume2-3", "pv-uid2-3", "pv-handle2-3", "1Gi", "pvc-uid2-3", "claim2-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), volume: newVolume("volume2-3", "pv-uid2-3", "pv-handle2-3", "1Gi", "pvc-uid2-3", "claim2-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
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,
snapshotId: "sid2-3", snapshotId: "sid2-3",
creationTime: timeNow, creationTime: timeNow,
readyToUse: false, readyToUse: False,
}, },
}, },
errors: noerrors, errors: noerrors,
@@ -91,33 +92,34 @@ func TestSync(t *testing.T) {
{ {
// nothing changed // nothing changed
name: "2-4 - noop", name: "2-4 - noop",
initialContents: newContentArray("content2-4", validSecretClass, "sid2-4", "vuid2-4", "volume2-4", "snapuid2-4", "snap2-4", &deletePolicy, nil, nil, false, nil), initialContents: newContentArray("content2-4", "snapuid2-4", "snap2-4", "sid2-4", validSecretClass, "", "", deletionPolicy, nil, nil, false),
expectedContents: newContentArray("content2-4", validSecretClass, "sid2-4", "vuid2-4", "volume2-4", "snapuid2-4", "snap2-4", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArray("content2-4", "snapuid2-4", "snap2-4", "sid2-4", validSecretClass, "", "", deletionPolicy, nil, nil, false),
initialSnapshots: newSnapshotArray("snap2-4", validSecretClass, "content2-4", "snapuid2-4", "claim2-4", true, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap2-4", "snapuid2-4", "claim2-4", "", validSecretClass, "content2-4", &True, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-4", validSecretClass, "content2-4", "snapuid2-4", "claim2-4", true, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-4", "snapuid2-4", "claim2-4", "", validSecretClass, "content2-4", &True, metaTimeNow, nil, nil),
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "2-5 - snapshot and content bound, status ready false -> true", name: "2-5 - snapshot and content bound, status ready false -> true",
initialContents: newContentArray("content2-5", validSecretClass, "sid2-5", "vuid2-5", "volume2-5", "snapuid2-5", "snap2-5", &deletePolicy, nil, nil, false, nil), initialContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false),
expectedContents: newContentArray("content2-5", validSecretClass, "sid2-5", "vuid2-5", "volume2-5", "snapuid2-5", "snap2-5", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, &timeNowStamp, &defaultSize, &True, false),
initialSnapshots: newSnapshotArray("snap2-5", validSecretClass, "content2-5", "snapuid2-5", "claim2-5", false, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &False, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-5", validSecretClass, "content2-5", "snapuid2-5", "claim2-5", true, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &True, metaTimeNow, getSize(defaultSize), nil),
initialClaims: newClaimArray("claim2-5", "pvc-uid2-5", "1Gi", "volume2-5", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim2-5", "pvc-uid2-5", "1Gi", "volume2-5", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume2-5", "pv-uid2-5", "pv-handle2-5", "1Gi", "pvc-uid2-5", "claim2-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume2-5", "pv-uid2-5", "pv-handle2-5", "1Gi", "pvc-uid2-5", "claim2-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid2-5", snapshotName: "snapshot-snapuid2-5",
volume: newVolume("volume2-5", "pv-uid2-5", "pv-handle2-5", "1Gi", "pvc-uid2-5", "claim2-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), volume: newVolume("volume2-5", "pv-uid2-5", "pv-handle2-5", "1Gi", "pvc-uid2-5", "claim2-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
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,
snapshotId: "sid2-5", snapshotId: "sid2-5",
creationTime: timeNow, creationTime: timeNow,
readyToUse: true, readyToUse: True,
}, },
}, },
errors: noerrors, errors: noerrors,
@@ -125,12 +127,13 @@ 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, &timeNowStamp, false, nil), initialContents: newContentArrayWithReadyToUse("content2-6", "snapuid2-6", "snap2-6", "sid2-6", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false),
expectedContents: newContentArray("content2-6", validSecretClass, "sid2-6", noVolume, noVolume, "snapuid2-6", "snap2-6", &deletePolicy, nil, &timeNowStamp, false, nil), expectedContents: newContentArrayWithReadyToUse("content2-6", "snapuid2-6", "snap2-6", "sid2-6", validSecretClass, "", "", deletionPolicy, &timeNowStamp, &defaultSize, &True, false),
initialSnapshots: newSnapshotArray("snap2-6", validSecretClass, "content2-6", "snapuid2-6", noClaim, false, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap2-6", "snapuid2-6", "", "content2-6", validSecretClass, "content2-6", &False, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-6", validSecretClass, "content2-6", "snapuid2-6", noClaim, true, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-6", "snapuid2-6", "", "content2-6", validSecretClass, "content2-6", &True, metaTimeNow, getSize(defaultSize), nil),
expectedListCalls: []listCall{ expectedListCalls: []listCall{
{ {
size: defaultSize,
snapshotID: "sid2-6", snapshotID: "sid2-6",
readyToUse: true, readyToUse: true,
}, },
@@ -140,18 +143,18 @@ func TestSync(t *testing.T) {
}, },
{ {
name: "2-7 - snapshot and content bound, csi driver get status error", name: "2-7 - snapshot and content bound, csi driver get status error",
initialContents: newContentArray("content2-7", validSecretClass, "sid2-7", "vuid2-7", "volume2-7", "snapuid2-7", "snap2-7", &deletePolicy, nil, nil, false, nil), initialContents: newContentArrayWithReadyToUse("content2-7", "snapuid2-7", "snap2-7", "sid2-7", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false),
expectedContents: newContentArray("content2-7", validSecretClass, "sid2-7", "vuid2-7", "volume2-7", "snapuid2-7", "snap2-7", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArrayWithReadyToUse("content2-7", "snapuid2-7", "snap2-7", "sid2-7", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false),
initialSnapshots: newSnapshotArray("snap2-7", validSecretClass, "content2-7", "snapuid2-7", "claim2-7", false, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap2-7", "snapuid2-7", "claim2-7", "", validSecretClass, "content2-7", &False, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-7", validSecretClass, "content2-7", "snapuid2-7", "claim2-7", false, newVolumeError("Failed to check and update snapshot: mock create snapshot error"), metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-7", "snapuid2-7", "claim2-7", "", validSecretClass, "content2-7", &False, metaTimeNow, nil, newVolumeError("Failed to check and update snapshot: mock create snapshot error")),
expectedEvents: []string{"Warning SnapshotCheckandUpdateFailed"}, expectedEvents: []string{"Warning SnapshotCheckandUpdateFailed"},
initialClaims: newClaimArray("claim2-7", "pvc-uid2-7", "1Gi", "volume2-7", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim2-7", "pvc-uid2-7", "1Gi", "volume2-7", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume2-7", "pv-uid2-7", "pv-handle2-7", "1Gi", "pvc-uid2-7", "claim2-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume2-7", "pv-uid2-7", "pv-handle2-7", "1Gi", "pvc-uid2-7", "claim2-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid2-7", snapshotName: "snapshot-snapuid2-7",
volume: newVolume("volume2-7", "pv-uid2-7", "pv-handle2-7", "1Gi", "pvc-uid2-7", "claim2-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), volume: newVolume("volume2-7", "pv-uid2-7", "pv-handle2-7", "1Gi", "pvc-uid2-7", "claim2-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
parameters: class5Parameters, parameters: class5Parameters,
secrets: map[string]string{"foo": "bar"}, secrets: map[string]string{"foo": "bar"},
// information to return // information to return
@@ -163,18 +166,18 @@ func TestSync(t *testing.T) {
}, },
{ {
name: "2-8 - snapshot and content bound, apiserver update status error", name: "2-8 - snapshot and content bound, apiserver update status error",
initialContents: newContentArray("content2-8", validSecretClass, "sid2-8", "vuid2-8", "volume2-8", "snapuid2-8", "snap2-8", &deletePolicy, nil, nil, false, nil), initialContents: newContentArrayWithReadyToUse("content2-8", "snapuid2-8", "snap2-8", "sid2-8", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false),
expectedContents: newContentArray("content2-8", validSecretClass, "sid2-8", "vuid2-8", "volume2-8", "snapuid2-8", "snap2-8", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArrayWithReadyToUse("content2-8", "snapuid2-8", "snap2-8", "sid2-8", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false),
initialSnapshots: newSnapshotArray("snap2-8", validSecretClass, "content2-8", "snapuid2-8", "claim2-8", false, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap2-8", "snapuid2-8", "claim2-8", "", validSecretClass, "content2-8", &False, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-8", validSecretClass, "content2-8", "snapuid2-8", "claim2-8", false, newVolumeError("Failed to check and update snapshot: snapshot controller failed to update default/snap2-8 on API server: mock update error"), metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-8", "snapuid2-8", "claim2-8", "", validSecretClass, "content2-8", &False, metaTimeNow, nil, newVolumeError("Failed to check and update snapshot: snapshot controller failed to update default/snap2-8 on API server: mock update error")),
expectedEvents: []string{"Warning SnapshotCheckandUpdateFailed"}, expectedEvents: []string{"Warning SnapshotCheckandUpdateFailed"},
initialClaims: newClaimArray("claim2-8", "pvc-uid2-8", "1Gi", "volume2-8", v1.ClaimBound, &classEmpty), initialClaims: newClaimArray("claim2-8", "pvc-uid2-8", "1Gi", "volume2-8", v1.ClaimBound, &classEmpty),
initialVolumes: newVolumeArray("volume2-8", "pv-uid2-8", "pv-handle2-8", "1Gi", "pvc-uid2-8", "claim2-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), initialVolumes: newVolumeArray("volume2-8", "pv-uid2-8", "pv-handle2-8", "1Gi", "pvc-uid2-8", "claim2-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
initialSecrets: []*v1.Secret{secret()}, initialSecrets: []*v1.Secret{secret()},
expectedCreateCalls: []createCall{ expectedCreateCalls: []createCall{
{ {
snapshotName: "snapshot-snapuid2-8", snapshotName: "snapshot-snapuid2-8",
volume: newVolume("volume2-8", "pv-uid2-8", "pv-handle2-8", "1Gi", "pvc-uid2-8", "claim2-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty, mockDriverName, testNamespace), volume: newVolume("volume2-8", "pv-uid2-8", "pv-handle2-8", "1Gi", "pvc-uid2-8", "claim2-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty),
parameters: class5Parameters, parameters: class5Parameters,
secrets: map[string]string{"foo": "bar"}, secrets: map[string]string{"foo": "bar"},
// information to return // information to return
@@ -186,27 +189,27 @@ func TestSync(t *testing.T) {
}, },
}, },
errors: []reactorError{ errors: []reactorError{
// Inject error to the first client.VolumesnapshotV1alpha1().VolumeSnapshots().Update call. // Inject error to the first client.VolumesnapshotV1beta1().VolumeSnapshots().Update call.
// All other calls will succeed. // All other calls will succeed.
{"update", "volumesnapshots", errors.New("mock update error")}, {"update", "volumesnapshots", errors.New("mock update error")},
}, },
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "2-9 - bind when snapshot and content matches", name: "2-9 - fail on status update as there is not pvc provided",
initialContents: newContentArray("content2-9", validSecretClass, "sid2-9", "vuid2-9", "volume2-9", "snapuid2-9", "snap2-9", &deletePolicy, nil, nil, false, nil), initialContents: newContentArray("content2-9", "snapuid2-9", "snap2-9", "sid2-9", validSecretClass, "", "", deletionPolicy, nil, nil, false),
expectedContents: newContentArray("content2-9", validSecretClass, "sid2-9", "vuid2-9", "volume2-9", "snapuid2-9", "snap2-9", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArray("content2-9", "snapuid2-9", "snap2-9", "sid2-9", validSecretClass, "", "", deletionPolicy, nil, nil, false),
initialSnapshots: newSnapshotArray("snap2-9", validSecretClass, "", "snapuid2-9", "claim2-9", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap2-9", "snapuid2-9", "claim2-9", "", validSecretClass, "", &False, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap2-9", validSecretClass, "content2-9", "snapuid2-9", "claim2-9", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap2-9", "snapuid2-9", "claim2-9", "", validSecretClass, "", &False, nil, nil, newVolumeError("Failed to check and update snapshot: failed to get input parameters to create snapshot snap2-9: \"failed to retrieve PVC claim2-9 from the lister: \\\"persistentvolumeclaim \\\\\\\"claim2-9\\\\\\\" not found\\\"\"")),
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "2-10 - do not bind when snapshot and content not match", name: "2-10 - do not bind when snapshot and content not match",
initialContents: newContentArray("content2-10", validSecretClass, "sid2-10", "vuid2-10", "volume2-10", "snapuid2-10-x", "snap2-10", &deletePolicy, nil, nil, false, nil), initialContents: newContentArray("content2-10", "snapuid2-10-x", "snap2-10", "sid2-10", validSecretClass, "", "", deletionPolicy, nil, nil, false),
expectedContents: newContentArray("content2-10", validSecretClass, "sid2-10", "vuid2-10", "volume2-10", "snapuid2-10-x", "snap2-10", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArray("content2-10", "snapuid2-10-x", "snap2-10", "sid2-10", validSecretClass, "", "", deletionPolicy, nil, nil, false),
initialSnapshots: newSnapshotArray("snap2-10", validSecretClass, "", "snapuid2-10", "claim2-10", false, newVolumeError("mock driver error"), nil, nil), initialSnapshots: newSnapshotArray("snap2-10", "snapuid2-10", "claim2-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("mock driver error")),
expectedSnapshots: newSnapshotArray("snap2-10", validSecretClass, "", "snapuid2-10", "claim2-10", false, newVolumeError("mock driver error"), nil, nil), expectedSnapshots: newSnapshotArray("snap2-10", "snapuid2-10", "claim2-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("mock driver error")),
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
@@ -214,56 +217,46 @@ func TestSync(t *testing.T) {
name: "3-1 - ready snapshot lost reference to VolumeSnapshotContent", name: "3-1 - ready snapshot lost reference to VolumeSnapshotContent",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap3-1", validSecretClass, "", "snapuid3-1", "claim3-1", true, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &True, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap3-1", validSecretClass, "", "snapuid3-1", "claim3-1", false, newVolumeError("Bound snapshot has lost reference to VolumeSnapshotContent"), metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is missing")),
errors: noerrors, errors: noerrors,
expectedEvents: []string{"Warning SnapshotLost"}, expectedEvents: []string{"Warning SnapshotContentMissing"},
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "3-2 - ready snapshot bound to none-exist content", name: "3-2 - ready snapshot bound to none-exist content",
initialContents: nocontents, initialContents: nocontents,
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap3-2", validSecretClass, "content3-2", "snapuid3-2", "claim3-2", true, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &True, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap3-2", validSecretClass, "content3-2", "snapuid3-2", "claim3-2", false, newVolumeError("VolumeSnapshotContent is missing"), metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is missing")),
errors: noerrors, errors: noerrors,
expectedEvents: []string{"Warning SnapshotContentMissing"}, expectedEvents: []string{"Warning SnapshotContentMissing"},
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "3-3 - ready snapshot(everything is well, do nothing)", name: "3-3 - ready snapshot(everything is well, do nothing)",
initialContents: newContentArray("content3-3", validSecretClass, "sid3-3", "vuid3-3", "volume3-3", "snapuid3-3", "snap3-3", &deletePolicy, nil, nil, false, nil), initialContents: newContentArray("content3-3", "snapuid3-3", "snap3-3", "sid3-3", validSecretClass, "", "", deletionPolicy, nil, nil, false),
expectedContents: newContentArray("content3-3", validSecretClass, "sid3-3", "vuid3-3", "volume3-3", "snapuid3-3", "snap3-3", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArray("content3-3", "snapuid3-3", "snap3-3", "sid3-3", validSecretClass, "", "", deletionPolicy, nil, nil, false),
initialSnapshots: newSnapshotArray("snap3-3", validSecretClass, "content3-3", "snapuid3-3", "claim3-3", true, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &True, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap3-3", validSecretClass, "content3-3", "snapuid3-3", "claim3-3", true, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &True, metaTimeNow, nil, nil),
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "3-4 - ready snapshot misbound to VolumeSnapshotContent", name: "3-4 - ready snapshot misbound to VolumeSnapshotContent",
initialContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-4", &deletePolicy, nil, nil, false, nil), initialContents: newContentArray("content3-4", "snapuid3-4-x", "snap3-4", "sid3-4", validSecretClass, "", "", deletionPolicy, nil, nil, false),
expectedContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-4", &deletePolicy, nil, nil, false, nil), expectedContents: newContentArray("content3-4", "snapuid3-4-x", "snap3-4", "sid3-4", validSecretClass, "", "", deletionPolicy, nil, nil, false),
initialSnapshots: newSnapshotArray("snap3-4", validSecretClass, "content3-4", "snapuid3-4", "claim3-4", true, nil, metaTimeNow, nil), initialSnapshots: newSnapshotArray("snap3-4", "snapuid3-4", "claim3-4", "", validSecretClass, "content3-4", &True, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap3-4", validSecretClass, "content3-4", "snapuid3-4", "claim3-4", false, newVolumeError("VolumeSnapshotContent is not bound to the VolumeSnapshot correctly"), metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap3-4", "snapuid3-4", "claim3-4", "", validSecretClass, "content3-4", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is not bound to the VolumeSnapshot correctly")),
errors: noerrors, errors: noerrors,
test: testSyncSnapshot, test: testSyncSnapshot,
}, },
{ {
name: "3-5 - snapshot bound to content in which the driver does not match", name: "3-5 - snapshot bound to content in which the driver does not match",
initialContents: newContentWithUnmatchDriverArray("content3-5", validSecretClass, "sid3-5", "vuid3-5", "volume3-5", "", "snap3-5", &deletePolicy, nil, nil), initialContents: newContentWithUnmatchDriverArray("content3-5", "snapuid3-5", "snap3-5", "sid3-5", validSecretClass, "", "", deletionPolicy, nil, nil, false),
expectedContents: nocontents, expectedContents: nocontents,
initialSnapshots: newSnapshotArray("snap3-5", validSecretClass, "content3-5", "snapuid3-5", "claim3-5", false, nil, nil, nil), initialSnapshots: newSnapshotArray("snap3-5", "snapuid3-5", "claim3-5", "", validSecretClass, "content3-5", &False, metaTimeNow, nil, nil),
expectedSnapshots: newSnapshotArray("snap3-5", validSecretClass, "content3-5", "snapuid3-5", "claim3-5", false, newVolumeError("VolumeSnapshotContent is missing"), nil, nil), expectedSnapshots: newSnapshotArray("snap3-5", "snapuid3-5", "claim3-5", "", validSecretClass, "content3-5", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is missing")),
expectedEvents: []string{"Warning SnapshotContentMissing"},
errors: noerrors,
test: testSyncSnapshotError,
},
{
name: "3-6 - snapshot bound to content in which the snapshot uid does not match",
initialContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-6", &deletePolicy, nil, nil, false, nil),
expectedContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-6", &deletePolicy, nil, nil, false, nil),
initialSnapshots: newSnapshotArray("snap3-5", validSecretClass, "content3-5", "snapuid3-5", "claim3-5", false, nil, nil, nil),
expectedSnapshots: newSnapshotArray("snap3-5", validSecretClass, "content3-5", "snapuid3-5", "claim3-5", false, newVolumeError("VolumeSnapshotContent is missing"), nil, nil),
expectedEvents: []string{"Warning SnapshotContentMissing"}, expectedEvents: []string{"Warning SnapshotContentMissing"},
errors: noerrors, errors: noerrors,
test: testSyncSnapshotError, test: testSyncSnapshotError,

View File

@@ -20,8 +20,12 @@ import (
"fmt" "fmt"
"strings" "strings"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" "os"
"k8s.io/api/core/v1" "strconv"
"time"
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
@@ -30,9 +34,6 @@ import (
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/util/slice" "k8s.io/kubernetes/pkg/util/slice"
"os"
"strconv"
"time"
) )
var ( var (
@@ -87,7 +88,7 @@ func snapshotKey(vs *crdv1.VolumeSnapshot) string {
return fmt.Sprintf("%s/%s", vs.Namespace, vs.Name) return fmt.Sprintf("%s/%s", vs.Namespace, vs.Name)
} }
func snapshotRefKey(vsref *v1.ObjectReference) string { func snapshotRefKey(vsref v1.ObjectReference) string {
return fmt.Sprintf("%s/%s", vsref.Namespace, vsref.Name) return fmt.Sprintf("%s/%s", vsref.Namespace, vsref.Name)
} }
@@ -152,8 +153,8 @@ func storeObjectUpdate(store cache.Store, obj interface{}, className string) (bo
func GetSnapshotContentNameForSnapshot(snapshot *crdv1.VolumeSnapshot) string { func GetSnapshotContentNameForSnapshot(snapshot *crdv1.VolumeSnapshot) string {
// If VolumeSnapshot object has SnapshotContentName, use it directly. // If VolumeSnapshot object has SnapshotContentName, use it directly.
// This might be the case for static provisioning. // This might be the case for static provisioning.
if len(snapshot.Spec.SnapshotContentName) > 0 { if snapshot.Spec.Source.VolumeSnapshotContentName != nil {
return snapshot.Spec.SnapshotContentName return *snapshot.Spec.Source.VolumeSnapshotContentName
} }
// Construct SnapshotContentName for dynamic provisioning. // Construct SnapshotContentName for dynamic provisioning.
return "snapcontent-" + string(snapshot.UID) return "snapcontent-" + string(snapshot.UID)

View File

@@ -17,7 +17,7 @@ limitations under the License.
package controller package controller
import ( import (
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"reflect" "reflect"

View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@@ -1,262 +0,0 @@
/*
Copyright 2017 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 apiextensions
import "k8s.io/apimachinery/pkg/runtime"
// TODO: Update this after a tag is created for interface fields in DeepCopy
func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps {
if in == nil {
return nil
}
out := new(JSONSchemaProps)
*out = *in
if in.Default != nil {
defaultJSON := JSON(runtime.DeepCopyJSONValue(*(in.Default)))
out.Default = &(defaultJSON)
} else {
out.Default = nil
}
if in.Example != nil {
exampleJSON := JSON(runtime.DeepCopyJSONValue(*(in.Example)))
out.Example = &(exampleJSON)
} else {
out.Example = nil
}
if in.Ref != nil {
in, out := &in.Ref, &out.Ref
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
if in.Maximum != nil {
in, out := &in.Maximum, &out.Maximum
if *in == nil {
*out = nil
} else {
*out = new(float64)
**out = **in
}
}
if in.Minimum != nil {
in, out := &in.Minimum, &out.Minimum
if *in == nil {
*out = nil
} else {
*out = new(float64)
**out = **in
}
}
if in.MaxLength != nil {
in, out := &in.MaxLength, &out.MaxLength
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MinLength != nil {
in, out := &in.MinLength, &out.MinLength
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MaxItems != nil {
in, out := &in.MaxItems, &out.MaxItems
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MinItems != nil {
in, out := &in.MinItems, &out.MinItems
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MultipleOf != nil {
in, out := &in.MultipleOf, &out.MultipleOf
if *in == nil {
*out = nil
} else {
*out = new(float64)
**out = **in
}
}
if in.Enum != nil {
out.Enum = make([]JSON, len(in.Enum))
for i := range in.Enum {
out.Enum[i] = runtime.DeepCopyJSONValue(in.Enum[i])
}
}
if in.MaxProperties != nil {
in, out := &in.MaxProperties, &out.MaxProperties
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MinProperties != nil {
in, out := &in.MinProperties, &out.MinProperties
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.Required != nil {
in, out := &in.Required, &out.Required
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Items != nil {
in, out := &in.Items, &out.Items
if *in == nil {
*out = nil
} else {
*out = new(JSONSchemaPropsOrArray)
(*in).DeepCopyInto(*out)
}
}
if in.AllOf != nil {
in, out := &in.AllOf, &out.AllOf
*out = make([]JSONSchemaProps, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.OneOf != nil {
in, out := &in.OneOf, &out.OneOf
*out = make([]JSONSchemaProps, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.AnyOf != nil {
in, out := &in.AnyOf, &out.AnyOf
*out = make([]JSONSchemaProps, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Not != nil {
in, out := &in.Not, &out.Not
if *in == nil {
*out = nil
} else {
*out = new(JSONSchemaProps)
(*in).DeepCopyInto(*out)
}
}
if in.Properties != nil {
in, out := &in.Properties, &out.Properties
*out = make(map[string]JSONSchemaProps, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.AdditionalProperties != nil {
in, out := &in.AdditionalProperties, &out.AdditionalProperties
if *in == nil {
*out = nil
} else {
*out = new(JSONSchemaPropsOrBool)
(*in).DeepCopyInto(*out)
}
}
if in.PatternProperties != nil {
in, out := &in.PatternProperties, &out.PatternProperties
*out = make(map[string]JSONSchemaProps, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.Dependencies != nil {
in, out := &in.Dependencies, &out.Dependencies
*out = make(JSONSchemaDependencies, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.AdditionalItems != nil {
in, out := &in.AdditionalItems, &out.AdditionalItems
if *in == nil {
*out = nil
} else {
*out = new(JSONSchemaPropsOrBool)
(*in).DeepCopyInto(*out)
}
}
if in.Definitions != nil {
in, out := &in.Definitions, &out.Definitions
*out = make(JSONSchemaDefinitions, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.ExternalDocs != nil {
in, out := &in.ExternalDocs, &out.ExternalDocs
if *in == nil {
*out = nil
} else {
*out = new(ExternalDocumentation)
(*in).DeepCopyInto(*out)
}
}
return out
}

View File

@@ -1,21 +0,0 @@
/*
Copyright 2017 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.
*/
// +k8s:deepcopy-gen=package
// +groupName=apiextensions.k8s.io
// Package apiextensions is the internal version of the API.
package apiextensions // import "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"

View File

@@ -1,256 +0,0 @@
/*
Copyright 2017 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 apiextensions
import (
"fmt"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
// SetCRDCondition sets the status condition. It either overwrites the existing one or creates a new one.
func SetCRDCondition(crd *CustomResourceDefinition, newCondition CustomResourceDefinitionCondition) {
existingCondition := FindCRDCondition(crd, newCondition.Type)
if existingCondition == nil {
newCondition.LastTransitionTime = metav1.NewTime(time.Now())
crd.Status.Conditions = append(crd.Status.Conditions, newCondition)
return
}
if existingCondition.Status != newCondition.Status {
existingCondition.Status = newCondition.Status
existingCondition.LastTransitionTime = newCondition.LastTransitionTime
}
existingCondition.Reason = newCondition.Reason
existingCondition.Message = newCondition.Message
}
// RemoveCRDCondition removes the status condition.
func RemoveCRDCondition(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) {
newConditions := []CustomResourceDefinitionCondition{}
for _, condition := range crd.Status.Conditions {
if condition.Type != conditionType {
newConditions = append(newConditions, condition)
}
}
crd.Status.Conditions = newConditions
}
// FindCRDCondition returns the condition you're looking for or nil.
func FindCRDCondition(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) *CustomResourceDefinitionCondition {
for i := range crd.Status.Conditions {
if crd.Status.Conditions[i].Type == conditionType {
return &crd.Status.Conditions[i]
}
}
return nil
}
// IsCRDConditionTrue indicates if the condition is present and strictly true.
func IsCRDConditionTrue(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) bool {
return IsCRDConditionPresentAndEqual(crd, conditionType, ConditionTrue)
}
// IsCRDConditionFalse indicates if the condition is present and false.
func IsCRDConditionFalse(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) bool {
return IsCRDConditionPresentAndEqual(crd, conditionType, ConditionFalse)
}
// IsCRDConditionPresentAndEqual indicates if the condition is present and equal to the given status.
func IsCRDConditionPresentAndEqual(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType, status ConditionStatus) bool {
for _, condition := range crd.Status.Conditions {
if condition.Type == conditionType {
return condition.Status == status
}
}
return false
}
// IsCRDConditionEquivalent returns true if the lhs and rhs are equivalent except for times.
func IsCRDConditionEquivalent(lhs, rhs *CustomResourceDefinitionCondition) bool {
if lhs == nil && rhs == nil {
return true
}
if lhs == nil || rhs == nil {
return false
}
return lhs.Message == rhs.Message && lhs.Reason == rhs.Reason && lhs.Status == rhs.Status && lhs.Type == rhs.Type
}
// CRDHasFinalizer returns true if the finalizer is in the list.
func CRDHasFinalizer(crd *CustomResourceDefinition, needle string) bool {
for _, finalizer := range crd.Finalizers {
if finalizer == needle {
return true
}
}
return false
}
// CRDRemoveFinalizer removes the finalizer if present.
func CRDRemoveFinalizer(crd *CustomResourceDefinition, needle string) {
newFinalizers := []string{}
for _, finalizer := range crd.Finalizers {
if finalizer != needle {
newFinalizers = append(newFinalizers, finalizer)
}
}
crd.Finalizers = newFinalizers
}
// HasServedCRDVersion returns true if the given version is in the list of CRD's versions and the Served flag is set.
func HasServedCRDVersion(crd *CustomResourceDefinition, version string) bool {
for _, v := range crd.Spec.Versions {
if v.Name == version {
return v.Served
}
}
return false
}
// GetCRDStorageVersion returns the storage version for given CRD.
func GetCRDStorageVersion(crd *CustomResourceDefinition) (string, error) {
for _, v := range crd.Spec.Versions {
if v.Storage {
return v.Name, nil
}
}
// This should not happened if crd is valid
return "", fmt.Errorf("invalid CustomResourceDefinition, no storage version")
}
// IsStoredVersion returns whether the given version is the storage version of the CRD.
func IsStoredVersion(crd *CustomResourceDefinition, version string) bool {
for _, v := range crd.Status.StoredVersions {
if version == v {
return true
}
}
return false
}
// GetSchemaForVersion returns the validation schema for the given version or nil.
func GetSchemaForVersion(crd *CustomResourceDefinition, version string) (*CustomResourceValidation, error) {
if !HasPerVersionSchema(crd.Spec.Versions) {
return crd.Spec.Validation, nil
}
if crd.Spec.Validation != nil {
return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version schemas must be mutual exclusive", crd.Name, version)
}
for _, v := range crd.Spec.Versions {
if version == v.Name {
return v.Schema, nil
}
}
return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name)
}
// GetSubresourcesForVersion returns the subresources for given version or nil.
func GetSubresourcesForVersion(crd *CustomResourceDefinition, version string) (*CustomResourceSubresources, error) {
if !HasPerVersionSubresources(crd.Spec.Versions) {
return crd.Spec.Subresources, nil
}
if crd.Spec.Subresources != nil {
return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version subresources must be mutual exclusive", crd.Name, version)
}
for _, v := range crd.Spec.Versions {
if version == v.Name {
return v.Subresources, nil
}
}
return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name)
}
// GetColumnsForVersion returns the columns for given version or nil.
// NOTE: the newly logically-defaulted columns is not pointing to the original CRD object.
// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through
// the original CRD object instead.
func GetColumnsForVersion(crd *CustomResourceDefinition, version string) ([]CustomResourceColumnDefinition, error) {
if !HasPerVersionColumns(crd.Spec.Versions) {
return serveDefaultColumnsIfEmpty(crd.Spec.AdditionalPrinterColumns), nil
}
if len(crd.Spec.AdditionalPrinterColumns) > 0 {
return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version additionalPrinterColumns must be mutual exclusive", crd.Name, version)
}
for _, v := range crd.Spec.Versions {
if version == v.Name {
return serveDefaultColumnsIfEmpty(v.AdditionalPrinterColumns), nil
}
}
return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name)
}
// HasPerVersionSchema returns true if a CRD uses per-version schema.
func HasPerVersionSchema(versions []CustomResourceDefinitionVersion) bool {
for _, v := range versions {
if v.Schema != nil {
return true
}
}
return false
}
// HasPerVersionSubresources returns true if a CRD uses per-version subresources.
func HasPerVersionSubresources(versions []CustomResourceDefinitionVersion) bool {
for _, v := range versions {
if v.Subresources != nil {
return true
}
}
return false
}
// HasPerVersionColumns returns true if a CRD uses per-version columns.
func HasPerVersionColumns(versions []CustomResourceDefinitionVersion) bool {
for _, v := range versions {
if len(v.AdditionalPrinterColumns) > 0 {
return true
}
}
return false
}
// serveDefaultColumnsIfEmpty applies logically defaulting to columns, if the input columns is empty.
// NOTE: in this way, the newly logically-defaulted columns is not pointing to the original CRD object.
// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through
// the original CRD object instead.
func serveDefaultColumnsIfEmpty(columns []CustomResourceColumnDefinition) []CustomResourceColumnDefinition {
if len(columns) > 0 {
return columns
}
return []CustomResourceColumnDefinition{
{Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"},
}
}
// HasVersionServed returns true if given CRD has given version served.
func HasVersionServed(crd *CustomResourceDefinition, version string) bool {
for _, v := range crd.Spec.Versions {
if !v.Served || v.Name != version {
continue
}
return true
}
return false
}

View File

@@ -1,51 +0,0 @@
/*
Copyright 2017 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 apiextensions
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
const GroupName = "apiextensions.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns back a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&CustomResourceDefinition{},
&CustomResourceDefinitionList{},
)
return nil
}

View File

@@ -1,377 +0,0 @@
/*
Copyright 2017 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 apiextensions
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ConversionStrategyType describes different conversion types.
type ConversionStrategyType string
const (
// NoneConverter is a converter that only sets apiversion of the CR and leave everything else unchanged.
NoneConverter ConversionStrategyType = "None"
// WebhookConverter is a converter that calls to an external webhook to convert the CR.
WebhookConverter ConversionStrategyType = "Webhook"
)
// CustomResourceDefinitionSpec describes how a user wants their resource to appear
type CustomResourceDefinitionSpec struct {
// Group is the group this resource belongs in
Group string
// Version is the version this resource belongs in
// Should be always first item in Versions field if provided.
// Optional, but at least one of Version or Versions must be set.
// Deprecated: Please use `Versions`.
Version string
// Names are the names used to describe this custom resource
Names CustomResourceDefinitionNames
// Scope indicates whether this resource is cluster or namespace scoped. Default is namespaced
Scope ResourceScope
// Validation describes the validation methods for CustomResources
// Optional, the global validation schema for all versions.
// Top-level and per-version schemas are mutually exclusive.
// +optional
Validation *CustomResourceValidation
// Subresources describes the subresources for CustomResource
// Optional, the global subresources for all versions.
// Top-level and per-version subresources are mutually exclusive.
// +optional
Subresources *CustomResourceSubresources
// Versions is the list of all supported versions for this resource.
// If Version field is provided, this field is optional.
// Validation: All versions must use the same validation schema for now. i.e., top
// level Validation field is applied to all of these versions.
// Order: The version name will be used to compute the order.
// If the version string is "kube-like", it will sort above non "kube-like" version strings, which are ordered
// lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major version),
// then optionally the string "alpha" or "beta" and another number (the minor version). These are sorted first
// by GA > beta > alpha (where GA is a version with no suffix such as beta or alpha), and then by comparing
// major version, then minor version. An example sorted list of versions:
// v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10.
Versions []CustomResourceDefinitionVersion
// AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column.
// Optional, the global columns for all versions.
// Top-level and per-version columns are mutually exclusive.
// +optional
AdditionalPrinterColumns []CustomResourceColumnDefinition
// `conversion` defines conversion settings for the CRD.
Conversion *CustomResourceConversion
}
// CustomResourceConversion describes how to convert different versions of a CR.
type CustomResourceConversion struct {
// `strategy` specifies the conversion strategy. Allowed values are:
// - `None`: The converter only change the apiVersion and would not touch any other field in the CR.
// - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option.
Strategy ConversionStrategyType
// `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`.
WebhookClientConfig *WebhookClientConfig
// ConversionReviewVersions is an ordered list of preferred `ConversionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, conversion will fail for this object.
// If a persisted Webhook configuration specifies allowed versions and does not
// include any versions known to the API Server, calls to the webhook will fail.
// +optional
ConversionReviewVersions []string
}
// WebhookClientConfig contains the information to make a TLS
// connection with the webhook. It has the same field as admissionregistration.internal.WebhookClientConfig.
type WebhookClientConfig struct {
// `url` gives the location of the webhook, in standard URL form
// (`scheme://host:port/path`). Exactly one of `url` or `service`
// must be specified.
//
// The `host` should not refer to a service running in the cluster; use
// the `service` field instead. The host might be resolved via external
// DNS in some apiservers (e.g., `kube-apiserver` cannot resolve
// in-cluster DNS as that would be a layering violation). `host` may
// also be an IP address.
//
// Please note that using `localhost` or `127.0.0.1` as a `host` is
// risky unless you take great care to run this webhook on all hosts
// which run an apiserver which might need to make calls to this
// webhook. Such installs are likely to be non-portable, i.e., not easy
// to turn up in a new cluster.
//
// The scheme must be "https"; the URL must begin with "https://".
//
// A path is optional, and if present may be any string permissible in
// a URL. You may use the path to pass an arbitrary string to the
// webhook, for example, a cluster identifier.
//
// Attempting to use a user or basic auth e.g. "user:password@" is not
// allowed. Fragments ("#...") and query parameters ("?...") are not
// allowed, either.
//
// +optional
URL *string
// `service` is a reference to the service for this webhook. Either
// `service` or `url` must be specified.
//
// If the webhook is running within the cluster, then you should use `service`.
//
// Port 443 will be used if it is open, otherwise it is an error.
//
// +optional
Service *ServiceReference
// `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// If unspecified, system trust roots on the apiserver are used.
// +optional
CABundle []byte
}
// ServiceReference holds a reference to Service.legacy.k8s.io
type ServiceReference struct {
// `namespace` is the namespace of the service.
// Required
Namespace string
// `name` is the name of the service.
// Required
Name string
// `path` is an optional URL path which will be sent in any request to
// this service.
// +optional
Path *string
}
// CustomResourceDefinitionVersion describes a version for CRD.
type CustomResourceDefinitionVersion struct {
// Name is the version name, e.g. “v1”, “v2beta1”, etc.
Name string
// Served is a flag enabling/disabling this version from being served via REST APIs
Served bool
// Storage flags the version as storage version. There must be exactly one flagged
// as storage version.
Storage bool
// Schema describes the schema for CustomResource used in validation, pruning, and defaulting.
// Top-level and per-version schemas are mutually exclusive.
// Per-version schemas must not all be set to identical values (top-level validation schema should be used instead)
// This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
// +optional
Schema *CustomResourceValidation
// Subresources describes the subresources for CustomResource
// Top-level and per-version subresources are mutually exclusive.
// Per-version subresources must not all be set to identical values (top-level subresources should be used instead)
// This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
// +optional
Subresources *CustomResourceSubresources
// AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column.
// Top-level and per-version columns are mutually exclusive.
// Per-version columns must not all be set to identical values (top-level columns should be used instead)
// This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
// NOTE: CRDs created prior to 1.13 populated the top-level additionalPrinterColumns field by default. To apply an
// update that changes to per-version additionalPrinterColumns, the top-level additionalPrinterColumns field must
// be explicitly set to null
// +optional
AdditionalPrinterColumns []CustomResourceColumnDefinition
}
// CustomResourceColumnDefinition specifies a column for server side printing.
type CustomResourceColumnDefinition struct {
// name is a human readable name for the column.
Name string
// type is an OpenAPI type definition for this column.
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
Type string
// format is an optional OpenAPI type definition for this column. The 'name' format is applied
// to the primary identifier column to assist in clients identifying column is the resource name.
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
Format string
// description is a human readable description of this column.
Description string
// priority is an integer defining the relative importance of this column compared to others. Lower
// numbers are considered higher priority. Columns that may be omitted in limited space scenarios
// should be given a higher priority.
Priority int32
// JSONPath is a simple JSON path, i.e. without array notation.
JSONPath string
}
// CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition
type CustomResourceDefinitionNames struct {
// Plural is the plural name of the resource to serve. It must match the name of the CustomResourceDefinition-registration
// too: plural.group and it must be all lowercase.
Plural string
// Singular is the singular name of the resource. It must be all lowercase Defaults to lowercased <kind>
Singular string
// ShortNames are short names for the resource. It must be all lowercase.
ShortNames []string
// Kind is the serialized kind of the resource. It is normally CamelCase and singular.
Kind string
// ListKind is the serialized kind of the list for this resource. Defaults to <kind>List.
ListKind string
// Categories is a list of grouped resources custom resources belong to (e.g. 'all')
// +optional
Categories []string
}
// ResourceScope is an enum defining the different scopes available to a custom resource
type ResourceScope string
const (
ClusterScoped ResourceScope = "Cluster"
NamespaceScoped ResourceScope = "Namespaced"
)
type ConditionStatus string
// These are valid condition statuses. "ConditionTrue" means a resource is in the condition.
// "ConditionFalse" means a resource is not in the condition. "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
ConditionTrue ConditionStatus = "True"
ConditionFalse ConditionStatus = "False"
ConditionUnknown ConditionStatus = "Unknown"
)
// CustomResourceDefinitionConditionType is a valid value for CustomResourceDefinitionCondition.Type
type CustomResourceDefinitionConditionType string
const (
// Established means that the resource has become active. A resource is established when all names are
// accepted without a conflict for the first time. A resource stays established until deleted, even during
// a later NamesAccepted due to changed names. Note that not all names can be changed.
Established CustomResourceDefinitionConditionType = "Established"
// NamesAccepted means the names chosen for this CustomResourceDefinition do not conflict with others in
// the group and are therefore accepted.
NamesAccepted CustomResourceDefinitionConditionType = "NamesAccepted"
// Terminating means that the CustomResourceDefinition has been deleted and is cleaning up.
Terminating CustomResourceDefinitionConditionType = "Terminating"
)
// CustomResourceDefinitionCondition contains details for the current condition of this pod.
type CustomResourceDefinitionCondition struct {
// Type is the type of the condition.
Type CustomResourceDefinitionConditionType
// Status is the status of the condition.
// Can be True, False, Unknown.
Status ConditionStatus
// Last time the condition transitioned from one status to another.
// +optional
LastTransitionTime metav1.Time
// Unique, one-word, CamelCase reason for the condition's last transition.
// +optional
Reason string
// Human-readable message indicating details about last transition.
// +optional
Message string
}
// CustomResourceDefinitionStatus indicates the state of the CustomResourceDefinition
type CustomResourceDefinitionStatus struct {
// Conditions indicate state for particular aspects of a CustomResourceDefinition
Conditions []CustomResourceDefinitionCondition
// AcceptedNames are the names that are actually being used to serve discovery
// They may be different than the names in spec.
AcceptedNames CustomResourceDefinitionNames
// StoredVersions are all versions of CustomResources that were ever persisted. Tracking these
// versions allows a migration path for stored versions in etcd. The field is mutable
// so the migration controller can first finish a migration to another version (i.e.
// that no old objects are left in the storage), and then remove the rest of the
// versions from this list.
// None of the versions in this list can be removed from the spec.Versions field.
StoredVersions []string
}
// CustomResourceCleanupFinalizer is the name of the finalizer which will delete instances of
// a CustomResourceDefinition
const CustomResourceCleanupFinalizer = "customresourcecleanup.apiextensions.k8s.io"
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// CustomResourceDefinition represents a resource that should be exposed on the API server. Its name MUST be in the format
// <.spec.name>.<.spec.group>.
type CustomResourceDefinition struct {
metav1.TypeMeta
metav1.ObjectMeta
// Spec describes how the user wants the resources to appear
Spec CustomResourceDefinitionSpec
// Status indicates the actual state of the CustomResourceDefinition
Status CustomResourceDefinitionStatus
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// CustomResourceDefinitionList is a list of CustomResourceDefinition objects.
type CustomResourceDefinitionList struct {
metav1.TypeMeta
metav1.ListMeta
// Items individual CustomResourceDefinitions
Items []CustomResourceDefinition
}
// CustomResourceValidation is a list of validation methods for CustomResources.
type CustomResourceValidation struct {
// OpenAPIV3Schema is the OpenAPI v3 schema to be validated against.
OpenAPIV3Schema *JSONSchemaProps
}
// CustomResourceSubresources defines the status and scale subresources for CustomResources.
type CustomResourceSubresources struct {
// Status denotes the status subresource for CustomResources
Status *CustomResourceSubresourceStatus
// Scale denotes the scale subresource for CustomResources
Scale *CustomResourceSubresourceScale
}
// CustomResourceSubresourceStatus defines how to serve the status subresource for CustomResources.
// Status is represented by the `.status` JSON path inside of a CustomResource. When set,
// * exposes a /status subresource for the custom resource
// * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza
// * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza
type CustomResourceSubresourceStatus struct{}
// CustomResourceSubresourceScale defines how to serve the scale subresource for CustomResources.
type CustomResourceSubresourceScale struct {
// SpecReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Spec.Replicas.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .spec.
// If there is no value under the given path in the CustomResource, the /scale subresource will return an error on GET.
SpecReplicasPath string
// StatusReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Replicas.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .status.
// If there is no value under the given path in the CustomResource, the status replica value in the /scale subresource
// will default to 0.
StatusReplicasPath string
// LabelSelectorPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Selector.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .status.
// Must be set to work with HPA.
// If there is no value under the given path in the CustomResource, the status label selector value in the /scale
// subresource will default to the empty string.
// +optional
LabelSelectorPath *string
}

View File

@@ -1,97 +0,0 @@
/*
Copyright 2017 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 apiextensions
// JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).
type JSONSchemaProps struct {
ID string
Schema JSONSchemaURL
Ref *string
Description string
Type string
Nullable bool
Format string
Title string
Default *JSON
Maximum *float64
ExclusiveMaximum bool
Minimum *float64
ExclusiveMinimum bool
MaxLength *int64
MinLength *int64
Pattern string
MaxItems *int64
MinItems *int64
UniqueItems bool
MultipleOf *float64
Enum []JSON
MaxProperties *int64
MinProperties *int64
Required []string
Items *JSONSchemaPropsOrArray
AllOf []JSONSchemaProps
OneOf []JSONSchemaProps
AnyOf []JSONSchemaProps
Not *JSONSchemaProps
Properties map[string]JSONSchemaProps
AdditionalProperties *JSONSchemaPropsOrBool
PatternProperties map[string]JSONSchemaProps
Dependencies JSONSchemaDependencies
AdditionalItems *JSONSchemaPropsOrBool
Definitions JSONSchemaDefinitions
ExternalDocs *ExternalDocumentation
Example *JSON
}
// JSON represents any valid JSON value.
// These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.
type JSON interface{}
// JSONSchemaURL represents a schema url.
type JSONSchemaURL string
// JSONSchemaPropsOrArray represents a value that can either be a JSONSchemaProps
// or an array of JSONSchemaProps. Mainly here for serialization purposes.
type JSONSchemaPropsOrArray struct {
Schema *JSONSchemaProps
JSONSchemas []JSONSchemaProps
}
// JSONSchemaPropsOrBool represents JSONSchemaProps or a boolean value.
// Defaults to true for the boolean property.
type JSONSchemaPropsOrBool struct {
Allows bool
Schema *JSONSchemaProps
}
// JSONSchemaDependencies represent a dependencies property.
type JSONSchemaDependencies map[string]JSONSchemaPropsOrStringArray
// JSONSchemaPropsOrStringArray represents a JSONSchemaProps or a string array.
type JSONSchemaPropsOrStringArray struct {
Schema *JSONSchemaProps
Property []string
}
// JSONSchemaDefinitions contains the models explicitly defined in this spec.
type JSONSchemaDefinitions map[string]JSONSchemaProps
// ExternalDocumentation allows referencing an external resource for extended documentation.
type ExternalDocumentation struct {
Description string
URL string
}

View File

@@ -1,73 +0,0 @@
/*
Copyright 2017 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 v1beta1
import (
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
)
func addConversionFuncs(scheme *runtime.Scheme) error {
// Add non-generated conversion functions
err := scheme.AddConversionFuncs(
Convert_apiextensions_JSONSchemaProps_To_v1beta1_JSONSchemaProps,
Convert_apiextensions_JSON_To_v1beta1_JSON,
Convert_v1beta1_JSON_To_apiextensions_JSON,
)
if err != nil {
return err
}
return nil
}
func Convert_apiextensions_JSONSchemaProps_To_v1beta1_JSONSchemaProps(in *apiextensions.JSONSchemaProps, out *JSONSchemaProps, s conversion.Scope) error {
if err := autoConvert_apiextensions_JSONSchemaProps_To_v1beta1_JSONSchemaProps(in, out, s); err != nil {
return err
}
if in.Default != nil && *(in.Default) == nil {
out.Default = nil
}
if in.Example != nil && *(in.Example) == nil {
out.Example = nil
}
return nil
}
func Convert_apiextensions_JSON_To_v1beta1_JSON(in *apiextensions.JSON, out *JSON, s conversion.Scope) error {
raw, err := json.Marshal(*in)
if err != nil {
return err
}
out.Raw = raw
return nil
}
func Convert_v1beta1_JSON_To_apiextensions_JSON(in *JSON, out *apiextensions.JSON, s conversion.Scope) error {
if in != nil {
var i interface{}
if err := json.Unmarshal(in.Raw, &i); err != nil {
return err
}
*out = i
} else {
out = nil
}
return nil
}

View File

@@ -1,238 +0,0 @@
/*
Copyright 2017 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 v1beta1
// TODO: Update this after a tag is created for interface fields in DeepCopy
func (in *JSONSchemaProps) DeepCopy() *JSONSchemaProps {
if in == nil {
return nil
}
out := new(JSONSchemaProps)
*out = *in
if in.Ref != nil {
in, out := &in.Ref, &out.Ref
if *in == nil {
*out = nil
} else {
*out = new(string)
**out = **in
}
}
if in.Maximum != nil {
in, out := &in.Maximum, &out.Maximum
if *in == nil {
*out = nil
} else {
*out = new(float64)
**out = **in
}
}
if in.Minimum != nil {
in, out := &in.Minimum, &out.Minimum
if *in == nil {
*out = nil
} else {
*out = new(float64)
**out = **in
}
}
if in.MaxLength != nil {
in, out := &in.MaxLength, &out.MaxLength
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MinLength != nil {
in, out := &in.MinLength, &out.MinLength
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MaxItems != nil {
in, out := &in.MaxItems, &out.MaxItems
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MinItems != nil {
in, out := &in.MinItems, &out.MinItems
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MultipleOf != nil {
in, out := &in.MultipleOf, &out.MultipleOf
if *in == nil {
*out = nil
} else {
*out = new(float64)
**out = **in
}
}
if in.MaxProperties != nil {
in, out := &in.MaxProperties, &out.MaxProperties
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.MinProperties != nil {
in, out := &in.MinProperties, &out.MinProperties
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
if in.Required != nil {
in, out := &in.Required, &out.Required
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Items != nil {
in, out := &in.Items, &out.Items
if *in == nil {
*out = nil
} else {
*out = new(JSONSchemaPropsOrArray)
(*in).DeepCopyInto(*out)
}
}
if in.AllOf != nil {
in, out := &in.AllOf, &out.AllOf
*out = make([]JSONSchemaProps, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.OneOf != nil {
in, out := &in.OneOf, &out.OneOf
*out = make([]JSONSchemaProps, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.AnyOf != nil {
in, out := &in.AnyOf, &out.AnyOf
*out = make([]JSONSchemaProps, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Not != nil {
in, out := &in.Not, &out.Not
if *in == nil {
*out = nil
} else {
*out = new(JSONSchemaProps)
(*in).DeepCopyInto(*out)
}
}
if in.Properties != nil {
in, out := &in.Properties, &out.Properties
*out = make(map[string]JSONSchemaProps, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.AdditionalProperties != nil {
in, out := &in.AdditionalProperties, &out.AdditionalProperties
if *in == nil {
*out = nil
} else {
*out = new(JSONSchemaPropsOrBool)
(*in).DeepCopyInto(*out)
}
}
if in.PatternProperties != nil {
in, out := &in.PatternProperties, &out.PatternProperties
*out = make(map[string]JSONSchemaProps, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.Dependencies != nil {
in, out := &in.Dependencies, &out.Dependencies
*out = make(JSONSchemaDependencies, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.AdditionalItems != nil {
in, out := &in.AdditionalItems, &out.AdditionalItems
if *in == nil {
*out = nil
} else {
*out = new(JSONSchemaPropsOrBool)
(*in).DeepCopyInto(*out)
}
}
if in.Definitions != nil {
in, out := &in.Definitions, &out.Definitions
*out = make(JSONSchemaDefinitions, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.ExternalDocs != nil {
in, out := &in.ExternalDocs, &out.ExternalDocs
if *in == nil {
*out = nil
} else {
*out = new(ExternalDocumentation)
(*in).DeepCopyInto(*out)
}
}
return out
}

View File

@@ -1,84 +0,0 @@
/*
Copyright 2017 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 v1beta1
import (
"strings"
"k8s.io/apimachinery/pkg/runtime"
)
func addDefaultingFuncs(scheme *runtime.Scheme) error {
scheme.AddTypeDefaultingFunc(&CustomResourceDefinition{}, func(obj interface{}) { SetDefaults_CustomResourceDefinition(obj.(*CustomResourceDefinition)) })
// TODO figure out why I can't seem to get my defaulter generated
// return RegisterDefaults(scheme)
return nil
}
func SetDefaults_CustomResourceDefinition(obj *CustomResourceDefinition) {
SetDefaults_CustomResourceDefinitionSpec(&obj.Spec)
if len(obj.Status.StoredVersions) == 0 {
for _, v := range obj.Spec.Versions {
if v.Storage {
obj.Status.StoredVersions = append(obj.Status.StoredVersions, v.Name)
break
}
}
}
}
func SetDefaults_CustomResourceDefinitionSpec(obj *CustomResourceDefinitionSpec) {
if len(obj.Scope) == 0 {
obj.Scope = NamespaceScoped
}
if len(obj.Names.Singular) == 0 {
obj.Names.Singular = strings.ToLower(obj.Names.Kind)
}
if len(obj.Names.ListKind) == 0 && len(obj.Names.Kind) > 0 {
obj.Names.ListKind = obj.Names.Kind + "List"
}
// If there is no list of versions, create on using deprecated Version field.
if len(obj.Versions) == 0 && len(obj.Version) != 0 {
obj.Versions = []CustomResourceDefinitionVersion{{
Name: obj.Version,
Storage: true,
Served: true,
}}
}
// For backward compatibility set the version field to the first item in versions list.
if len(obj.Version) == 0 && len(obj.Versions) != 0 {
obj.Version = obj.Versions[0].Name
}
if obj.Conversion == nil {
obj.Conversion = &CustomResourceConversion{
Strategy: NoneConverter,
}
}
if obj.Conversion.Strategy == WebhookConverter && len(obj.Conversion.ConversionReviewVersions) == 0 {
obj.Conversion.ConversionReviewVersions = []string{SchemeGroupVersion.Version}
}
}
// hasPerVersionColumns returns true if a CRD uses per-version columns.
func hasPerVersionColumns(versions []CustomResourceDefinitionVersion) bool {
for _, v := range versions {
if len(v.AdditionalPrinterColumns) > 0 {
return true
}
}
return false
}

View File

@@ -1,25 +0,0 @@
/*
Copyright 2017 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.
*/
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:conversion-gen=k8s.io/apiextensions-apiserver/pkg/apis/apiextensions
// +k8s:defaulter-gen=TypeMeta
// +k8s:openapi-gen=true
// +groupName=apiextensions.k8s.io
// Package v1beta1 is the v1beta1 version of the API.
package v1beta1 // import "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"

File diff suppressed because it is too large Load Diff

View File

@@ -1,135 +0,0 @@
/*
Copyright 2017 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 v1beta1
import (
"errors"
"k8s.io/apimachinery/pkg/util/json"
)
var jsTrue = []byte("true")
var jsFalse = []byte("false")
func (s JSONSchemaPropsOrBool) MarshalJSON() ([]byte, error) {
if s.Schema != nil {
return json.Marshal(s.Schema)
}
if s.Schema == nil && !s.Allows {
return jsFalse, nil
}
return jsTrue, nil
}
func (s *JSONSchemaPropsOrBool) UnmarshalJSON(data []byte) error {
var nw JSONSchemaPropsOrBool
switch {
case len(data) == 0:
case data[0] == '{':
var sch JSONSchemaProps
if err := json.Unmarshal(data, &sch); err != nil {
return err
}
nw.Allows = true
nw.Schema = &sch
case len(data) == 4 && string(data) == "true":
nw.Allows = true
case len(data) == 5 && string(data) == "false":
nw.Allows = false
default:
return errors.New("boolean or JSON schema expected")
}
*s = nw
return nil
}
func (s JSONSchemaPropsOrStringArray) MarshalJSON() ([]byte, error) {
if len(s.Property) > 0 {
return json.Marshal(s.Property)
}
if s.Schema != nil {
return json.Marshal(s.Schema)
}
return []byte("null"), nil
}
func (s *JSONSchemaPropsOrStringArray) UnmarshalJSON(data []byte) error {
var first byte
if len(data) > 1 {
first = data[0]
}
var nw JSONSchemaPropsOrStringArray
if first == '{' {
var sch JSONSchemaProps
if err := json.Unmarshal(data, &sch); err != nil {
return err
}
nw.Schema = &sch
}
if first == '[' {
if err := json.Unmarshal(data, &nw.Property); err != nil {
return err
}
}
*s = nw
return nil
}
func (s JSONSchemaPropsOrArray) MarshalJSON() ([]byte, error) {
if len(s.JSONSchemas) > 0 {
return json.Marshal(s.JSONSchemas)
}
return json.Marshal(s.Schema)
}
func (s *JSONSchemaPropsOrArray) UnmarshalJSON(data []byte) error {
var nw JSONSchemaPropsOrArray
var first byte
if len(data) > 1 {
first = data[0]
}
if first == '{' {
var sch JSONSchemaProps
if err := json.Unmarshal(data, &sch); err != nil {
return err
}
nw.Schema = &sch
}
if first == '[' {
if err := json.Unmarshal(data, &nw.JSONSchemas); err != nil {
return err
}
}
*s = nw
return nil
}
func (s JSON) MarshalJSON() ([]byte, error) {
if len(s.Raw) > 0 {
return s.Raw, nil
}
return []byte("null"), nil
}
func (s *JSON) UnmarshalJSON(data []byte) error {
if len(data) > 0 && string(data) != "null" {
s.Raw = data
}
return nil
}

View File

@@ -1,62 +0,0 @@
/*
Copyright 2017 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 v1beta1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
const GroupName = "apiextensions.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns back a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addDefaultingFuncs, addConversionFuncs)
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
)
// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&CustomResourceDefinition{},
&CustomResourceDefinitionList{},
&ConversionReview{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addDefaultingFuncs, addConversionFuncs)
}

View File

@@ -1,438 +0,0 @@
/*
Copyright 2017 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 v1beta1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
)
// ConversionStrategyType describes different conversion types.
type ConversionStrategyType string
const (
// NoneConverter is a converter that only sets apiversion of the CR and leave everything else unchanged.
NoneConverter ConversionStrategyType = "None"
// WebhookConverter is a converter that calls to an external webhook to convert the CR.
WebhookConverter ConversionStrategyType = "Webhook"
)
// CustomResourceDefinitionSpec describes how a user wants their resource to appear
type CustomResourceDefinitionSpec struct {
// Group is the group this resource belongs in
Group string `json:"group" protobuf:"bytes,1,opt,name=group"`
// Version is the version this resource belongs in
// Should be always first item in Versions field if provided.
// Optional, but at least one of Version or Versions must be set.
// Deprecated: Please use `Versions`.
// +optional
Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"`
// Names are the names used to describe this custom resource
Names CustomResourceDefinitionNames `json:"names" protobuf:"bytes,3,opt,name=names"`
// Scope indicates whether this resource is cluster or namespace scoped. Default is namespaced
Scope ResourceScope `json:"scope" protobuf:"bytes,4,opt,name=scope,casttype=ResourceScope"`
// Validation describes the validation methods for CustomResources
// Optional, the global validation schema for all versions.
// Top-level and per-version schemas are mutually exclusive.
// +optional
Validation *CustomResourceValidation `json:"validation,omitempty" protobuf:"bytes,5,opt,name=validation"`
// Subresources describes the subresources for CustomResource
// Optional, the global subresources for all versions.
// Top-level and per-version subresources are mutually exclusive.
// +optional
Subresources *CustomResourceSubresources `json:"subresources,omitempty" protobuf:"bytes,6,opt,name=subresources"`
// Versions is the list of all supported versions for this resource.
// If Version field is provided, this field is optional.
// Validation: All versions must use the same validation schema for now. i.e., top
// level Validation field is applied to all of these versions.
// Order: The version name will be used to compute the order.
// If the version string is "kube-like", it will sort above non "kube-like" version strings, which are ordered
// lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major version),
// then optionally the string "alpha" or "beta" and another number (the minor version). These are sorted first
// by GA > beta > alpha (where GA is a version with no suffix such as beta or alpha), and then by comparing
// major version, then minor version. An example sorted list of versions:
// v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10.
// +optional
Versions []CustomResourceDefinitionVersion `json:"versions,omitempty" protobuf:"bytes,7,rep,name=versions"`
// AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column.
// Optional, the global columns for all versions.
// Top-level and per-version columns are mutually exclusive.
// +optional
AdditionalPrinterColumns []CustomResourceColumnDefinition `json:"additionalPrinterColumns,omitempty" protobuf:"bytes,8,rep,name=additionalPrinterColumns"`
// `conversion` defines conversion settings for the CRD.
// +optional
Conversion *CustomResourceConversion `json:"conversion,omitempty" protobuf:"bytes,9,opt,name=conversion"`
}
// CustomResourceConversion describes how to convert different versions of a CR.
type CustomResourceConversion struct {
// `strategy` specifies the conversion strategy. Allowed values are:
// - `None`: The converter only change the apiVersion and would not touch any other field in the CR.
// - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option.
Strategy ConversionStrategyType `json:"strategy" protobuf:"bytes,1,name=strategy"`
// `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`. This field is
// alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
// +optional
WebhookClientConfig *WebhookClientConfig `json:"webhookClientConfig,omitempty" protobuf:"bytes,2,name=webhookClientConfig"`
// ConversionReviewVersions is an ordered list of preferred `ConversionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, conversion will fail for this object.
// If a persisted Webhook configuration specifies allowed versions and does not
// include any versions known to the API Server, calls to the webhook will fail.
// Default to `['v1beta1']`.
// +optional
ConversionReviewVersions []string `json:"conversionReviewVersions,omitempty" protobuf:"bytes,3,rep,name=conversionReviewVersions"`
}
// WebhookClientConfig contains the information to make a TLS
// connection with the webhook. It has the same field as admissionregistration.v1beta1.WebhookClientConfig.
type WebhookClientConfig struct {
// `url` gives the location of the webhook, in standard URL form
// (`scheme://host:port/path`). Exactly one of `url` or `service`
// must be specified.
//
// The `host` should not refer to a service running in the cluster; use
// the `service` field instead. The host might be resolved via external
// DNS in some apiservers (e.g., `kube-apiserver` cannot resolve
// in-cluster DNS as that would be a layering violation). `host` may
// also be an IP address.
//
// Please note that using `localhost` or `127.0.0.1` as a `host` is
// risky unless you take great care to run this webhook on all hosts
// which run an apiserver which might need to make calls to this
// webhook. Such installs are likely to be non-portable, i.e., not easy
// to turn up in a new cluster.
//
// The scheme must be "https"; the URL must begin with "https://".
//
// A path is optional, and if present may be any string permissible in
// a URL. You may use the path to pass an arbitrary string to the
// webhook, for example, a cluster identifier.
//
// Attempting to use a user or basic auth e.g. "user:password@" is not
// allowed. Fragments ("#...") and query parameters ("?...") are not
// allowed, either.
//
// +optional
URL *string `json:"url,omitempty" protobuf:"bytes,3,opt,name=url"`
// `service` is a reference to the service for this webhook. Either
// `service` or `url` must be specified.
//
// If the webhook is running within the cluster, then you should use `service`.
//
// Port 443 will be used if it is open, otherwise it is an error.
//
// +optional
Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,1,opt,name=service"`
// `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// If unspecified, system trust roots on the apiserver are used.
// +optional
CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"`
}
// ServiceReference holds a reference to Service.legacy.k8s.io
type ServiceReference struct {
// `namespace` is the namespace of the service.
// Required
Namespace string `json:"namespace" protobuf:"bytes,1,opt,name=namespace"`
// `name` is the name of the service.
// Required
Name string `json:"name" protobuf:"bytes,2,opt,name=name"`
// `path` is an optional URL path which will be sent in any request to
// this service.
// +optional
Path *string `json:"path,omitempty" protobuf:"bytes,3,opt,name=path"`
}
// CustomResourceDefinitionVersion describes a version for CRD.
type CustomResourceDefinitionVersion struct {
// Name is the version name, e.g. “v1”, “v2beta1”, etc.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// Served is a flag enabling/disabling this version from being served via REST APIs
Served bool `json:"served" protobuf:"varint,2,opt,name=served"`
// Storage flags the version as storage version. There must be exactly one
// flagged as storage version.
Storage bool `json:"storage" protobuf:"varint,3,opt,name=storage"`
// Schema describes the schema for CustomResource used in validation, pruning, and defaulting.
// Top-level and per-version schemas are mutually exclusive.
// Per-version schemas must not all be set to identical values (top-level validation schema should be used instead)
// This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
// +optional
Schema *CustomResourceValidation `json:"schema,omitempty" protobuf:"bytes,4,opt,name=schema"`
// Subresources describes the subresources for CustomResource
// Top-level and per-version subresources are mutually exclusive.
// Per-version subresources must not all be set to identical values (top-level subresources should be used instead)
// This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
// +optional
Subresources *CustomResourceSubresources `json:"subresources,omitempty" protobuf:"bytes,5,opt,name=subresources"`
// AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column.
// Top-level and per-version columns are mutually exclusive.
// Per-version columns must not all be set to identical values (top-level columns should be used instead)
// This field is alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
// NOTE: CRDs created prior to 1.13 populated the top-level additionalPrinterColumns field by default. To apply an
// update that changes to per-version additionalPrinterColumns, the top-level additionalPrinterColumns field must
// be explicitly set to null
// +optional
AdditionalPrinterColumns []CustomResourceColumnDefinition `json:"additionalPrinterColumns,omitempty" protobuf:"bytes,6,rep,name=additionalPrinterColumns"`
}
// CustomResourceColumnDefinition specifies a column for server side printing.
type CustomResourceColumnDefinition struct {
// name is a human readable name for the column.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// type is an OpenAPI type definition for this column.
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
Type string `json:"type" protobuf:"bytes,2,opt,name=type"`
// format is an optional OpenAPI type definition for this column. The 'name' format is applied
// to the primary identifier column to assist in clients identifying column is the resource name.
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
// +optional
Format string `json:"format,omitempty" protobuf:"bytes,3,opt,name=format"`
// description is a human readable description of this column.
// +optional
Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"`
// priority is an integer defining the relative importance of this column compared to others. Lower
// numbers are considered higher priority. Columns that may be omitted in limited space scenarios
// should be given a higher priority.
// +optional
Priority int32 `json:"priority,omitempty" protobuf:"bytes,5,opt,name=priority"`
// JSONPath is a simple JSON path, i.e. with array notation.
JSONPath string `json:"JSONPath" protobuf:"bytes,6,opt,name=JSONPath"`
}
// CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition
type CustomResourceDefinitionNames struct {
// Plural is the plural name of the resource to serve. It must match the name of the CustomResourceDefinition-registration
// too: plural.group and it must be all lowercase.
Plural string `json:"plural" protobuf:"bytes,1,opt,name=plural"`
// Singular is the singular name of the resource. It must be all lowercase Defaults to lowercased <kind>
// +optional
Singular string `json:"singular,omitempty" protobuf:"bytes,2,opt,name=singular"`
// ShortNames are short names for the resource. It must be all lowercase.
// +optional
ShortNames []string `json:"shortNames,omitempty" protobuf:"bytes,3,opt,name=shortNames"`
// Kind is the serialized kind of the resource. It is normally CamelCase and singular.
Kind string `json:"kind" protobuf:"bytes,4,opt,name=kind"`
// ListKind is the serialized kind of the list for this resource. Defaults to <kind>List.
// +optional
ListKind string `json:"listKind,omitempty" protobuf:"bytes,5,opt,name=listKind"`
// Categories is a list of grouped resources custom resources belong to (e.g. 'all')
// +optional
Categories []string `json:"categories,omitempty" protobuf:"bytes,6,rep,name=categories"`
}
// ResourceScope is an enum defining the different scopes available to a custom resource
type ResourceScope string
const (
ClusterScoped ResourceScope = "Cluster"
NamespaceScoped ResourceScope = "Namespaced"
)
type ConditionStatus string
// These are valid condition statuses. "ConditionTrue" means a resource is in the condition.
// "ConditionFalse" means a resource is not in the condition. "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
ConditionTrue ConditionStatus = "True"
ConditionFalse ConditionStatus = "False"
ConditionUnknown ConditionStatus = "Unknown"
)
// CustomResourceDefinitionConditionType is a valid value for CustomResourceDefinitionCondition.Type
type CustomResourceDefinitionConditionType string
const (
// Established means that the resource has become active. A resource is established when all names are
// accepted without a conflict for the first time. A resource stays established until deleted, even during
// a later NamesAccepted due to changed names. Note that not all names can be changed.
Established CustomResourceDefinitionConditionType = "Established"
// NamesAccepted means the names chosen for this CustomResourceDefinition do not conflict with others in
// the group and are therefore accepted.
NamesAccepted CustomResourceDefinitionConditionType = "NamesAccepted"
// Terminating means that the CustomResourceDefinition has been deleted and is cleaning up.
Terminating CustomResourceDefinitionConditionType = "Terminating"
)
// CustomResourceDefinitionCondition contains details for the current condition of this pod.
type CustomResourceDefinitionCondition struct {
// Type is the type of the condition.
Type CustomResourceDefinitionConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=CustomResourceDefinitionConditionType"`
// Status is the status of the condition.
// Can be True, False, Unknown.
Status ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=ConditionStatus"`
// Last time the condition transitioned from one status to another.
// +optional
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"`
// Unique, one-word, CamelCase reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
// Human-readable message indicating details about last transition.
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
}
// CustomResourceDefinitionStatus indicates the state of the CustomResourceDefinition
type CustomResourceDefinitionStatus struct {
// Conditions indicate state for particular aspects of a CustomResourceDefinition
Conditions []CustomResourceDefinitionCondition `json:"conditions" protobuf:"bytes,1,opt,name=conditions"`
// AcceptedNames are the names that are actually being used to serve discovery
// They may be different than the names in spec.
AcceptedNames CustomResourceDefinitionNames `json:"acceptedNames" protobuf:"bytes,2,opt,name=acceptedNames"`
// StoredVersions are all versions of CustomResources that were ever persisted. Tracking these
// versions allows a migration path for stored versions in etcd. The field is mutable
// so the migration controller can first finish a migration to another version (i.e.
// that no old objects are left in the storage), and then remove the rest of the
// versions from this list.
// None of the versions in this list can be removed from the spec.Versions field.
StoredVersions []string `json:"storedVersions" protobuf:"bytes,3,rep,name=storedVersions"`
}
// CustomResourceCleanupFinalizer is the name of the finalizer which will delete instances of
// a CustomResourceDefinition
const CustomResourceCleanupFinalizer = "customresourcecleanup.apiextensions.k8s.io"
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// CustomResourceDefinition represents a resource that should be exposed on the API server. Its name MUST be in the format
// <.spec.name>.<.spec.group>.
type CustomResourceDefinition struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Spec describes how the user wants the resources to appear
Spec CustomResourceDefinitionSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
// Status indicates the actual state of the CustomResourceDefinition
// +optional
Status CustomResourceDefinitionStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// CustomResourceDefinitionList is a list of CustomResourceDefinition objects.
type CustomResourceDefinitionList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Items individual CustomResourceDefinitions
Items []CustomResourceDefinition `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// CustomResourceValidation is a list of validation methods for CustomResources.
type CustomResourceValidation struct {
// OpenAPIV3Schema is the OpenAPI v3 schema to be validated against.
// +optional
OpenAPIV3Schema *JSONSchemaProps `json:"openAPIV3Schema,omitempty" protobuf:"bytes,1,opt,name=openAPIV3Schema"`
}
// CustomResourceSubresources defines the status and scale subresources for CustomResources.
type CustomResourceSubresources struct {
// Status denotes the status subresource for CustomResources
// +optional
Status *CustomResourceSubresourceStatus `json:"status,omitempty" protobuf:"bytes,1,opt,name=status"`
// Scale denotes the scale subresource for CustomResources
// +optional
Scale *CustomResourceSubresourceScale `json:"scale,omitempty" protobuf:"bytes,2,opt,name=scale"`
}
// CustomResourceSubresourceStatus defines how to serve the status subresource for CustomResources.
// Status is represented by the `.status` JSON path inside of a CustomResource. When set,
// * exposes a /status subresource for the custom resource
// * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza
// * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza
type CustomResourceSubresourceStatus struct{}
// CustomResourceSubresourceScale defines how to serve the scale subresource for CustomResources.
type CustomResourceSubresourceScale struct {
// SpecReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Spec.Replicas.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .spec.
// If there is no value under the given path in the CustomResource, the /scale subresource will return an error on GET.
SpecReplicasPath string `json:"specReplicasPath" protobuf:"bytes,1,name=specReplicasPath"`
// StatusReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Replicas.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .status.
// If there is no value under the given path in the CustomResource, the status replica value in the /scale subresource
// will default to 0.
StatusReplicasPath string `json:"statusReplicasPath" protobuf:"bytes,2,opt,name=statusReplicasPath"`
// LabelSelectorPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Selector.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .status.
// Must be set to work with HPA.
// If there is no value under the given path in the CustomResource, the status label selector value in the /scale
// subresource will default to the empty string.
// +optional
LabelSelectorPath *string `json:"labelSelectorPath,omitempty" protobuf:"bytes,3,opt,name=labelSelectorPath"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ConversionReview describes a conversion request/response.
type ConversionReview struct {
metav1.TypeMeta `json:",inline"`
// `request` describes the attributes for the conversion request.
// +optional
Request *ConversionRequest `json:"request,omitempty" protobuf:"bytes,1,opt,name=request"`
// `response` describes the attributes for the conversion response.
// +optional
Response *ConversionResponse `json:"response,omitempty" protobuf:"bytes,2,opt,name=response"`
}
// ConversionRequest describes the conversion request parameters.
type ConversionRequest struct {
// `uid` is an identifier for the individual request/response. It allows us to distinguish instances of requests which are
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
UID types.UID `json:"uid" protobuf:"bytes,1,name=uid"`
// `desiredAPIVersion` is the version to convert given objects to. e.g. "myapi.example.com/v1"
DesiredAPIVersion string `json:"desiredAPIVersion" protobuf:"bytes,2,name=desiredAPIVersion"`
// `objects` is the list of CR objects to be converted.
Objects []runtime.RawExtension `json:"objects" protobuf:"bytes,3,rep,name=objects"`
}
// ConversionResponse describes a conversion response.
type ConversionResponse struct {
// `uid` is an identifier for the individual request/response.
// This should be copied over from the corresponding AdmissionRequest.
UID types.UID `json:"uid" protobuf:"bytes,1,name=uid"`
// `convertedObjects` is the list of converted version of `request.objects` if the `result` is successful otherwise empty.
// The webhook is expected to set apiVersion of these objects to the ConversionRequest.desiredAPIVersion. The list
// must also has the same size as input list with the same objects in the same order(i.e. equal UIDs and object meta)
ConvertedObjects []runtime.RawExtension `json:"convertedObjects" protobuf:"bytes,2,rep,name=convertedObjects"`
// `result` contains the result of conversion with extra details if the conversion failed. `result.status` determines if
// the conversion failed or succeeded. The `result.status` field is required and represent the success or failure of the
// conversion. A successful conversion must set `result.status` to `Success`. A failed conversion must set
// `result.status` to `Failure` and provide more details in `result.message` and return http status 200. The `result.message`
// will be used to construct an error message for the end user.
Result metav1.Status `json:"result" protobuf:"bytes,3,name=result"`
}

View File

@@ -1,151 +0,0 @@
/*
Copyright 2017 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 v1beta1
// JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).
type JSONSchemaProps struct {
ID string `json:"id,omitempty" protobuf:"bytes,1,opt,name=id"`
Schema JSONSchemaURL `json:"$schema,omitempty" protobuf:"bytes,2,opt,name=schema"`
Ref *string `json:"$ref,omitempty" protobuf:"bytes,3,opt,name=ref"`
Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"`
Type string `json:"type,omitempty" protobuf:"bytes,5,opt,name=type"`
Format string `json:"format,omitempty" protobuf:"bytes,6,opt,name=format"`
Title string `json:"title,omitempty" protobuf:"bytes,7,opt,name=title"`
Default *JSON `json:"default,omitempty" protobuf:"bytes,8,opt,name=default"`
Maximum *float64 `json:"maximum,omitempty" protobuf:"bytes,9,opt,name=maximum"`
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty" protobuf:"bytes,10,opt,name=exclusiveMaximum"`
Minimum *float64 `json:"minimum,omitempty" protobuf:"bytes,11,opt,name=minimum"`
ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty" protobuf:"bytes,12,opt,name=exclusiveMinimum"`
MaxLength *int64 `json:"maxLength,omitempty" protobuf:"bytes,13,opt,name=maxLength"`
MinLength *int64 `json:"minLength,omitempty" protobuf:"bytes,14,opt,name=minLength"`
Pattern string `json:"pattern,omitempty" protobuf:"bytes,15,opt,name=pattern"`
MaxItems *int64 `json:"maxItems,omitempty" protobuf:"bytes,16,opt,name=maxItems"`
MinItems *int64 `json:"minItems,omitempty" protobuf:"bytes,17,opt,name=minItems"`
UniqueItems bool `json:"uniqueItems,omitempty" protobuf:"bytes,18,opt,name=uniqueItems"`
MultipleOf *float64 `json:"multipleOf,omitempty" protobuf:"bytes,19,opt,name=multipleOf"`
Enum []JSON `json:"enum,omitempty" protobuf:"bytes,20,rep,name=enum"`
MaxProperties *int64 `json:"maxProperties,omitempty" protobuf:"bytes,21,opt,name=maxProperties"`
MinProperties *int64 `json:"minProperties,omitempty" protobuf:"bytes,22,opt,name=minProperties"`
Required []string `json:"required,omitempty" protobuf:"bytes,23,rep,name=required"`
Items *JSONSchemaPropsOrArray `json:"items,omitempty" protobuf:"bytes,24,opt,name=items"`
AllOf []JSONSchemaProps `json:"allOf,omitempty" protobuf:"bytes,25,rep,name=allOf"`
OneOf []JSONSchemaProps `json:"oneOf,omitempty" protobuf:"bytes,26,rep,name=oneOf"`
AnyOf []JSONSchemaProps `json:"anyOf,omitempty" protobuf:"bytes,27,rep,name=anyOf"`
Not *JSONSchemaProps `json:"not,omitempty" protobuf:"bytes,28,opt,name=not"`
Properties map[string]JSONSchemaProps `json:"properties,omitempty" protobuf:"bytes,29,rep,name=properties"`
AdditionalProperties *JSONSchemaPropsOrBool `json:"additionalProperties,omitempty" protobuf:"bytes,30,opt,name=additionalProperties"`
PatternProperties map[string]JSONSchemaProps `json:"patternProperties,omitempty" protobuf:"bytes,31,rep,name=patternProperties"`
Dependencies JSONSchemaDependencies `json:"dependencies,omitempty" protobuf:"bytes,32,opt,name=dependencies"`
AdditionalItems *JSONSchemaPropsOrBool `json:"additionalItems,omitempty" protobuf:"bytes,33,opt,name=additionalItems"`
Definitions JSONSchemaDefinitions `json:"definitions,omitempty" protobuf:"bytes,34,opt,name=definitions"`
ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty" protobuf:"bytes,35,opt,name=externalDocs"`
Example *JSON `json:"example,omitempty" protobuf:"bytes,36,opt,name=example"`
Nullable bool `json:"nullable,omitempty" protobuf:"bytes,37,opt,name=nullable"`
}
// JSON represents any valid JSON value.
// These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.
type JSON struct {
Raw []byte `protobuf:"bytes,1,opt,name=raw"`
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ JSON) OpenAPISchemaType() []string {
// TODO: return actual types when anyOf is supported
return nil
}
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ JSON) OpenAPISchemaFormat() string { return "" }
// JSONSchemaURL represents a schema url.
type JSONSchemaURL string
// JSONSchemaPropsOrArray represents a value that can either be a JSONSchemaProps
// or an array of JSONSchemaProps. Mainly here for serialization purposes.
type JSONSchemaPropsOrArray struct {
Schema *JSONSchemaProps `protobuf:"bytes,1,opt,name=schema"`
JSONSchemas []JSONSchemaProps `protobuf:"bytes,2,rep,name=jSONSchemas"`
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ JSONSchemaPropsOrArray) OpenAPISchemaType() []string {
// TODO: return actual types when anyOf is supported
return nil
}
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ JSONSchemaPropsOrArray) OpenAPISchemaFormat() string { return "" }
// JSONSchemaPropsOrBool represents JSONSchemaProps or a boolean value.
// Defaults to true for the boolean property.
type JSONSchemaPropsOrBool struct {
Allows bool `protobuf:"varint,1,opt,name=allows"`
Schema *JSONSchemaProps `protobuf:"bytes,2,opt,name=schema"`
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ JSONSchemaPropsOrBool) OpenAPISchemaType() []string {
// TODO: return actual types when anyOf is supported
return nil
}
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ JSONSchemaPropsOrBool) OpenAPISchemaFormat() string { return "" }
// JSONSchemaDependencies represent a dependencies property.
type JSONSchemaDependencies map[string]JSONSchemaPropsOrStringArray
// JSONSchemaPropsOrStringArray represents a JSONSchemaProps or a string array.
type JSONSchemaPropsOrStringArray struct {
Schema *JSONSchemaProps `protobuf:"bytes,1,opt,name=schema"`
Property []string `protobuf:"bytes,2,rep,name=property"`
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ JSONSchemaPropsOrStringArray) OpenAPISchemaType() []string {
// TODO: return actual types when anyOf is supported
return nil
}
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ JSONSchemaPropsOrStringArray) OpenAPISchemaFormat() string { return "" }
// JSONSchemaDefinitions contains the models explicitly defined in this spec.
type JSONSchemaDefinitions map[string]JSONSchemaProps
// ExternalDocumentation allows referencing an external resource for extended documentation.
type ExternalDocumentation struct {
Description string `json:"description,omitempty" protobuf:"bytes,1,opt,name=description"`
URL string `json:"url,omitempty" protobuf:"bytes,2,opt,name=url"`
}

View File

@@ -1,652 +0,0 @@
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1beta1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConversionRequest) DeepCopyInto(out *ConversionRequest) {
*out = *in
if in.Objects != nil {
in, out := &in.Objects, &out.Objects
*out = make([]runtime.RawExtension, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionRequest.
func (in *ConversionRequest) DeepCopy() *ConversionRequest {
if in == nil {
return nil
}
out := new(ConversionRequest)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConversionResponse) DeepCopyInto(out *ConversionResponse) {
*out = *in
if in.ConvertedObjects != nil {
in, out := &in.ConvertedObjects, &out.ConvertedObjects
*out = make([]runtime.RawExtension, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
in.Result.DeepCopyInto(&out.Result)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionResponse.
func (in *ConversionResponse) DeepCopy() *ConversionResponse {
if in == nil {
return nil
}
out := new(ConversionResponse)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConversionReview) DeepCopyInto(out *ConversionReview) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.Request != nil {
in, out := &in.Request, &out.Request
*out = new(ConversionRequest)
(*in).DeepCopyInto(*out)
}
if in.Response != nil {
in, out := &in.Response, &out.Response
*out = new(ConversionResponse)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionReview.
func (in *ConversionReview) DeepCopy() *ConversionReview {
if in == nil {
return nil
}
out := new(ConversionReview)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ConversionReview) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceColumnDefinition) DeepCopyInto(out *CustomResourceColumnDefinition) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceColumnDefinition.
func (in *CustomResourceColumnDefinition) DeepCopy() *CustomResourceColumnDefinition {
if in == nil {
return nil
}
out := new(CustomResourceColumnDefinition)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceConversion) DeepCopyInto(out *CustomResourceConversion) {
*out = *in
if in.WebhookClientConfig != nil {
in, out := &in.WebhookClientConfig, &out.WebhookClientConfig
*out = new(WebhookClientConfig)
(*in).DeepCopyInto(*out)
}
if in.ConversionReviewVersions != nil {
in, out := &in.ConversionReviewVersions, &out.ConversionReviewVersions
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceConversion.
func (in *CustomResourceConversion) DeepCopy() *CustomResourceConversion {
if in == nil {
return nil
}
out := new(CustomResourceConversion)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinition) DeepCopyInto(out *CustomResourceDefinition) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinition.
func (in *CustomResourceDefinition) DeepCopy() *CustomResourceDefinition {
if in == nil {
return nil
}
out := new(CustomResourceDefinition)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *CustomResourceDefinition) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionCondition) DeepCopyInto(out *CustomResourceDefinitionCondition) {
*out = *in
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionCondition.
func (in *CustomResourceDefinitionCondition) DeepCopy() *CustomResourceDefinitionCondition {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionCondition)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionList) DeepCopyInto(out *CustomResourceDefinitionList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]CustomResourceDefinition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionList.
func (in *CustomResourceDefinitionList) DeepCopy() *CustomResourceDefinitionList {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *CustomResourceDefinitionList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionNames) DeepCopyInto(out *CustomResourceDefinitionNames) {
*out = *in
if in.ShortNames != nil {
in, out := &in.ShortNames, &out.ShortNames
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Categories != nil {
in, out := &in.Categories, &out.Categories
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionNames.
func (in *CustomResourceDefinitionNames) DeepCopy() *CustomResourceDefinitionNames {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionNames)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionSpec) DeepCopyInto(out *CustomResourceDefinitionSpec) {
*out = *in
in.Names.DeepCopyInto(&out.Names)
if in.Validation != nil {
in, out := &in.Validation, &out.Validation
*out = new(CustomResourceValidation)
(*in).DeepCopyInto(*out)
}
if in.Subresources != nil {
in, out := &in.Subresources, &out.Subresources
*out = new(CustomResourceSubresources)
(*in).DeepCopyInto(*out)
}
if in.Versions != nil {
in, out := &in.Versions, &out.Versions
*out = make([]CustomResourceDefinitionVersion, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.AdditionalPrinterColumns != nil {
in, out := &in.AdditionalPrinterColumns, &out.AdditionalPrinterColumns
*out = make([]CustomResourceColumnDefinition, len(*in))
copy(*out, *in)
}
if in.Conversion != nil {
in, out := &in.Conversion, &out.Conversion
*out = new(CustomResourceConversion)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionSpec.
func (in *CustomResourceDefinitionSpec) DeepCopy() *CustomResourceDefinitionSpec {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionStatus) DeepCopyInto(out *CustomResourceDefinitionStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]CustomResourceDefinitionCondition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
in.AcceptedNames.DeepCopyInto(&out.AcceptedNames)
if in.StoredVersions != nil {
in, out := &in.StoredVersions, &out.StoredVersions
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionStatus.
func (in *CustomResourceDefinitionStatus) DeepCopy() *CustomResourceDefinitionStatus {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionVersion) DeepCopyInto(out *CustomResourceDefinitionVersion) {
*out = *in
if in.Schema != nil {
in, out := &in.Schema, &out.Schema
*out = new(CustomResourceValidation)
(*in).DeepCopyInto(*out)
}
if in.Subresources != nil {
in, out := &in.Subresources, &out.Subresources
*out = new(CustomResourceSubresources)
(*in).DeepCopyInto(*out)
}
if in.AdditionalPrinterColumns != nil {
in, out := &in.AdditionalPrinterColumns, &out.AdditionalPrinterColumns
*out = make([]CustomResourceColumnDefinition, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionVersion.
func (in *CustomResourceDefinitionVersion) DeepCopy() *CustomResourceDefinitionVersion {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionVersion)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceSubresourceScale) DeepCopyInto(out *CustomResourceSubresourceScale) {
*out = *in
if in.LabelSelectorPath != nil {
in, out := &in.LabelSelectorPath, &out.LabelSelectorPath
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresourceScale.
func (in *CustomResourceSubresourceScale) DeepCopy() *CustomResourceSubresourceScale {
if in == nil {
return nil
}
out := new(CustomResourceSubresourceScale)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceSubresourceStatus) DeepCopyInto(out *CustomResourceSubresourceStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresourceStatus.
func (in *CustomResourceSubresourceStatus) DeepCopy() *CustomResourceSubresourceStatus {
if in == nil {
return nil
}
out := new(CustomResourceSubresourceStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceSubresources) DeepCopyInto(out *CustomResourceSubresources) {
*out = *in
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(CustomResourceSubresourceStatus)
**out = **in
}
if in.Scale != nil {
in, out := &in.Scale, &out.Scale
*out = new(CustomResourceSubresourceScale)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresources.
func (in *CustomResourceSubresources) DeepCopy() *CustomResourceSubresources {
if in == nil {
return nil
}
out := new(CustomResourceSubresources)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceValidation) DeepCopyInto(out *CustomResourceValidation) {
*out = *in
if in.OpenAPIV3Schema != nil {
in, out := &in.OpenAPIV3Schema, &out.OpenAPIV3Schema
*out = (*in).DeepCopy()
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceValidation.
func (in *CustomResourceValidation) DeepCopy() *CustomResourceValidation {
if in == nil {
return nil
}
out := new(CustomResourceValidation)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalDocumentation) DeepCopyInto(out *ExternalDocumentation) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalDocumentation.
func (in *ExternalDocumentation) DeepCopy() *ExternalDocumentation {
if in == nil {
return nil
}
out := new(ExternalDocumentation)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSON) DeepCopyInto(out *JSON) {
*out = *in
if in.Raw != nil {
in, out := &in.Raw, &out.Raw
*out = make([]byte, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSON.
func (in *JSON) DeepCopy() *JSON {
if in == nil {
return nil
}
out := new(JSON)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in JSONSchemaDefinitions) DeepCopyInto(out *JSONSchemaDefinitions) {
{
in := &in
*out = make(JSONSchemaDefinitions, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaDefinitions.
func (in JSONSchemaDefinitions) DeepCopy() JSONSchemaDefinitions {
if in == nil {
return nil
}
out := new(JSONSchemaDefinitions)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in JSONSchemaDependencies) DeepCopyInto(out *JSONSchemaDependencies) {
{
in := &in
*out = make(JSONSchemaDependencies, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaDependencies.
func (in JSONSchemaDependencies) DeepCopy() JSONSchemaDependencies {
if in == nil {
return nil
}
out := new(JSONSchemaDependencies)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONSchemaProps) DeepCopyInto(out *JSONSchemaProps) {
clone := in.DeepCopy()
*out = *clone
return
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONSchemaPropsOrArray) DeepCopyInto(out *JSONSchemaPropsOrArray) {
*out = *in
if in.Schema != nil {
in, out := &in.Schema, &out.Schema
*out = (*in).DeepCopy()
}
if in.JSONSchemas != nil {
in, out := &in.JSONSchemas, &out.JSONSchemas
*out = make([]JSONSchemaProps, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaPropsOrArray.
func (in *JSONSchemaPropsOrArray) DeepCopy() *JSONSchemaPropsOrArray {
if in == nil {
return nil
}
out := new(JSONSchemaPropsOrArray)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONSchemaPropsOrBool) DeepCopyInto(out *JSONSchemaPropsOrBool) {
*out = *in
if in.Schema != nil {
in, out := &in.Schema, &out.Schema
*out = (*in).DeepCopy()
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaPropsOrBool.
func (in *JSONSchemaPropsOrBool) DeepCopy() *JSONSchemaPropsOrBool {
if in == nil {
return nil
}
out := new(JSONSchemaPropsOrBool)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONSchemaPropsOrStringArray) DeepCopyInto(out *JSONSchemaPropsOrStringArray) {
*out = *in
if in.Schema != nil {
in, out := &in.Schema, &out.Schema
*out = (*in).DeepCopy()
}
if in.Property != nil {
in, out := &in.Property, &out.Property
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaPropsOrStringArray.
func (in *JSONSchemaPropsOrStringArray) DeepCopy() *JSONSchemaPropsOrStringArray {
if in == nil {
return nil
}
out := new(JSONSchemaPropsOrStringArray)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceReference) DeepCopyInto(out *ServiceReference) {
*out = *in
if in.Path != nil {
in, out := &in.Path, &out.Path
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceReference.
func (in *ServiceReference) DeepCopy() *ServiceReference {
if in == nil {
return nil
}
out := new(ServiceReference)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WebhookClientConfig) DeepCopyInto(out *WebhookClientConfig) {
*out = *in
if in.URL != nil {
in, out := &in.URL, &out.URL
*out = new(string)
**out = **in
}
if in.Service != nil {
in, out := &in.Service, &out.Service
*out = new(ServiceReference)
(*in).DeepCopyInto(*out)
}
if in.CABundle != nil {
in, out := &in.CABundle, &out.CABundle
*out = make([]byte, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookClientConfig.
func (in *WebhookClientConfig) DeepCopy() *WebhookClientConfig {
if in == nil {
return nil
}
out := new(WebhookClientConfig)
in.DeepCopyInto(out)
return out
}

View File

@@ -1,48 +0,0 @@
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by defaulter-gen. DO NOT EDIT.
package v1beta1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// RegisterDefaults adds defaulters functions to the given scheme.
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
scheme.AddTypeDefaultingFunc(&CustomResourceDefinition{}, func(obj interface{}) { SetObjectDefaults_CustomResourceDefinition(obj.(*CustomResourceDefinition)) })
scheme.AddTypeDefaultingFunc(&CustomResourceDefinitionList{}, func(obj interface{}) {
SetObjectDefaults_CustomResourceDefinitionList(obj.(*CustomResourceDefinitionList))
})
return nil
}
func SetObjectDefaults_CustomResourceDefinition(in *CustomResourceDefinition) {
SetDefaults_CustomResourceDefinition(in)
SetDefaults_CustomResourceDefinitionSpec(&in.Spec)
}
func SetObjectDefaults_CustomResourceDefinitionList(in *CustomResourceDefinitionList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_CustomResourceDefinition(a)
}
}

View File

@@ -1,549 +0,0 @@
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package apiextensions
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceColumnDefinition) DeepCopyInto(out *CustomResourceColumnDefinition) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceColumnDefinition.
func (in *CustomResourceColumnDefinition) DeepCopy() *CustomResourceColumnDefinition {
if in == nil {
return nil
}
out := new(CustomResourceColumnDefinition)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceConversion) DeepCopyInto(out *CustomResourceConversion) {
*out = *in
if in.WebhookClientConfig != nil {
in, out := &in.WebhookClientConfig, &out.WebhookClientConfig
*out = new(WebhookClientConfig)
(*in).DeepCopyInto(*out)
}
if in.ConversionReviewVersions != nil {
in, out := &in.ConversionReviewVersions, &out.ConversionReviewVersions
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceConversion.
func (in *CustomResourceConversion) DeepCopy() *CustomResourceConversion {
if in == nil {
return nil
}
out := new(CustomResourceConversion)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinition) DeepCopyInto(out *CustomResourceDefinition) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinition.
func (in *CustomResourceDefinition) DeepCopy() *CustomResourceDefinition {
if in == nil {
return nil
}
out := new(CustomResourceDefinition)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *CustomResourceDefinition) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionCondition) DeepCopyInto(out *CustomResourceDefinitionCondition) {
*out = *in
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionCondition.
func (in *CustomResourceDefinitionCondition) DeepCopy() *CustomResourceDefinitionCondition {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionCondition)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionList) DeepCopyInto(out *CustomResourceDefinitionList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]CustomResourceDefinition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionList.
func (in *CustomResourceDefinitionList) DeepCopy() *CustomResourceDefinitionList {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *CustomResourceDefinitionList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionNames) DeepCopyInto(out *CustomResourceDefinitionNames) {
*out = *in
if in.ShortNames != nil {
in, out := &in.ShortNames, &out.ShortNames
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Categories != nil {
in, out := &in.Categories, &out.Categories
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionNames.
func (in *CustomResourceDefinitionNames) DeepCopy() *CustomResourceDefinitionNames {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionNames)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionSpec) DeepCopyInto(out *CustomResourceDefinitionSpec) {
*out = *in
in.Names.DeepCopyInto(&out.Names)
if in.Validation != nil {
in, out := &in.Validation, &out.Validation
*out = new(CustomResourceValidation)
(*in).DeepCopyInto(*out)
}
if in.Subresources != nil {
in, out := &in.Subresources, &out.Subresources
*out = new(CustomResourceSubresources)
(*in).DeepCopyInto(*out)
}
if in.Versions != nil {
in, out := &in.Versions, &out.Versions
*out = make([]CustomResourceDefinitionVersion, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.AdditionalPrinterColumns != nil {
in, out := &in.AdditionalPrinterColumns, &out.AdditionalPrinterColumns
*out = make([]CustomResourceColumnDefinition, len(*in))
copy(*out, *in)
}
if in.Conversion != nil {
in, out := &in.Conversion, &out.Conversion
*out = new(CustomResourceConversion)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionSpec.
func (in *CustomResourceDefinitionSpec) DeepCopy() *CustomResourceDefinitionSpec {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionStatus) DeepCopyInto(out *CustomResourceDefinitionStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]CustomResourceDefinitionCondition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
in.AcceptedNames.DeepCopyInto(&out.AcceptedNames)
if in.StoredVersions != nil {
in, out := &in.StoredVersions, &out.StoredVersions
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionStatus.
func (in *CustomResourceDefinitionStatus) DeepCopy() *CustomResourceDefinitionStatus {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceDefinitionVersion) DeepCopyInto(out *CustomResourceDefinitionVersion) {
*out = *in
if in.Schema != nil {
in, out := &in.Schema, &out.Schema
*out = new(CustomResourceValidation)
(*in).DeepCopyInto(*out)
}
if in.Subresources != nil {
in, out := &in.Subresources, &out.Subresources
*out = new(CustomResourceSubresources)
(*in).DeepCopyInto(*out)
}
if in.AdditionalPrinterColumns != nil {
in, out := &in.AdditionalPrinterColumns, &out.AdditionalPrinterColumns
*out = make([]CustomResourceColumnDefinition, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceDefinitionVersion.
func (in *CustomResourceDefinitionVersion) DeepCopy() *CustomResourceDefinitionVersion {
if in == nil {
return nil
}
out := new(CustomResourceDefinitionVersion)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceSubresourceScale) DeepCopyInto(out *CustomResourceSubresourceScale) {
*out = *in
if in.LabelSelectorPath != nil {
in, out := &in.LabelSelectorPath, &out.LabelSelectorPath
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresourceScale.
func (in *CustomResourceSubresourceScale) DeepCopy() *CustomResourceSubresourceScale {
if in == nil {
return nil
}
out := new(CustomResourceSubresourceScale)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceSubresourceStatus) DeepCopyInto(out *CustomResourceSubresourceStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresourceStatus.
func (in *CustomResourceSubresourceStatus) DeepCopy() *CustomResourceSubresourceStatus {
if in == nil {
return nil
}
out := new(CustomResourceSubresourceStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceSubresources) DeepCopyInto(out *CustomResourceSubresources) {
*out = *in
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(CustomResourceSubresourceStatus)
**out = **in
}
if in.Scale != nil {
in, out := &in.Scale, &out.Scale
*out = new(CustomResourceSubresourceScale)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresources.
func (in *CustomResourceSubresources) DeepCopy() *CustomResourceSubresources {
if in == nil {
return nil
}
out := new(CustomResourceSubresources)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomResourceValidation) DeepCopyInto(out *CustomResourceValidation) {
*out = *in
if in.OpenAPIV3Schema != nil {
in, out := &in.OpenAPIV3Schema, &out.OpenAPIV3Schema
*out = (*in).DeepCopy()
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceValidation.
func (in *CustomResourceValidation) DeepCopy() *CustomResourceValidation {
if in == nil {
return nil
}
out := new(CustomResourceValidation)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalDocumentation) DeepCopyInto(out *ExternalDocumentation) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalDocumentation.
func (in *ExternalDocumentation) DeepCopy() *ExternalDocumentation {
if in == nil {
return nil
}
out := new(ExternalDocumentation)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in JSONSchemaDefinitions) DeepCopyInto(out *JSONSchemaDefinitions) {
{
in := &in
*out = make(JSONSchemaDefinitions, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaDefinitions.
func (in JSONSchemaDefinitions) DeepCopy() JSONSchemaDefinitions {
if in == nil {
return nil
}
out := new(JSONSchemaDefinitions)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in JSONSchemaDependencies) DeepCopyInto(out *JSONSchemaDependencies) {
{
in := &in
*out = make(JSONSchemaDependencies, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaDependencies.
func (in JSONSchemaDependencies) DeepCopy() JSONSchemaDependencies {
if in == nil {
return nil
}
out := new(JSONSchemaDependencies)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONSchemaProps) DeepCopyInto(out *JSONSchemaProps) {
clone := in.DeepCopy()
*out = *clone
return
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONSchemaPropsOrArray) DeepCopyInto(out *JSONSchemaPropsOrArray) {
*out = *in
if in.Schema != nil {
in, out := &in.Schema, &out.Schema
*out = (*in).DeepCopy()
}
if in.JSONSchemas != nil {
in, out := &in.JSONSchemas, &out.JSONSchemas
*out = make([]JSONSchemaProps, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaPropsOrArray.
func (in *JSONSchemaPropsOrArray) DeepCopy() *JSONSchemaPropsOrArray {
if in == nil {
return nil
}
out := new(JSONSchemaPropsOrArray)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONSchemaPropsOrBool) DeepCopyInto(out *JSONSchemaPropsOrBool) {
*out = *in
if in.Schema != nil {
in, out := &in.Schema, &out.Schema
*out = (*in).DeepCopy()
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaPropsOrBool.
func (in *JSONSchemaPropsOrBool) DeepCopy() *JSONSchemaPropsOrBool {
if in == nil {
return nil
}
out := new(JSONSchemaPropsOrBool)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONSchemaPropsOrStringArray) DeepCopyInto(out *JSONSchemaPropsOrStringArray) {
*out = *in
if in.Schema != nil {
in, out := &in.Schema, &out.Schema
*out = (*in).DeepCopy()
}
if in.Property != nil {
in, out := &in.Property, &out.Property
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaPropsOrStringArray.
func (in *JSONSchemaPropsOrStringArray) DeepCopy() *JSONSchemaPropsOrStringArray {
if in == nil {
return nil
}
out := new(JSONSchemaPropsOrStringArray)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceReference) DeepCopyInto(out *ServiceReference) {
*out = *in
if in.Path != nil {
in, out := &in.Path, &out.Path
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceReference.
func (in *ServiceReference) DeepCopy() *ServiceReference {
if in == nil {
return nil
}
out := new(ServiceReference)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WebhookClientConfig) DeepCopyInto(out *WebhookClientConfig) {
*out = *in
if in.URL != nil {
in, out := &in.URL, &out.URL
*out = new(string)
**out = **in
}
if in.Service != nil {
in, out := &in.Service, &out.Service
*out = new(ServiceReference)
(*in).DeepCopyInto(*out)
}
if in.CABundle != nil {
in, out := &in.CABundle, &out.CABundle
*out = make([]byte, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookClientConfig.
func (in *WebhookClientConfig) DeepCopy() *WebhookClientConfig {
if in == nil {
return nil
}
out := new(WebhookClientConfig)
in.DeepCopyInto(out)
return out
}

View File

@@ -1,90 +0,0 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package clientset
import (
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
discovery "k8s.io/client-go/discovery"
rest "k8s.io/client-go/rest"
flowcontrol "k8s.io/client-go/util/flowcontrol"
)
type Interface interface {
Discovery() discovery.DiscoveryInterface
ApiextensionsV1beta1() apiextensionsv1beta1.ApiextensionsV1beta1Interface
}
// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
type Clientset struct {
*discovery.DiscoveryClient
apiextensionsV1beta1 *apiextensionsv1beta1.ApiextensionsV1beta1Client
}
// ApiextensionsV1beta1 retrieves the ApiextensionsV1beta1Client
func (c *Clientset) ApiextensionsV1beta1() apiextensionsv1beta1.ApiextensionsV1beta1Interface {
return c.apiextensionsV1beta1
}
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
if c == nil {
return nil
}
return c.DiscoveryClient
}
// NewForConfig creates a new Clientset for the given config.
func NewForConfig(c *rest.Config) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
}
var cs Clientset
var err error
cs.apiextensionsV1beta1, err = apiextensionsv1beta1.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
return &cs, nil
}
// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *Clientset {
var cs Clientset
cs.apiextensionsV1beta1 = apiextensionsv1beta1.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs
}
// New creates a new Clientset for the given RESTClient.
func New(c rest.Interface) *Clientset {
var cs Clientset
cs.apiextensionsV1beta1 = apiextensionsv1beta1.New(c)
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &cs
}

View File

@@ -1,20 +0,0 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated clientset.
package clientset

View File

@@ -1,20 +0,0 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package contains the scheme of the automatically generated clientset.
package scheme

View File

@@ -1,56 +0,0 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package scheme
import (
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
)
var Scheme = runtime.NewScheme()
var Codecs = serializer.NewCodecFactory(Scheme)
var ParameterCodec = runtime.NewParameterCodec(Scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
apiextensionsv1beta1.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(AddToScheme(Scheme))
}

View File

@@ -1,90 +0,0 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
rest "k8s.io/client-go/rest"
)
type ApiextensionsV1beta1Interface interface {
RESTClient() rest.Interface
CustomResourceDefinitionsGetter
}
// ApiextensionsV1beta1Client is used to interact with features provided by the apiextensions.k8s.io group.
type ApiextensionsV1beta1Client struct {
restClient rest.Interface
}
func (c *ApiextensionsV1beta1Client) CustomResourceDefinitions() CustomResourceDefinitionInterface {
return newCustomResourceDefinitions(c)
}
// NewForConfig creates a new ApiextensionsV1beta1Client for the given config.
func NewForConfig(c *rest.Config) (*ApiextensionsV1beta1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &ApiextensionsV1beta1Client{client}, nil
}
// NewForConfigOrDie creates a new ApiextensionsV1beta1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *ApiextensionsV1beta1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new ApiextensionsV1beta1Client for the given RESTClient.
func New(c rest.Interface) *ApiextensionsV1beta1Client {
return &ApiextensionsV1beta1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1beta1.SchemeGroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *ApiextensionsV1beta1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}

View File

@@ -1,180 +0,0 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
"time"
v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
scheme "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
)
// CustomResourceDefinitionsGetter has a method to return a CustomResourceDefinitionInterface.
// A group's client should implement this interface.
type CustomResourceDefinitionsGetter interface {
CustomResourceDefinitions() CustomResourceDefinitionInterface
}
// CustomResourceDefinitionInterface has methods to work with CustomResourceDefinition resources.
type CustomResourceDefinitionInterface interface {
Create(*v1beta1.CustomResourceDefinition) (*v1beta1.CustomResourceDefinition, error)
Update(*v1beta1.CustomResourceDefinition) (*v1beta1.CustomResourceDefinition, error)
UpdateStatus(*v1beta1.CustomResourceDefinition) (*v1beta1.CustomResourceDefinition, error)
Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options v1.GetOptions) (*v1beta1.CustomResourceDefinition, error)
List(opts v1.ListOptions) (*v1beta1.CustomResourceDefinitionList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CustomResourceDefinition, err error)
CustomResourceDefinitionExpansion
}
// customResourceDefinitions implements CustomResourceDefinitionInterface
type customResourceDefinitions struct {
client rest.Interface
}
// newCustomResourceDefinitions returns a CustomResourceDefinitions
func newCustomResourceDefinitions(c *ApiextensionsV1beta1Client) *customResourceDefinitions {
return &customResourceDefinitions{
client: c.RESTClient(),
}
}
// Get takes name of the customResourceDefinition, and returns the corresponding customResourceDefinition object, and an error if there is any.
func (c *customResourceDefinitions) Get(name string, options v1.GetOptions) (result *v1beta1.CustomResourceDefinition, err error) {
result = &v1beta1.CustomResourceDefinition{}
err = c.client.Get().
Resource("customresourcedefinitions").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of CustomResourceDefinitions that match those selectors.
func (c *customResourceDefinitions) List(opts v1.ListOptions) (result *v1beta1.CustomResourceDefinitionList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1beta1.CustomResourceDefinitionList{}
err = c.client.Get().
Resource("customresourcedefinitions").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested customResourceDefinitions.
func (c *customResourceDefinitions) Watch(opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Resource("customresourcedefinitions").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch()
}
// Create takes the representation of a customResourceDefinition and creates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any.
func (c *customResourceDefinitions) Create(customResourceDefinition *v1beta1.CustomResourceDefinition) (result *v1beta1.CustomResourceDefinition, err error) {
result = &v1beta1.CustomResourceDefinition{}
err = c.client.Post().
Resource("customresourcedefinitions").
Body(customResourceDefinition).
Do().
Into(result)
return
}
// Update takes the representation of a customResourceDefinition and updates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any.
func (c *customResourceDefinitions) Update(customResourceDefinition *v1beta1.CustomResourceDefinition) (result *v1beta1.CustomResourceDefinition, err error) {
result = &v1beta1.CustomResourceDefinition{}
err = c.client.Put().
Resource("customresourcedefinitions").
Name(customResourceDefinition.Name).
Body(customResourceDefinition).
Do().
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *customResourceDefinitions) UpdateStatus(customResourceDefinition *v1beta1.CustomResourceDefinition) (result *v1beta1.CustomResourceDefinition, err error) {
result = &v1beta1.CustomResourceDefinition{}
err = c.client.Put().
Resource("customresourcedefinitions").
Name(customResourceDefinition.Name).
SubResource("status").
Body(customResourceDefinition).
Do().
Into(result)
return
}
// Delete takes name of the customResourceDefinition and deletes it. Returns an error if one occurs.
func (c *customResourceDefinitions) Delete(name string, options *v1.DeleteOptions) error {
return c.client.Delete().
Resource("customresourcedefinitions").
Name(name).
Body(options).
Do().
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *customResourceDefinitions) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
var timeout time.Duration
if listOptions.TimeoutSeconds != nil {
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Resource("customresourcedefinitions").
VersionedParams(&listOptions, scheme.ParameterCodec).
Timeout(timeout).
Body(options).
Do().
Error()
}
// Patch applies the patch and returns the patched customResourceDefinition.
func (c *customResourceDefinitions) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CustomResourceDefinition, err error) {
result = &v1beta1.CustomResourceDefinition{}
err = c.client.Patch(pt).
Resource("customresourcedefinitions").
SubResource(subresources...).
Name(name).
Body(data).
Do().
Into(result)
return
}

View File

@@ -1,20 +0,0 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1beta1

View File

@@ -1,21 +0,0 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
type CustomResourceDefinitionExpansion interface{}