From 871312988b4963eb5bc7e1e7da570d6f0d908ffa Mon Sep 17 00:00:00 2001 From: Raunak Pradip Shah Date: Sat, 1 Apr 2023 14:10:29 +0530 Subject: [PATCH] Added create group volume snapshot functionality --- cmd/csi-snapshotter/main.go | 7 + go.mod | 2 +- go.sum | 4 +- .../groupsnapshot_controller_helper.go | 4 +- .../snapshot_controller_base.go | 3 + pkg/group_snapshotter/group_snapshotter.go | 89 + pkg/sidecar-controller/csi_handler.go | 56 + pkg/sidecar-controller/framework_test.go | 1 + .../groupsnapshot_helper.go | 485 ++++- .../snapshot_controller_base.go | 6 +- pkg/utils/util.go | 17 + .../spec/lib/go/csi/csi.pb.go | 1562 +++++++++++++---- vendor/modules.txt | 2 +- 13 files changed, 1904 insertions(+), 334 deletions(-) create mode 100644 pkg/group_snapshotter/group_snapshotter.go diff --git a/cmd/csi-snapshotter/main.go b/cmd/csi-snapshotter/main.go index cd094c34..18c356fc 100644 --- a/cmd/csi-snapshotter/main.go +++ b/cmd/csi-snapshotter/main.go @@ -20,6 +20,7 @@ import ( "context" "flag" "fmt" + "github.com/kubernetes-csi/external-snapshotter/v6/pkg/group_snapshotter" "net/http" "os" "os/signal" @@ -223,6 +224,11 @@ func main() { klog.V(2).Infof("Start NewCSISnapshotSideCarController with snapshotter [%s] kubeconfig [%s] csiTimeout [%+v] csiAddress [%s] resyncPeriod [%+v] snapshotNamePrefix [%s] snapshotNameUUIDLength [%d]", driverName, *kubeconfig, *csiTimeout, *csiAddress, *resyncPeriod, *snapshotNamePrefix, snapshotNameUUIDLength) snapShotter := snapshotter.NewSnapshotter(csiConn) + var groupSnapshotter group_snapshotter.GroupSnapshotter + if *enableVolumeGroupSnapshots { + groupSnapshotter = group_snapshotter.NewGroupSnapshotter(csiConn) + } + ctrl := controller.NewCSISnapshotSideCarController( snapClient, kubeClient, @@ -230,6 +236,7 @@ func main() { snapshotContentfactory.Snapshot().V1().VolumeSnapshotContents(), factory.Snapshot().V1().VolumeSnapshotClasses(), snapShotter, + groupSnapshotter, *csiTimeout, *resyncPeriod, *snapshotNamePrefix, diff --git a/go.mod b/go.mod index e380005e..a3e56f2e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/kubernetes-csi/external-snapshotter/v6 go 1.20 require ( - github.com/container-storage-interface/spec v1.7.0 + github.com/container-storage-interface/spec v1.8.0 github.com/evanphx/json-patch v4.12.0+incompatible github.com/fsnotify/fsnotify v1.6.0 github.com/golang/mock v1.6.0 diff --git a/go.sum b/go.sum index ef8a60fc..45a3c6db 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/container-storage-interface/spec v1.3.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= -github.com/container-storage-interface/spec v1.7.0 h1:gW8eyFQUZWWrMWa8p1seJ28gwDoN5CVJ4uAbQ+Hdycw= -github.com/container-storage-interface/spec v1.7.0/go.mod h1:JYuzLqr9VVNoDJl44xp/8fmCOvWPDKzuGTwCoklhuqk= +github.com/container-storage-interface/spec v1.8.0 h1:D0vhF3PLIZwlwZEf2eNbpujGCNwspwTYf2idJRJx4xI= +github.com/container-storage-interface/spec v1.8.0/go.mod h1:ROLik+GhPslwwWRNFF1KasPzroNARibH2rfz1rkg4H0= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/pkg/common-controller/groupsnapshot_controller_helper.go b/pkg/common-controller/groupsnapshot_controller_helper.go index fb650ef3..0232dd8e 100644 --- a/pkg/common-controller/groupsnapshot_controller_helper.go +++ b/pkg/common-controller/groupsnapshot_controller_helper.go @@ -220,7 +220,7 @@ func (ctrl *csiSnapshotCommonController) getClaimsFromVolumeGroupSnapshot(groupS labelSelector := groupSnapshot.Spec.Source.Selector // Get PVC that has group snapshot label applied. - pvcList, err := ctrl.client.CoreV1().PersistentVolumeClaims(groupSnapshot.Namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: labelSelector.String()}) + pvcList, err := ctrl.client.CoreV1().PersistentVolumeClaims(groupSnapshot.Namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: labels.Set(labelSelector.MatchLabels).String()}) if err != nil { return nil, fmt.Errorf("failed to list PVCs with label selector %s: %q", labelSelector.String(), err) } @@ -647,7 +647,7 @@ func (ctrl *csiSnapshotCommonController) getDynamicallyProvisionedGroupContentFr return nil, nil } // check whether the content represents a dynamically provisioned snapshot - if content.Spec.Source.VolumeGroupSnapshotHandle == nil { + if content.Spec.Source.VolumeGroupSnapshotHandle != nil { ctrl.updateGroupSnapshotErrorStatusWithEvent(groupSnapshot, true, v1.EventTypeWarning, "GroupSnapshotContentMismatch", "VolumeGroupSnapshotContent "+contentName+" is pre-provisioned while expecting a dynamically provisioned one") klog.V(4).Infof("sync group snapshot[%s]: group snapshot content %s is pre-provisioned while expecting a dynamically provisioned one", utils.GroupSnapshotKey(groupSnapshot), contentName) return nil, fmt.Errorf("group snapshot %s expects a dynamically provisioned VolumeGroupSnapshotContent %s but gets a pre-provisioned one", utils.GroupSnapshotKey(groupSnapshot), contentName) diff --git a/pkg/common-controller/snapshot_controller_base.go b/pkg/common-controller/snapshot_controller_base.go index 42b6a4c3..1f9ecad9 100644 --- a/pkg/common-controller/snapshot_controller_base.go +++ b/pkg/common-controller/snapshot_controller_base.go @@ -165,6 +165,9 @@ func NewCSISnapshotCommonController( ctrl.enableVolumeGroupSnapshots = enableVolumeGroupSnapshots if enableVolumeGroupSnapshots { + ctrl.groupSnapshotStore = cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc) + ctrl.groupSnapshotContentStore = cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc) + ctrl.groupSnapshotQueue = workqueue.NewNamedRateLimitingQueue(groupSnapshotRateLimiter, "snapshot-controller-group-snapshot") ctrl.groupSnapshotContentQueue = workqueue.NewNamedRateLimitingQueue(groupSnapshotContentRateLimiter, "snapshot-controller-group-content") diff --git a/pkg/group_snapshotter/group_snapshotter.go b/pkg/group_snapshotter/group_snapshotter.go new file mode 100644 index 00000000..b660753d --- /dev/null +++ b/pkg/group_snapshotter/group_snapshotter.go @@ -0,0 +1,89 @@ +/* +Copyright 2023 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 group_snapshotter + +import ( + "context" + "github.com/container-storage-interface/spec/lib/go/csi" + "github.com/golang/protobuf/ptypes" + csirpc "github.com/kubernetes-csi/csi-lib-utils/rpc" + "google.golang.org/grpc" + klog "k8s.io/klog/v2" + "time" +) + +// GroupSnapshotter implements CreateGroupSnapshot/DeleteGroupSnapshot operations against a remote CSI driver. +type GroupSnapshotter interface { + // CreateGroupSnapshot creates a snapshot for a volume + CreateGroupSnapshot(ctx context.Context, groupSnapshotName string, volumeIDs []string, parameters map[string]string, snapshotterCredentials map[string]string) (driverName string, snapshotId string, snapshots []*csi.Snapshot, timestamp time.Time, readyToUse bool, err error) + + // DeleteGroupSnapshot deletes a snapshot from a volume + DeleteGroupSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) (err error) + + // GetGroupSnapshotStatus returns if a snapshot is ready to use, creation time, and restore size. + GetGroupSnapshotStatus(ctx context.Context, snapshotID string, snapshotterListCredentials map[string]string) (bool, time.Time, error) +} + +type groupSnapshot struct { + conn *grpc.ClientConn +} + +func NewGroupSnapshotter(conn *grpc.ClientConn) GroupSnapshotter { + return &groupSnapshot{ + conn: conn, + } +} + +func (gs *groupSnapshot) CreateGroupSnapshot(ctx context.Context, groupSnapshotName string, volumeIDs []string, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, []*csi.Snapshot, time.Time, bool, error) { + klog.V(5).Infof("CSI CreateSnapshot: %s", groupSnapshotName) + client := csi.NewGroupControllerClient(gs.conn) + + driverName, err := csirpc.GetDriverName(ctx, gs.conn) + if err != nil { + return "", "", nil, time.Time{}, false, err + } + + req := csi.CreateVolumeGroupSnapshotRequest{ + Name: groupSnapshotName, + SourceVolumeIds: volumeIDs, + Secrets: snapshotterCredentials, + Parameters: parameters, + } + + rsp, err := client.CreateVolumeGroupSnapshot(ctx, &req) + if err != nil { + return "", "", nil, time.Time{}, false, err + } + + klog.V(5).Infof("CSI CreateSnapshot: %s driver name [%s] snapshot ID [%s] time stamp [%v] snapshots [%v] readyToUse [%v]", groupSnapshotName, driverName, rsp.GroupSnapshot.GroupSnapshotId, rsp.GroupSnapshot.CreationTime, rsp.GroupSnapshot.Snapshots, rsp.GroupSnapshot.ReadyToUse) + creationTime, err := ptypes.Timestamp(rsp.GroupSnapshot.CreationTime) + if err != nil { + return "", "", nil, time.Time{}, false, err + } + return driverName, rsp.GroupSnapshot.GroupSnapshotId, rsp.GroupSnapshot.Snapshots, creationTime, rsp.GroupSnapshot.ReadyToUse, nil + +} + +func (gs *groupSnapshot) DeleteGroupSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) error { + // TODO: Implement DeleteGroupSnapshot + return nil +} + +func (gs *groupSnapshot) GetGroupSnapshotStatus(ctx context.Context, snapshotID string, snapshotterListCredentials map[string]string) (bool, time.Time, error) { + // TODO: Implement GetGroupSnapshotStatus + return true, time.Now(), nil +} diff --git a/pkg/sidecar-controller/csi_handler.go b/pkg/sidecar-controller/csi_handler.go index 4c1fb811..bf67ad2c 100644 --- a/pkg/sidecar-controller/csi_handler.go +++ b/pkg/sidecar-controller/csi_handler.go @@ -19,6 +19,9 @@ package sidecar_controller import ( "context" "fmt" + "github.com/container-storage-interface/spec/lib/go/csi" + crdv1alpha1 "github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumegroupsnapshot/v1alpha1" + "github.com/kubernetes-csi/external-snapshotter/v6/pkg/group_snapshotter" "strings" "time" @@ -31,11 +34,14 @@ type Handler interface { CreateSnapshot(content *crdv1.VolumeSnapshotContent, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, time.Time, int64, bool, error) DeleteSnapshot(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) error GetSnapshotStatus(content *crdv1.VolumeSnapshotContent, snapshotterListCredentials map[string]string) (bool, time.Time, int64, error) + CreateGroupSnapshot(content *crdv1alpha1.VolumeGroupSnapshotContent, volumeIDs []string, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, []*csi.Snapshot, time.Time, bool, error) + GetGroupSnapshotStatus(content *crdv1alpha1.VolumeGroupSnapshotContent, snapshotterListCredentials map[string]string) (bool, time.Time, error) } // csiHandler is a handler that calls CSI to create/delete volume snapshot. type csiHandler struct { snapshotter snapshotter.Snapshotter + groupSnapshotter group_snapshotter.GroupSnapshotter timeout time.Duration snapshotNamePrefix string snapshotNameUUIDLength int @@ -44,12 +50,14 @@ type csiHandler struct { // NewCSIHandler returns a handler which includes the csi connection and Snapshot name details func NewCSIHandler( snapshotter snapshotter.Snapshotter, + groupSnapshotter group_snapshotter.GroupSnapshotter, timeout time.Duration, snapshotNamePrefix string, snapshotNameUUIDLength int, ) Handler { return &csiHandler{ snapshotter: snapshotter, + groupSnapshotter: groupSnapshotter, timeout: timeout, snapshotNamePrefix: snapshotNamePrefix, snapshotNameUUIDLength: snapshotNameUUIDLength, @@ -131,3 +139,51 @@ func makeSnapshotName(prefix, snapshotUID string, snapshotNameUUIDLength int) (s } return fmt.Sprintf("%s-%s", prefix, strings.Replace(snapshotUID, "-", "", -1)[0:snapshotNameUUIDLength]), nil } + +func (handler *csiHandler) CreateGroupSnapshot(content *crdv1alpha1.VolumeGroupSnapshotContent, volumeIDs []string, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, []*csi.Snapshot, time.Time, bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), handler.timeout) + defer cancel() + + if content.Spec.VolumeGroupSnapshotRef.UID == "" { + return "", "", nil, time.Time{}, false, fmt.Errorf("cannot create group snapshot. Group snapshot content %s not bound to a group snapshot", content.Name) + } + + if len(volumeIDs) == 0 { + return "", "", nil, time.Time{}, false, fmt.Errorf("cannot create group snapshot. PVCs to be snapshotted not found in group snapshot content %s", content.Name) + } + + snapshotName, err := makeGroupSnapshotName(handler.snapshotNamePrefix, string(content.Spec.VolumeGroupSnapshotRef.UID)) + if err != nil { + return "", "", nil, time.Time{}, false, err + } + return handler.groupSnapshotter.CreateGroupSnapshot(ctx, snapshotName, volumeIDs, parameters, snapshotterCredentials) +} + +func (handler *csiHandler) GetGroupSnapshotStatus(content *crdv1alpha1.VolumeGroupSnapshotContent, snapshotterListCredentials map[string]string) (bool, time.Time, error) { + ctx, cancel := context.WithTimeout(context.Background(), handler.timeout) + defer cancel() + + var snapshotHandle string + var err error + if content.Status != nil && content.Status.VolumeGroupSnapshotHandle != nil { + snapshotHandle = *content.Status.VolumeGroupSnapshotHandle + } else if content.Spec.Source.VolumeGroupSnapshotHandle != nil { + snapshotHandle = *content.Spec.Source.VolumeGroupSnapshotHandle + } else { + return false, time.Time{}, fmt.Errorf("failed to list snapshot for content %s: snapshotHandle is missing", content.Name) + } + + csiSnapshotStatus, timestamp, err := handler.groupSnapshotter.GetGroupSnapshotStatus(ctx, snapshotHandle, snapshotterListCredentials) + if err != nil { + return false, time.Time{}, fmt.Errorf("failed to list snapshot for content %s: %q", content.Name, err) + } + + return csiSnapshotStatus, timestamp, nil +} + +func makeGroupSnapshotName(prefix, groupSnapshotUID string) (string, error) { + if len(groupSnapshotUID) == 0 { + return "", fmt.Errorf("group snapshot object is missing UID") + } + return fmt.Sprintf("%s-%s", prefix, strings.Replace(groupSnapshotUID, "-", "", -1)), nil +} diff --git a/pkg/sidecar-controller/framework_test.go b/pkg/sidecar-controller/framework_test.go index 568c573f..9f2fe3e4 100644 --- a/pkg/sidecar-controller/framework_test.go +++ b/pkg/sidecar-controller/framework_test.go @@ -566,6 +566,7 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte informerFactory.Snapshot().V1().VolumeSnapshotContents(), informerFactory.Snapshot().V1().VolumeSnapshotClasses(), fakeSnapshot, + nil, // TODO: Replace with fake group snapshotter 5*time.Millisecond, 60*time.Second, "snapshot", diff --git a/pkg/sidecar-controller/groupsnapshot_helper.go b/pkg/sidecar-controller/groupsnapshot_helper.go index 37940586..728f1de8 100644 --- a/pkg/sidecar-controller/groupsnapshot_helper.go +++ b/pkg/sidecar-controller/groupsnapshot_helper.go @@ -17,11 +17,19 @@ limitations under the License. package sidecar_controller import ( + "context" + "crypto/sha256" + "fmt" + "time" + + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/cache" klog "k8s.io/klog/v2" crdv1alpha1 "github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumegroupsnapshot/v1alpha1" + crdv1 "github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumesnapshot/v1" "github.com/kubernetes-csi/external-snapshotter/v6/pkg/utils" ) @@ -159,12 +167,477 @@ func (ctrl *csiSnapshotSideCarController) syncGroupSnapshotContent(content *crdv TODO: Check if the group snapshot content should be deleted */ - /* - TODO: Check if a new group snapshot should be created by calling CreateGroupSnapshot - */ + if len(content.Spec.Source.PersistentVolumeNames) != 0 && content.Status == nil { + klog.V(5).Infof("syncContent: Call CreateGroupSnapshot for group snapshot content %s", content.Name) + return ctrl.createGroupSnapshot(content) + } + + // Skip checkandUpdateGroupSnapshotContentStatus() if ReadyToUse is already + // true. We don't want to keep calling CreateGroupSnapshot CSI methods over + // and over again for performance reasons. + var err error + if content.Status != nil && content.Status.ReadyToUse != nil && *content.Status.ReadyToUse == true { + // Try to remove AnnVolumeGroupSnapshotBeingCreated if it is not removed yet for some reason + _, err = ctrl.removeAnnVolumeGroupSnapshotBeingCreated(content) + return err + } + return ctrl.checkandUpdateGroupSnapshotContentStatus(content) +} + +// createGroupSnapshot starts new asynchronous operation to create group snapshot +func (ctrl *csiSnapshotSideCarController) createGroupSnapshot(content *crdv1alpha1.VolumeGroupSnapshotContent) error { + klog.V(5).Infof("createGroupSnapshot for group snapshot content [%s]: started", content.Name) + contentObj, err := ctrl.createGroupSnapshotWrapper(content) + if err != nil { + ctrl.updateGroupSnapshotContentErrorStatusWithEvent(contentObj, v1.EventTypeWarning, "SnapshotCreationFailed", fmt.Sprintf("Failed to create group snapshot: %v", err)) + klog.Errorf("createSnapshot for content [%s]: error occurred in createSnapshotWrapper: %v", content.Name, err) + return err + } + + _, updateErr := ctrl.storeGroupSnapshotContentUpdate(contentObj) + if updateErr != nil { + // We will get a "group snapshot update" event soon, this is not a big error + klog.V(4).Infof("createSnapshot for content [%s]: cannot update internal content cache: %v", content.Name, updateErr) + } - /* - TODO: Check and update group snapshot content status - */ return nil } + +// This is a wrapper function for the group snapshot creation process. +func (ctrl *csiSnapshotSideCarController) createGroupSnapshotWrapper(content *crdv1alpha1.VolumeGroupSnapshotContent) (*crdv1alpha1.VolumeGroupSnapshotContent, error) { + klog.Infof("createGroupSnapshotWrapper: Creating group snapshot for group snapshot content %s through the plugin ...", content.Name) + + class, snapshotterCredentials, err := ctrl.getCSIGroupSnapshotInput(content) + if err != nil { + return content, fmt.Errorf("failed to get input parameters to create group snapshot for content %s: %q", content.Name, err) + } + + // NOTE(xyang): handle create timeout + // Add an annotation to indicate the group snapshot creation request has been + // sent to the storage system and the controller is waiting for a response. + // The annotation will be removed after the storage system has responded with + // success or permanent failure. If the request times out, annotation will + // remain on the content to avoid potential leaking of a group snapshot resource on + // the storage system. + content, err = ctrl.setAnnVolumeGroupSnapshotBeingCreated(content) + if err != nil { + return content, fmt.Errorf("failed to add VolumeGroupSnapshotBeingCreated annotation on the content %s: %q", content.Name, err) + } + + parameters, err := utils.RemovePrefixedParameters(class.Parameters) + if err != nil { + return content, fmt.Errorf("failed to remove CSI Parameters of prefixed keys: %v", err) + } + if ctrl.extraCreateMetadata { + parameters[utils.PrefixedVolumeGroupSnapshotNameKey] = content.Spec.VolumeGroupSnapshotRef.Name + parameters[utils.PrefixedVolumeGroupSnapshotNamespaceKey] = content.Spec.VolumeGroupSnapshotRef.Namespace + parameters[utils.PrefixedVolumeGroupSnapshotContentNameKey] = content.Name + } + + volumeIDs, err := ctrl.getGroupSnapshotVolumeIDs(content) + driverName, groupSnapshotID, snapshots, creationTime, readyToUse, err := ctrl.handler.CreateGroupSnapshot(content, volumeIDs, parameters, snapshotterCredentials) + if err != nil { + // NOTE(xyang): handle create timeout + // If it is a final error, remove annotation to indicate + // storage system has responded with an error + klog.Infof("createSnapshotWrapper: CreateSnapshot for content %s returned error: %v", content.Name, err) + if isCSIFinalError(err) { + var removeAnnotationErr error + if content, removeAnnotationErr = ctrl.removeAnnVolumeGroupSnapshotBeingCreated(content); removeAnnotationErr != nil { + return content, fmt.Errorf("failed to remove VolumeGroupSnapshotBeingCreated annotation from the content %s: %s", content.Name, removeAnnotationErr) + } + } + + return content, fmt.Errorf("failed to take group snapshot of the volumes %s: %q", content.Spec.Source.PersistentVolumeNames, err) + } + + klog.V(5).Infof("Created group snapshot: driver %s, groupSnapshotId %s, creationTime %v, readyToUse %t", driverName, groupSnapshotID, creationTime, readyToUse) + + if creationTime.IsZero() { + creationTime = time.Now() + } + + // Create individual snapshots and snapshot contents + for _, snapshot := range snapshots { + volumeSnapshotContentName := GetSnapshotContentNameForVolumeGroupSnapshotContent(content) + volumeSnapshotName := GetSnapshotNameForVolumeGroupSnapshotContent(content) + volumeSnapshotNamespace := content.Spec.VolumeGroupSnapshotRef.Namespace + volumeSnapshotContent := &crdv1.VolumeSnapshotContent{ + ObjectMeta: metav1.ObjectMeta{ + Name: volumeSnapshotContentName, + }, + Spec: crdv1.VolumeSnapshotContentSpec{ + VolumeSnapshotRef: v1.ObjectReference{ + Kind: "VolumeSnapshots", + Name: volumeSnapshotName, + Namespace: volumeSnapshotNamespace, + }, + DeletionPolicy: content.Spec.DeletionPolicy, + Driver: content.Spec.Driver, + Source: crdv1.VolumeSnapshotContentSource{ + SnapshotHandle: &snapshot.SnapshotId, + }, + SourceVolumeMode: nil, + }, + } + + volumeSnapshot := &crdv1.VolumeSnapshot{ + ObjectMeta: metav1.ObjectMeta{ + Name: volumeSnapshotName, + Namespace: volumeSnapshotNamespace, + }, + Spec: crdv1.VolumeSnapshotSpec{ + Source: crdv1.VolumeSnapshotSource{ + VolumeSnapshotContentName: &volumeSnapshotContentName, + }, + }, + } + _, err = ctrl.clientset.SnapshotV1().VolumeSnapshotContents().Create(context.TODO(), volumeSnapshotContent, metav1.CreateOptions{}) + if err != nil { + return content, err + } + + _, err = ctrl.clientset.SnapshotV1().VolumeSnapshots(volumeSnapshotNamespace).Create(context.TODO(), volumeSnapshot, metav1.CreateOptions{}) + if err != nil { + return content, err + } + + } + newContent, err := ctrl.updateGroupSnapshotContentStatus(content, groupSnapshotID, readyToUse, creationTime.UnixNano()) + if err != nil { + klog.Errorf("error updating status for volume group snapshot content %s: %v.", content.Name, err) + return content, fmt.Errorf("error updating status for volume group snapshot content %s: %v", content.Name, err) + } + content = newContent + + // NOTE(xyang): handle create timeout + // Remove annotation to indicate storage system has successfully + // cut the group snapshot + content, err = ctrl.removeAnnVolumeGroupSnapshotBeingCreated(content) + if err != nil { + return content, fmt.Errorf("failed to remove VolumeGroupSnapshotBeingCreated annotation on the content %s: %q", content.Name, err) + } + return content, nil +} + +func (ctrl *csiSnapshotSideCarController) getCSIGroupSnapshotInput(content *crdv1alpha1.VolumeGroupSnapshotContent) (*crdv1alpha1.VolumeGroupSnapshotClass, map[string]string, error) { + className := content.Spec.VolumeGroupSnapshotClassName + klog.V(5).Infof("getCSIGroupSnapshotInput for group snapshot content [%s]", content.Name) + var class *crdv1alpha1.VolumeGroupSnapshotClass + var err error + if className != nil { + class, err = ctrl.getGroupSnapshotClass(*className) + if err != nil { + klog.Errorf("getCSISnapshotInput failed to getClassFromVolumeGroupSnapshot %s", err) + return nil, nil, err + } + } else { + // If dynamic provisioning, return failure if no group snapshot class + if len(content.Spec.Source.PersistentVolumeNames) != 0 { + klog.Errorf("failed to getCSISnapshotInput %s without a group snapshot class", content.Name) + return nil, nil, fmt.Errorf("failed to take group snapshot %s without a group snapshot class", content.Name) + } + // For pre-provisioned group snapshot, group snapshot class is not required + klog.V(5).Infof("getCSISnapshotInput for content [%s]: no VolumeGroupSnapshotClassName provided for pre-provisioned group snapshot", content.Name) + } + + // TODO: Resolve snapshotting secret credentials. + + return class, nil, nil +} + +// getGroupSnapshotClass is a helper function to get group snapshot class from the class name. +func (ctrl *csiSnapshotSideCarController) getGroupSnapshotClass(className string) (*crdv1alpha1.VolumeGroupSnapshotClass, error) { + klog.V(5).Infof("getGroupSnapshotClass: VolumeGroupSnapshotClassName [%s]", className) + + class, err := ctrl.groupSnapshotClassLister.Get(className) + if err != nil { + klog.Errorf("failed to retrieve group snapshot class %s from the informer: %q", className, err) + return nil, err + } + + return class, nil +} + +// setAnnVolumeGroupSnapshotBeingCreated sets VolumeGroupSnapshotBeingCreated annotation +// on VolumeGroupSnapshotContent +// If set, it indicates group snapshot is being created +func (ctrl *csiSnapshotSideCarController) setAnnVolumeGroupSnapshotBeingCreated(content *crdv1alpha1.VolumeGroupSnapshotContent) (*crdv1alpha1.VolumeGroupSnapshotContent, error) { + if metav1.HasAnnotation(content.ObjectMeta, utils.AnnVolumeGroupSnapshotBeingCreated) { + // the annotation already exists, return directly + return content, nil + } + + // Set AnnVolumeGroupSnapshotBeingCreated + // Combine existing annotations with the new annotations. + // If there are no existing annotations, we create a new map. + klog.V(5).Infof("setAnnVolumeGroupSnapshotBeingCreated: set annotation [%s:yes] on content [%s].", utils.AnnVolumeGroupSnapshotBeingCreated, content.Name) + patchedAnnotations := make(map[string]string) + for k, v := range content.GetAnnotations() { + patchedAnnotations[k] = v + } + patchedAnnotations[utils.AnnVolumeGroupSnapshotBeingCreated] = "yes" + + var patches []utils.PatchOp + patches = append(patches, utils.PatchOp{ + Op: "replace", + Path: "/metadata/annotations", + Value: patchedAnnotations, + }) + + patchedContent, err := utils.PatchVolumeGroupSnapshotContent(content, patches, ctrl.clientset) + if err != nil { + return content, newControllerUpdateError(content.Name, err.Error()) + } + // update content if update is successful + content = patchedContent + + _, err = ctrl.storeContentUpdate(content) + if err != nil { + klog.V(4).Infof("setAnnVolumeGroupSnapshotBeingCreated for content [%s]: cannot update internal cache %v", content.Name, err) + } + klog.V(5).Infof("setAnnVolumeGroupSnapshotBeingCreated: volume group snapshot content %+v", content) + + return content, nil +} + +func (ctrl *csiSnapshotSideCarController) getGroupSnapshotVolumeIDs(content *crdv1alpha1.VolumeGroupSnapshotContent) ([]string, error) { + // TODO: Get add PV lister + var volumeIDs []string + for _, pvName := range content.Spec.Source.PersistentVolumeNames { + pv, err := ctrl.client.CoreV1().PersistentVolumes().Get(context.TODO(), pvName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + if pv.Spec.CSI != nil && pv.Spec.CSI.VolumeHandle != "" { + volumeIDs = append(volumeIDs, pv.Spec.CSI.VolumeHandle) + } + } + return volumeIDs, nil +} + +// removeAnnVolumeGroupSnapshotBeingCreated removes the VolumeGroupSnapshotBeingCreated +// annotation from a content if there exists one. +func (ctrl csiSnapshotSideCarController) removeAnnVolumeGroupSnapshotBeingCreated(content *crdv1alpha1.VolumeGroupSnapshotContent) (*crdv1alpha1.VolumeGroupSnapshotContent, error) { + if !metav1.HasAnnotation(content.ObjectMeta, utils.AnnVolumeGroupSnapshotBeingCreated) { + // the annotation does not exist, return directly + return content, nil + } + contentClone := content.DeepCopy() + delete(contentClone.ObjectMeta.Annotations, utils.AnnVolumeGroupSnapshotBeingCreated) + + updatedContent, err := ctrl.clientset.GroupsnapshotV1alpha1().VolumeGroupSnapshotContents().Update(context.TODO(), contentClone, metav1.UpdateOptions{}) + if err != nil { + return content, newControllerUpdateError(content.Name, err.Error()) + } + + klog.V(5).Infof("Removed VolumeGroupSnapshotBeingCreated annotation from volume group snapshot content %s", content.Name) + _, err = ctrl.storeContentUpdate(updatedContent) + if err != nil { + klog.Errorf("failed to update content store %v", err) + } + return updatedContent, nil +} + +func (ctrl *csiSnapshotSideCarController) updateGroupSnapshotContentStatus( + content *crdv1alpha1.VolumeGroupSnapshotContent, + groupSnapshotHandle string, + readyToUse bool, + createdAt int64) (*crdv1alpha1.VolumeGroupSnapshotContent, error) { + klog.V(5).Infof("updateSnapshotContentStatus: updating VolumeGroupSnapshotContent [%s], groupSnapshotHandle %s, readyToUse %v, createdAt %v", content.Name, groupSnapshotHandle, readyToUse, createdAt) + + contentObj, err := ctrl.clientset.GroupsnapshotV1alpha1().VolumeGroupSnapshotContents().Get(context.TODO(), content.Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("error get group snapshot content %s from api server: %v", content.Name, err) + } + + var newStatus *crdv1alpha1.VolumeGroupSnapshotContentStatus + updated := false + if contentObj.Status == nil { + newStatus = &crdv1alpha1.VolumeGroupSnapshotContentStatus{ + VolumeGroupSnapshotHandle: &groupSnapshotHandle, + ReadyToUse: &readyToUse, + CreationTime: &createdAt, + } + updated = true + } else { + newStatus = contentObj.Status.DeepCopy() + if newStatus.VolumeGroupSnapshotHandle == nil { + newStatus.VolumeGroupSnapshotHandle = &groupSnapshotHandle + updated = true + } + if newStatus.ReadyToUse == nil || *newStatus.ReadyToUse != readyToUse { + newStatus.ReadyToUse = &readyToUse + updated = true + if readyToUse && newStatus.Error != nil { + newStatus.Error = nil + } + } + if newStatus.CreationTime == nil { + newStatus.CreationTime = &createdAt + updated = true + } + } + + if updated { + contentClone := contentObj.DeepCopy() + contentClone.Status = newStatus + newContent, err := ctrl.clientset.GroupsnapshotV1alpha1().VolumeGroupSnapshotContents().UpdateStatus(context.TODO(), contentClone, metav1.UpdateOptions{}) + if err != nil { + return contentObj, newControllerUpdateError(content.Name, err.Error()) + } + return newContent, nil + } + + return contentObj, nil +} + +// updateContentStatusWithEvent saves new content.Status to API server and emits +// given event on the content. It saves the status and emits the event only when +// the status has actually changed from the version saved in API server. +// Parameters: +// +// * content - content to update +// * eventtype, reason, message - event to send, see EventRecorder.Event() +func (ctrl *csiSnapshotSideCarController) updateGroupSnapshotContentErrorStatusWithEvent(content *crdv1alpha1.VolumeGroupSnapshotContent, eventtype, reason, message string) error { + klog.V(5).Infof("updateContentStatusWithEvent[%s]", content.Name) + + if content.Status != nil && content.Status.Error != nil && *content.Status.Error.Message == message { + klog.V(4).Infof("updateContentStatusWithEvent[%s]: the same error %v is already set", content.Name, content.Status.Error) + return nil + } + + var patches []utils.PatchOp + ready := false + contentStatusError := &crdv1.VolumeSnapshotError{ + Time: &metav1.Time{ + Time: time.Now(), + }, + Message: &message, + } + if content.Status == nil { + // Initialize status if nil + patches = append(patches, utils.PatchOp{ + Op: "replace", + Path: "/status", + Value: &crdv1alpha1.VolumeGroupSnapshotContentStatus{ + ReadyToUse: &ready, + Error: contentStatusError, + }, + }) + } else { + // Patch status if non-nil + patches = append(patches, utils.PatchOp{ + Op: "replace", + Path: "/status/error", + Value: contentStatusError, + }) + patches = append(patches, utils.PatchOp{ + Op: "replace", + Path: "/status/readyToUse", + Value: &ready, + }) + + } + + newContent, err := utils.PatchVolumeGroupSnapshotContent(content, patches, ctrl.clientset, "status") + + // Emit the event even if the status update fails so that user can see the error + ctrl.eventRecorder.Event(newContent, eventtype, reason, message) + + if err != nil { + klog.V(4).Infof("updating VolumeGroupSnapshotContent[%s] error status failed %v", content.Name, err) + return err + } + + _, err = ctrl.storeGroupSnapshotContentUpdate(newContent) + if err != nil { + klog.V(4).Infof("updating VolumeGroupSnapshotContent[%s] error status: cannot update internal cache %v", content.Name, err) + return err + } + + return nil +} + +// GetSnapshotNameForVolumeGroupSnapshotContent returns a unique snapshot name for a VolumeGroupSnapshotContent. +func GetSnapshotNameForVolumeGroupSnapshotContent(content *crdv1alpha1.VolumeGroupSnapshotContent) string { + return fmt.Sprintf("groupsnapshot-%x-%d", sha256.Sum256([]byte(content.UID)), time.Duration(time.Now().UnixNano())/time.Millisecond) +} + +// GetSnapshotContentNameForVolumeGroupSnapshotContent returns a unique content name for the +// passed in VolumeGroupSnapshotContent. +func GetSnapshotContentNameForVolumeGroupSnapshotContent(content *crdv1alpha1.VolumeGroupSnapshotContent) string { + return fmt.Sprintf("groupsnapcontent-%x-%d", sha256.Sum256([]byte(content.UID)), time.Duration(time.Now().UnixNano())/time.Millisecond) +} + +func (ctrl *csiSnapshotSideCarController) checkandUpdateGroupSnapshotContentStatus(content *crdv1alpha1.VolumeGroupSnapshotContent) error { + klog.V(5).Infof("checkandUpdateGroupSnapshotContentStatus[%s] started", content.Name) + contentObj, err := ctrl.checkandUpdateGroupSnapshotContentStatusOperation(content) + if err != nil { + ctrl.updateGroupSnapshotContentErrorStatusWithEvent(contentObj, v1.EventTypeWarning, "GroupSnapshotContentCheckandUpdateFailed", fmt.Sprintf("Failed to check and update group snapshot content: %v", err)) + klog.Errorf("checkandUpdateGroupSnapshotContentStatus [%s]: error occurred %v", content.Name, err) + return err + } + _, updateErr := ctrl.storeGroupSnapshotContentUpdate(contentObj) + if updateErr != nil { + // We will get a "group snapshot update" event soon, this is not a big error + klog.V(4).Infof("checkandUpdateGroupSnapshotContentStatus [%s]: cannot update internal cache: %v", content.Name, updateErr) + } + + return nil +} + +func (ctrl *csiSnapshotSideCarController) checkandUpdateGroupSnapshotContentStatusOperation(content *crdv1alpha1.VolumeGroupSnapshotContent) (*crdv1alpha1.VolumeGroupSnapshotContent, error) { + var err error + var creationTime time.Time + readyToUse := false + var driverName string + var groupSnapshotID string + var snapshotterListCredentials map[string]string + + if content.Spec.Source.VolumeGroupSnapshotHandle != nil { + klog.V(5).Infof("checkandUpdateGroupSnapshotContentStatusOperation: call GetSnapshotStatus for group snapshot which is pre-bound to content [%s]", content.Name) + + if content.Spec.VolumeGroupSnapshotClassName != nil { + class, err := ctrl.getGroupSnapshotClass(*content.Spec.VolumeGroupSnapshotClassName) + if err != nil { + klog.Errorf("Failed to get group snapshot class %s for group snapshot content %s: %v", *content.Spec.VolumeGroupSnapshotClassName, content.Name, err) + return content, fmt.Errorf("failed to get group snapshot class %s for group snapshot content %s: %v", *content.Spec.VolumeGroupSnapshotClassName, content.Name, err) + } + + snapshotterListSecretRef, err := utils.GetSecretReference(utils.SnapshotterListSecretParams, class.Parameters, content.GetObjectMeta().GetName(), nil) + if err != nil { + klog.Errorf("Failed to get secret reference for group snapshot content %s: %v", content.Name, err) + return content, fmt.Errorf("failed to get secret reference for group snapshot content %s: %v", content.Name, err) + } + + snapshotterListCredentials, err = utils.GetCredentials(ctrl.client, snapshotterListSecretRef) + if err != nil { + // Continue with deletion, as the secret may have already been deleted. + klog.Errorf("Failed to get credentials for group snapshot content %s: %v", content.Name, err) + return content, fmt.Errorf("failed to get credentials for group snapshot content %s: %v", content.Name, err) + } + } + + readyToUse, creationTime, err = ctrl.handler.GetGroupSnapshotStatus(content, snapshotterListCredentials) + if err != nil { + klog.Errorf("checkandUpdateGroupSnapshotContentStatusOperation: failed to call get group snapshot status to check whether group snapshot is ready to use %q", err) + return content, err + } + driverName = content.Spec.Driver + groupSnapshotID = *content.Spec.Source.VolumeGroupSnapshotHandle + + klog.V(5).Infof("checkandUpdateGroupSnapshotContentStatusOperation: driver %s, groupSnapshotId %s, creationTime %v, size %d, readyToUse %t", driverName, groupSnapshotID, creationTime, readyToUse) + + if creationTime.IsZero() { + creationTime = time.Now() + } + + updatedContent, err := ctrl.updateGroupSnapshotContentStatus(content, groupSnapshotID, readyToUse, creationTime.UnixNano()) + if err != nil { + return content, err + } + return updatedContent, nil + } + return ctrl.createGroupSnapshotWrapper(content) +} diff --git a/pkg/sidecar-controller/snapshot_controller_base.go b/pkg/sidecar-controller/snapshot_controller_base.go index 148c13d0..5f789d0a 100644 --- a/pkg/sidecar-controller/snapshot_controller_base.go +++ b/pkg/sidecar-controller/snapshot_controller_base.go @@ -18,6 +18,7 @@ package sidecar_controller import ( "fmt" + "github.com/kubernetes-csi/external-snapshotter/v6/pkg/group_snapshotter" "time" v1 "k8s.io/api/core/v1" @@ -79,6 +80,7 @@ func NewCSISnapshotSideCarController( volumeSnapshotContentInformer snapshotinformers.VolumeSnapshotContentInformer, volumeSnapshotClassInformer snapshotinformers.VolumeSnapshotClassInformer, snapshotter snapshotter.Snapshotter, + groupSnapshotter group_snapshotter.GroupSnapshotter, timeout time.Duration, resyncPeriod time.Duration, snapshotNamePrefix string, @@ -101,7 +103,7 @@ func NewCSISnapshotSideCarController( client: client, driverName: driverName, eventRecorder: eventRecorder, - handler: NewCSIHandler(snapshotter, timeout, snapshotNamePrefix, snapshotNameUUIDLength), + handler: NewCSIHandler(snapshotter, groupSnapshotter, timeout, snapshotNamePrefix, snapshotNameUUIDLength), resyncPeriod: resyncPeriod, contentStore: cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc), contentQueue: workqueue.NewNamedRateLimitingQueue(contentRateLimiter, "csi-snapshotter-content"), @@ -159,7 +161,7 @@ func NewCSISnapshotSideCarController( ) ctrl.groupSnapshotContentLister = volumeGroupSnapshotContentInformer.Lister() - ctrl.groupSnapshotClassListerSynced = volumeGroupSnapshotContentInformer.Informer().HasSynced + ctrl.groupSnapshotContentListerSynced = volumeGroupSnapshotContentInformer.Informer().HasSynced ctrl.groupSnapshotClassLister = volumeGroupSnapshotClassInformer.Lister() ctrl.groupSnapshotClassListerSynced = volumeGroupSnapshotClassInformer.Informer().HasSynced diff --git a/pkg/utils/util.go b/pkg/utils/util.go index d938477d..f0ea2cb1 100644 --- a/pkg/utils/util.go +++ b/pkg/utils/util.go @@ -64,6 +64,10 @@ const ( PrefixedVolumeSnapshotNamespaceKey = csiParameterPrefix + "volumesnapshot/namespace" // Prefixed VolumeSnapshot namespace key PrefixedVolumeSnapshotContentNameKey = csiParameterPrefix + "volumesnapshotcontent/name" // Prefixed VolumeSnapshotContent name key + PrefixedVolumeGroupSnapshotNameKey = csiParameterPrefix + "volumegroupsnapshot/name" // Prefixed VolumeGroupSnapshot name key + PrefixedVolumeGroupSnapshotNamespaceKey = csiParameterPrefix + "volumegroupsnapshot/namespace" // Prefixed VolumeGroupSnapshot namespace key + PrefixedVolumeGroupSnapshotContentNameKey = csiParameterPrefix + "volumegroupsnapshotcontent/name" // Prefixed VolumeGroupSnapshotContent name key + // Name of finalizer on VolumeSnapshotContents that are bound by VolumeSnapshots VolumeSnapshotContentFinalizer = "snapshot.storage.kubernetes.io/volumesnapshotcontent-bound-protection" // Name of finalizer on VolumeSnapshot that is being used as a source to create a PVC @@ -96,6 +100,19 @@ const ( // snapshots. AnnVolumeSnapshotBeingCreated = "snapshot.storage.kubernetes.io/volumesnapshot-being-created" + // AnnVolumeGroupSnapshotBeingCreated annotation applies to VolumeGroupSnapshotContents. + // If it is set, it indicates that the csi-snapshotter + // sidecar has sent the create group snapshot request to the storage system and + // is waiting for a response of success or failure. + // This annotation will be removed once the driver's CreateGroupSnapshot + // CSI function returns success or a final error (determined by isFinalError()). + // If the create group snapshot request fails with a non-final error such as timeout, + // retry will happen and the annotation will remain. + // This only applies to dynamic provisioning of group snapshots because + // the create group snapshot CSI method will not be called for pre-provisioned + // group snapshots. + AnnVolumeGroupSnapshotBeingCreated = "snapshot.storage.kubernetes.io/volumegroupsnapshot-being-created" + // Annotation for secret name and namespace will be added to the content // and used at snapshot content deletion time. AnnDeletionSecretRefName = "snapshot.storage.kubernetes.io/deletion-secret-name" diff --git a/vendor/github.com/container-storage-interface/spec/lib/go/csi/csi.pb.go b/vendor/github.com/container-storage-interface/spec/lib/go/csi/csi.pb.go index d889edb2..fa010c37 100644 --- a/vendor/github.com/container-storage-interface/spec/lib/go/csi/csi.pb.go +++ b/vendor/github.com/container-storage-interface/spec/lib/go/csi/csi.pb.go @@ -47,18 +47,28 @@ const ( // returned by NodeGetInfo to ensure that a given volume is // accessible from a given node when scheduling workloads. PluginCapability_Service_VOLUME_ACCESSIBILITY_CONSTRAINTS PluginCapability_Service_Type = 2 + // GROUP_CONTROLLER_SERVICE indicates that the Plugin provides + // RPCs for operating on groups of volumes. Plugins MAY provide + // this capability. + // The presence of this capability determines whether the CO will + // attempt to invoke the REQUIRED GroupController service RPCs, as + // well as specific RPCs as indicated by + // GroupControllerGetCapabilities. + PluginCapability_Service_GROUP_CONTROLLER_SERVICE PluginCapability_Service_Type = 3 ) var PluginCapability_Service_Type_name = map[int32]string{ 0: "UNKNOWN", 1: "CONTROLLER_SERVICE", 2: "VOLUME_ACCESSIBILITY_CONSTRAINTS", + 3: "GROUP_CONTROLLER_SERVICE", } var PluginCapability_Service_Type_value = map[string]int32{ "UNKNOWN": 0, "CONTROLLER_SERVICE": 1, "VOLUME_ACCESSIBILITY_CONSTRAINTS": 2, + "GROUP_CONTROLLER_SERVICE": 3, } func (x PluginCapability_Service_Type) String() string { @@ -85,17 +95,20 @@ const ( // expansion of node-published volume via NodeExpandVolume. // // Example 1: Given a shared filesystem volume (e.g. GlusterFs), - // the Plugin may set the ONLINE volume expansion capability and - // implement ControllerExpandVolume but not NodeExpandVolume. + // + // the Plugin may set the ONLINE volume expansion capability and + // implement ControllerExpandVolume but not NodeExpandVolume. // // Example 2: Given a block storage volume type (e.g. EBS), the - // Plugin may set the ONLINE volume expansion capability and - // implement both ControllerExpandVolume and NodeExpandVolume. + // + // Plugin may set the ONLINE volume expansion capability and + // implement both ControllerExpandVolume and NodeExpandVolume. // // Example 3: Given a Plugin that supports volume expansion only - // upon a node, the Plugin may set the ONLINE volume - // expansion capability and implement NodeExpandVolume but not - // ControllerExpandVolume. + // + // upon a node, the Plugin may set the ONLINE volume + // expansion capability and implement NodeExpandVolume but not + // ControllerExpandVolume. PluginCapability_VolumeExpansion_ONLINE PluginCapability_VolumeExpansion_Type = 1 // OFFLINE indicates that volumes currently published and // available on a node SHALL NOT be expanded via @@ -105,10 +118,11 @@ const ( // the EXPAND_VOLUME node capability. // // Example 1: Given a block storage volume type (e.g. Azure Disk) - // that does not support expansion of "node-attached" (i.e. - // controller-published) volumes, the Plugin may indicate - // OFFLINE volume expansion support and implement both - // ControllerExpandVolume and NodeExpandVolume. + // + // that does not support expansion of "node-attached" (i.e. + // controller-published) volumes, the Plugin may indicate + // OFFLINE volume expansion support and implement both + // ControllerExpandVolume and NodeExpandVolume. PluginCapability_VolumeExpansion_OFFLINE PluginCapability_VolumeExpansion_Type = 2 ) @@ -385,6 +399,34 @@ func (NodeServiceCapability_RPC_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor_9cdb00adce470e01, []int{55, 0, 0} } +type GroupControllerServiceCapability_RPC_Type int32 + +const ( + GroupControllerServiceCapability_RPC_UNKNOWN GroupControllerServiceCapability_RPC_Type = 0 + // Indicates that the group controller plugin supports + // creating, deleting, and getting details of a volume + // group snapshot. + GroupControllerServiceCapability_RPC_CREATE_DELETE_GET_VOLUME_GROUP_SNAPSHOT GroupControllerServiceCapability_RPC_Type = 1 +) + +var GroupControllerServiceCapability_RPC_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "CREATE_DELETE_GET_VOLUME_GROUP_SNAPSHOT", +} + +var GroupControllerServiceCapability_RPC_Type_value = map[string]int32{ + "UNKNOWN": 0, + "CREATE_DELETE_GET_VOLUME_GROUP_SNAPSHOT": 1, +} + +func (x GroupControllerServiceCapability_RPC_Type) String() string { + return proto.EnumName(GroupControllerServiceCapability_RPC_Type_name, int32(x)) +} + +func (GroupControllerServiceCapability_RPC_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{62, 0, 0} +} + type GetPluginInfoRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -555,6 +597,7 @@ func (m *GetPluginCapabilitiesResponse) GetCapabilities() []*PluginCapability { // Specifies a capability of the plugin. type PluginCapability struct { // Types that are valid to be assigned to Type: + // // *PluginCapability_Service_ // *PluginCapability_VolumeExpansion_ Type isPluginCapability_Type `protobuf_oneof:"type"` @@ -748,16 +791,16 @@ type ProbeResponse struct { // and it is important for a CO to distinguish between the following // cases: // - // 1) The plugin is in an unhealthy state and MAY need restarting. In - // this case a gRPC error code SHALL be returned. - // 2) The plugin is still initializing, but is otherwise perfectly - // healthy. In this case a successful response SHALL be returned - // with a readiness value of `false`. Calls to the plugin's - // Controller and/or Node services MAY fail due to an incomplete - // initialization state. - // 3) The plugin has finished initializing and is ready to service - // calls to its Controller and/or Node services. A successful - // response is returned with a readiness value of `true`. + // 1. The plugin is in an unhealthy state and MAY need restarting. In + // this case a gRPC error code SHALL be returned. + // 2. The plugin is still initializing, but is otherwise perfectly + // healthy. In this case a successful response SHALL be returned + // with a readiness value of `false`. Calls to the plugin's + // Controller and/or Node services MAY fail due to an incomplete + // initialization state. + // 3. The plugin has finished initializing and is ready to service + // calls to its Controller and/or Node services. A successful + // response is returned with a readiness value of `true`. // // This field is OPTIONAL. If not present, the caller SHALL assume // that the plugin is in a ready state and is accepting calls to its @@ -804,26 +847,27 @@ func (m *ProbeResponse) GetReady() *wrappers.BoolValue { type CreateVolumeRequest struct { // The suggested name for the storage space. This field is REQUIRED. // It serves two purposes: - // 1) Idempotency - This name is generated by the CO to achieve - // idempotency. The Plugin SHOULD ensure that multiple - // `CreateVolume` calls for the same name do not result in more - // than one piece of storage provisioned corresponding to that - // name. If a Plugin is unable to enforce idempotency, the CO's - // error recovery logic could result in multiple (unused) volumes - // being provisioned. - // In the case of error, the CO MUST handle the gRPC error codes - // per the recovery behavior defined in the "CreateVolume Errors" - // section below. - // The CO is responsible for cleaning up volumes it provisioned - // that it no longer needs. If the CO is uncertain whether a volume - // was provisioned or not when a `CreateVolume` call fails, the CO - // MAY call `CreateVolume` again, with the same name, to ensure the - // volume exists and to retrieve the volume's `volume_id` (unless - // otherwise prohibited by "CreateVolume Errors"). - // 2) Suggested name - Some storage systems allow callers to specify - // an identifier by which to refer to the newly provisioned - // storage. If a storage system supports this, it can optionally - // use this name as the identifier for the new volume. + // 1. Idempotency - This name is generated by the CO to achieve + // idempotency. The Plugin SHOULD ensure that multiple + // `CreateVolume` calls for the same name do not result in more + // than one piece of storage provisioned corresponding to that + // name. If a Plugin is unable to enforce idempotency, the CO's + // error recovery logic could result in multiple (unused) volumes + // being provisioned. + // In the case of error, the CO MUST handle the gRPC error codes + // per the recovery behavior defined in the "CreateVolume Errors" + // section below. + // The CO is responsible for cleaning up volumes it provisioned + // that it no longer needs. If the CO is uncertain whether a volume + // was provisioned or not when a `CreateVolume` call fails, the CO + // MAY call `CreateVolume` again, with the same name, to ensure the + // volume exists and to retrieve the volume's `volume_id` (unless + // otherwise prohibited by "CreateVolume Errors"). + // 2. Suggested name - Some storage systems allow callers to specify + // an identifier by which to refer to the newly provisioned + // storage. If a storage system supports this, it can optionally + // use this name as the identifier for the new volume. + // // Any Unicode string that conforms to the length limit is allowed // except those containing the following banned characters: // U+0000-U+0008, U+000B, U+000C, U+000E-U+001F, U+007F-U+009F. @@ -957,6 +1001,7 @@ func (m *CreateVolumeRequest) GetAccessibilityRequirements() *TopologyRequiremen // type fields MUST be specified. type VolumeContentSource struct { // Types that are valid to be assigned to Type: + // // *VolumeContentSource_Snapshot // *VolumeContentSource_Volume Type isVolumeContentSource_Type `protobuf_oneof:"type"` @@ -1168,6 +1213,7 @@ type VolumeCapability struct { // following fields MUST be specified. // // Types that are valid to be assigned to AccessType: + // // *VolumeCapability_Block // *VolumeCapability_Mount AccessType isVolumeCapability_AccessType `protobuf_oneof:"access_type"` @@ -1509,14 +1555,18 @@ type Volume struct { // node. // // Example 1: - // accessible_topology = {"region": "R1", "zone": "Z2"} + // + // accessible_topology = {"region": "R1", "zone": "Z2"} + // // Indicates a volume accessible only from the "region" "R1" and the // "zone" "Z2". // // Example 2: - // accessible_topology = - // {"region": "R1", "zone": "Z2"}, - // {"region": "R1", "zone": "Z3"} + // + // accessible_topology = + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"} + // // Indicates a volume accessible from both "zone" "Z2" and "zone" "Z3" // in the "region" "R1". AccessibleTopology []*Topology `protobuf:"bytes,5,rep,name=accessible_topology,json=accessibleTopology,proto3" json:"accessible_topology,omitempty"` @@ -1595,21 +1645,27 @@ type TopologyRequirement struct { // accessible from at least one of the requisite topologies. // // Given - // x = number of topologies provisioned volume is accessible from - // n = number of requisite topologies + // + // x = number of topologies provisioned volume is accessible from + // n = number of requisite topologies + // // The CO MUST ensure n >= 1. The SP MUST ensure x >= 1 // If x==n, then the SP MUST make the provisioned volume available to // all topologies from the list of requisite topologies. If it is // unable to do so, the SP MUST fail the CreateVolume call. // For example, if a volume should be accessible from a single zone, // and requisite = - // {"region": "R1", "zone": "Z2"} + // + // {"region": "R1", "zone": "Z2"} + // // then the provisioned volume MUST be accessible from the "region" // "R1" and the "zone" "Z2". // Similarly, if a volume should be accessible from two zones, and // requisite = - // {"region": "R1", "zone": "Z2"}, - // {"region": "R1", "zone": "Z3"} + // + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"} + // // then the provisioned volume MUST be accessible from the "region" // "R1" and both "zone" "Z2" and "zone" "Z3". // @@ -1618,18 +1674,23 @@ type TopologyRequirement struct { // the CreateVolume call. // For example, if a volume should be accessible from a single zone, // and requisite = - // {"region": "R1", "zone": "Z2"}, - // {"region": "R1", "zone": "Z3"} + // + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"} + // // then the SP may choose to make the provisioned volume available in // either the "zone" "Z2" or the "zone" "Z3" in the "region" "R1". // Similarly, if a volume should be accessible from two zones, and // requisite = - // {"region": "R1", "zone": "Z2"}, - // {"region": "R1", "zone": "Z3"}, - // {"region": "R1", "zone": "Z4"} + // + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"}, + // {"region": "R1", "zone": "Z4"} + // // then the provisioned volume MUST be accessible from any combination // of two unique topologies: e.g. "R1/Z2" and "R1/Z3", or "R1/Z2" and - // "R1/Z4", or "R1/Z3" and "R1/Z4". + // + // "R1/Z4", or "R1/Z3" and "R1/Z4". // // If x>n, then the SP MUST make the provisioned volume available from // all topologies from the list of requisite topologies and MAY choose @@ -1638,7 +1699,9 @@ type TopologyRequirement struct { // CreateVolume call. // For example, if a volume should be accessible from two zones, and // requisite = - // {"region": "R1", "zone": "Z2"} + // + // {"region": "R1", "zone": "Z2"} + // // then the provisioned volume MUST be accessible from the "region" // "R1" and the "zone" "Z2" and the SP may select the second zone // independently, e.g. "R1/Z4". @@ -1667,10 +1730,14 @@ type TopologyRequirement struct { // Example 1: // Given a volume should be accessible from a single zone, and // requisite = - // {"region": "R1", "zone": "Z2"}, - // {"region": "R1", "zone": "Z3"} + // + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"} + // // preferred = - // {"region": "R1", "zone": "Z3"} + // + // {"region": "R1", "zone": "Z3"} + // // then the SP SHOULD first attempt to make the provisioned volume // available from "zone" "Z3" in the "region" "R1" and fall back to // "zone" "Z2" in the "region" "R1" if that is not possible. @@ -1678,13 +1745,17 @@ type TopologyRequirement struct { // Example 2: // Given a volume should be accessible from a single zone, and // requisite = - // {"region": "R1", "zone": "Z2"}, - // {"region": "R1", "zone": "Z3"}, - // {"region": "R1", "zone": "Z4"}, - // {"region": "R1", "zone": "Z5"} + // + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"}, + // {"region": "R1", "zone": "Z4"}, + // {"region": "R1", "zone": "Z5"} + // // preferred = - // {"region": "R1", "zone": "Z4"}, - // {"region": "R1", "zone": "Z2"} + // + // {"region": "R1", "zone": "Z4"}, + // {"region": "R1", "zone": "Z2"} + // // then the SP SHOULD first attempt to make the provisioned volume // accessible from "zone" "Z4" in the "region" "R1" and fall back to // "zone" "Z2" in the "region" "R1" if that is not possible. If that @@ -1697,13 +1768,17 @@ type TopologyRequirement struct { // the volume is accessible from two zones, aka synchronously // replicated), and // requisite = - // {"region": "R1", "zone": "Z2"}, - // {"region": "R1", "zone": "Z3"}, - // {"region": "R1", "zone": "Z4"}, - // {"region": "R1", "zone": "Z5"} + // + // {"region": "R1", "zone": "Z2"}, + // {"region": "R1", "zone": "Z3"}, + // {"region": "R1", "zone": "Z4"}, + // {"region": "R1", "zone": "Z5"} + // // preferred = - // {"region": "R1", "zone": "Z5"}, - // {"region": "R1", "zone": "Z3"} + // + // {"region": "R1", "zone": "Z5"}, + // {"region": "R1", "zone": "Z3"} + // // then the SP SHOULD first attempt to make the provisioned volume // accessible from the combination of the two "zones" "Z5" and "Z3" in // the "region" "R1". If that's not possible, it should fall back to @@ -2972,6 +3047,7 @@ func (m *ControllerGetCapabilitiesResponse) GetCapabilities() []*ControllerServi // Specifies a capability of the controller service. type ControllerServiceCapability struct { // Types that are valid to be assigned to Type: + // // *ControllerServiceCapability_Rpc Type isControllerServiceCapability_Type `protobuf_oneof:"type"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -3093,12 +3169,12 @@ type CreateSnapshotRequest struct { // This field is OPTIONAL. The Plugin is responsible for parsing and // validating these parameters. COs will treat these as opaque. // Use cases for opaque parameters: - // - Specify a policy to automatically clean up the snapshot. - // - Specify an expiration date for the snapshot. - // - Specify whether the snapshot is readonly or read/write. - // - Specify if the snapshot should be replicated to some place. - // - Specify primary or secondary for replication systems that - // support snapshotting only on primary. + // - Specify a policy to automatically clean up the snapshot. + // - Specify an expiration date for the snapshot. + // - Specify whether the snapshot is readonly or read/write. + // - Specify if the snapshot should be replicated to some place. + // - Specify primary or secondary for replication systems that + // support snapshotting only on primary. Parameters map[string]string `protobuf:"bytes,4,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -3230,7 +3306,21 @@ type Snapshot struct { // Indicates if a snapshot is ready to use as a // `volume_content_source` in a `CreateVolumeRequest`. The default // value is false. This field is REQUIRED. - ReadyToUse bool `protobuf:"varint,5,opt,name=ready_to_use,json=readyToUse,proto3" json:"ready_to_use,omitempty"` + ReadyToUse bool `protobuf:"varint,5,opt,name=ready_to_use,json=readyToUse,proto3" json:"ready_to_use,omitempty"` + // The ID of the volume group snapshot that this snapshot is part of. + // It uniquely identifies the group snapshot on the storage system. + // This field is OPTIONAL. + // If this snapshot is a member of a volume group snapshot, and it + // MUST NOT be deleted as a stand alone snapshot, then the SP + // MUST provide the ID of the volume group snapshot in this field. + // If provided, CO MUST use this field in subsequent volume group + // snapshot operations to indicate that this snapshot is part of the + // specified group snapshot. + // If not provided, CO SHALL treat the snapshot as independent, + // and SP SHALL allow it to be deleted separately. + // If this message is inside a VolumeGroupSnapshot message, the value + // MUST be the same as the group_snapshot_id in that message. + GroupSnapshotId string `protobuf:"bytes,6,opt,name=group_snapshot_id,json=groupSnapshotId,proto3" json:"group_snapshot_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -3296,6 +3386,13 @@ func (m *Snapshot) GetReadyToUse() bool { return false } +func (m *Snapshot) GetGroupSnapshotId() string { + if m != nil { + return m.GroupSnapshotId + } + return "" +} + type DeleteSnapshotRequest struct { // The ID of the snapshot to be deleted. // This field is REQUIRED. @@ -4500,6 +4597,7 @@ func (m *NodeGetCapabilitiesResponse) GetCapabilities() []*NodeServiceCapability // Specifies a capability of the node service. type NodeServiceCapability struct { // Types that are valid to be assigned to Type: + // // *NodeServiceCapability_Rpc Type isNodeServiceCapability_Type `protobuf_oneof:"type"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -4666,8 +4764,10 @@ type NodeGetInfoResponse struct { // no topological constraints declared for V. // // Example 1: - // accessible_topology = - // {"region": "R1", "zone": "Z2"} + // + // accessible_topology = + // {"region": "R1", "zone": "Z2"} + // // Indicates the node exists within the "region" "R1" and the "zone" // "Z2". AccessibleTopology *Topology `protobuf:"bytes,3,opt,name=accessible_topology,json=accessibleTopology,proto3" json:"accessible_topology,omitempty"` @@ -4874,6 +4974,608 @@ func (m *NodeExpandVolumeResponse) GetCapacityBytes() int64 { return 0 } +type GroupControllerGetCapabilitiesRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupControllerGetCapabilitiesRequest) Reset() { *m = GroupControllerGetCapabilitiesRequest{} } +func (m *GroupControllerGetCapabilitiesRequest) String() string { return proto.CompactTextString(m) } +func (*GroupControllerGetCapabilitiesRequest) ProtoMessage() {} +func (*GroupControllerGetCapabilitiesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{60} +} + +func (m *GroupControllerGetCapabilitiesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupControllerGetCapabilitiesRequest.Unmarshal(m, b) +} +func (m *GroupControllerGetCapabilitiesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupControllerGetCapabilitiesRequest.Marshal(b, m, deterministic) +} +func (m *GroupControllerGetCapabilitiesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupControllerGetCapabilitiesRequest.Merge(m, src) +} +func (m *GroupControllerGetCapabilitiesRequest) XXX_Size() int { + return xxx_messageInfo_GroupControllerGetCapabilitiesRequest.Size(m) +} +func (m *GroupControllerGetCapabilitiesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GroupControllerGetCapabilitiesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupControllerGetCapabilitiesRequest proto.InternalMessageInfo + +type GroupControllerGetCapabilitiesResponse struct { + // All the capabilities that the group controller service supports. + // This field is OPTIONAL. + Capabilities []*GroupControllerServiceCapability `protobuf:"bytes,1,rep,name=capabilities,proto3" json:"capabilities,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupControllerGetCapabilitiesResponse) Reset() { + *m = GroupControllerGetCapabilitiesResponse{} +} +func (m *GroupControllerGetCapabilitiesResponse) String() string { return proto.CompactTextString(m) } +func (*GroupControllerGetCapabilitiesResponse) ProtoMessage() {} +func (*GroupControllerGetCapabilitiesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{61} +} + +func (m *GroupControllerGetCapabilitiesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupControllerGetCapabilitiesResponse.Unmarshal(m, b) +} +func (m *GroupControllerGetCapabilitiesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupControllerGetCapabilitiesResponse.Marshal(b, m, deterministic) +} +func (m *GroupControllerGetCapabilitiesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupControllerGetCapabilitiesResponse.Merge(m, src) +} +func (m *GroupControllerGetCapabilitiesResponse) XXX_Size() int { + return xxx_messageInfo_GroupControllerGetCapabilitiesResponse.Size(m) +} +func (m *GroupControllerGetCapabilitiesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GroupControllerGetCapabilitiesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupControllerGetCapabilitiesResponse proto.InternalMessageInfo + +func (m *GroupControllerGetCapabilitiesResponse) GetCapabilities() []*GroupControllerServiceCapability { + if m != nil { + return m.Capabilities + } + return nil +} + +// Specifies a capability of the group controller service. +type GroupControllerServiceCapability struct { + // Types that are valid to be assigned to Type: + // + // *GroupControllerServiceCapability_Rpc + Type isGroupControllerServiceCapability_Type `protobuf_oneof:"type"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupControllerServiceCapability) Reset() { *m = GroupControllerServiceCapability{} } +func (m *GroupControllerServiceCapability) String() string { return proto.CompactTextString(m) } +func (*GroupControllerServiceCapability) ProtoMessage() {} +func (*GroupControllerServiceCapability) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{62} +} + +func (m *GroupControllerServiceCapability) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupControllerServiceCapability.Unmarshal(m, b) +} +func (m *GroupControllerServiceCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupControllerServiceCapability.Marshal(b, m, deterministic) +} +func (m *GroupControllerServiceCapability) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupControllerServiceCapability.Merge(m, src) +} +func (m *GroupControllerServiceCapability) XXX_Size() int { + return xxx_messageInfo_GroupControllerServiceCapability.Size(m) +} +func (m *GroupControllerServiceCapability) XXX_DiscardUnknown() { + xxx_messageInfo_GroupControllerServiceCapability.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupControllerServiceCapability proto.InternalMessageInfo + +type isGroupControllerServiceCapability_Type interface { + isGroupControllerServiceCapability_Type() +} + +type GroupControllerServiceCapability_Rpc struct { + Rpc *GroupControllerServiceCapability_RPC `protobuf:"bytes,1,opt,name=rpc,proto3,oneof"` +} + +func (*GroupControllerServiceCapability_Rpc) isGroupControllerServiceCapability_Type() {} + +func (m *GroupControllerServiceCapability) GetType() isGroupControllerServiceCapability_Type { + if m != nil { + return m.Type + } + return nil +} + +func (m *GroupControllerServiceCapability) GetRpc() *GroupControllerServiceCapability_RPC { + if x, ok := m.GetType().(*GroupControllerServiceCapability_Rpc); ok { + return x.Rpc + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*GroupControllerServiceCapability) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*GroupControllerServiceCapability_Rpc)(nil), + } +} + +type GroupControllerServiceCapability_RPC struct { + Type GroupControllerServiceCapability_RPC_Type `protobuf:"varint,1,opt,name=type,proto3,enum=csi.v1.GroupControllerServiceCapability_RPC_Type" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupControllerServiceCapability_RPC) Reset() { *m = GroupControllerServiceCapability_RPC{} } +func (m *GroupControllerServiceCapability_RPC) String() string { return proto.CompactTextString(m) } +func (*GroupControllerServiceCapability_RPC) ProtoMessage() {} +func (*GroupControllerServiceCapability_RPC) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{62, 0} +} + +func (m *GroupControllerServiceCapability_RPC) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupControllerServiceCapability_RPC.Unmarshal(m, b) +} +func (m *GroupControllerServiceCapability_RPC) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupControllerServiceCapability_RPC.Marshal(b, m, deterministic) +} +func (m *GroupControllerServiceCapability_RPC) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupControllerServiceCapability_RPC.Merge(m, src) +} +func (m *GroupControllerServiceCapability_RPC) XXX_Size() int { + return xxx_messageInfo_GroupControllerServiceCapability_RPC.Size(m) +} +func (m *GroupControllerServiceCapability_RPC) XXX_DiscardUnknown() { + xxx_messageInfo_GroupControllerServiceCapability_RPC.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupControllerServiceCapability_RPC proto.InternalMessageInfo + +func (m *GroupControllerServiceCapability_RPC) GetType() GroupControllerServiceCapability_RPC_Type { + if m != nil { + return m.Type + } + return GroupControllerServiceCapability_RPC_UNKNOWN +} + +type CreateVolumeGroupSnapshotRequest struct { + // The suggested name for the group snapshot. This field is REQUIRED + // for idempotency. + // Any Unicode string that conforms to the length limit is allowed + // except those containing the following banned characters: + // U+0000-U+0008, U+000B, U+000C, U+000E-U+001F, U+007F-U+009F. + // (These are control characters other than commonly used whitespace.) + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // volume IDs of the source volumes to be snapshotted together. + // This field is REQUIRED. + SourceVolumeIds []string `protobuf:"bytes,2,rep,name=source_volume_ids,json=sourceVolumeIds,proto3" json:"source_volume_ids,omitempty"` + // Secrets required by plugin to complete + // ControllerCreateVolumeGroupSnapshot request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + // The secrets provided in this field SHOULD be the same for + // all group snapshot operations on the same group snapshot. + Secrets map[string]string `protobuf:"bytes,3,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Plugin specific parameters passed in as opaque key-value pairs. + // This field is OPTIONAL. The Plugin is responsible for parsing and + // validating these parameters. COs will treat these as opaque. + Parameters map[string]string `protobuf:"bytes,4,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateVolumeGroupSnapshotRequest) Reset() { *m = CreateVolumeGroupSnapshotRequest{} } +func (m *CreateVolumeGroupSnapshotRequest) String() string { return proto.CompactTextString(m) } +func (*CreateVolumeGroupSnapshotRequest) ProtoMessage() {} +func (*CreateVolumeGroupSnapshotRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{63} +} + +func (m *CreateVolumeGroupSnapshotRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateVolumeGroupSnapshotRequest.Unmarshal(m, b) +} +func (m *CreateVolumeGroupSnapshotRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateVolumeGroupSnapshotRequest.Marshal(b, m, deterministic) +} +func (m *CreateVolumeGroupSnapshotRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateVolumeGroupSnapshotRequest.Merge(m, src) +} +func (m *CreateVolumeGroupSnapshotRequest) XXX_Size() int { + return xxx_messageInfo_CreateVolumeGroupSnapshotRequest.Size(m) +} +func (m *CreateVolumeGroupSnapshotRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CreateVolumeGroupSnapshotRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateVolumeGroupSnapshotRequest proto.InternalMessageInfo + +func (m *CreateVolumeGroupSnapshotRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *CreateVolumeGroupSnapshotRequest) GetSourceVolumeIds() []string { + if m != nil { + return m.SourceVolumeIds + } + return nil +} + +func (m *CreateVolumeGroupSnapshotRequest) GetSecrets() map[string]string { + if m != nil { + return m.Secrets + } + return nil +} + +func (m *CreateVolumeGroupSnapshotRequest) GetParameters() map[string]string { + if m != nil { + return m.Parameters + } + return nil +} + +type CreateVolumeGroupSnapshotResponse struct { + // Contains all attributes of the newly created group snapshot. + // This field is REQUIRED. + GroupSnapshot *VolumeGroupSnapshot `protobuf:"bytes,1,opt,name=group_snapshot,json=groupSnapshot,proto3" json:"group_snapshot,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateVolumeGroupSnapshotResponse) Reset() { *m = CreateVolumeGroupSnapshotResponse{} } +func (m *CreateVolumeGroupSnapshotResponse) String() string { return proto.CompactTextString(m) } +func (*CreateVolumeGroupSnapshotResponse) ProtoMessage() {} +func (*CreateVolumeGroupSnapshotResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{64} +} + +func (m *CreateVolumeGroupSnapshotResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateVolumeGroupSnapshotResponse.Unmarshal(m, b) +} +func (m *CreateVolumeGroupSnapshotResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateVolumeGroupSnapshotResponse.Marshal(b, m, deterministic) +} +func (m *CreateVolumeGroupSnapshotResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateVolumeGroupSnapshotResponse.Merge(m, src) +} +func (m *CreateVolumeGroupSnapshotResponse) XXX_Size() int { + return xxx_messageInfo_CreateVolumeGroupSnapshotResponse.Size(m) +} +func (m *CreateVolumeGroupSnapshotResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CreateVolumeGroupSnapshotResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateVolumeGroupSnapshotResponse proto.InternalMessageInfo + +func (m *CreateVolumeGroupSnapshotResponse) GetGroupSnapshot() *VolumeGroupSnapshot { + if m != nil { + return m.GroupSnapshot + } + return nil +} + +type VolumeGroupSnapshot struct { + // The identifier for this group snapshot, generated by the plugin. + // This field MUST contain enough information to uniquely identify + // this specific snapshot vs all other group snapshots supported by + // this plugin. + // This field SHALL be used by the CO in subsequent calls to refer to + // this group snapshot. + // The SP is NOT responsible for global uniqueness of + // group_snapshot_id across multiple SPs. + // This field is REQUIRED. + GroupSnapshotId string `protobuf:"bytes,1,opt,name=group_snapshot_id,json=groupSnapshotId,proto3" json:"group_snapshot_id,omitempty"` + // A list of snapshots belonging to this group. + // This field is REQUIRED. + Snapshots []*Snapshot `protobuf:"bytes,2,rep,name=snapshots,proto3" json:"snapshots,omitempty"` + // Timestamp of when the volume group snapshot was taken. + // This field is REQUIRED. + CreationTime *timestamp.Timestamp `protobuf:"bytes,3,opt,name=creation_time,json=creationTime,proto3" json:"creation_time,omitempty"` + // Indicates if all individual snapshots in the group snapshot + // are ready to use as a `volume_content_source` in a + // `CreateVolumeRequest`. The default value is false. + // If any snapshot in the list of snapshots in this message have + // ready_to_use set to false, the SP MUST set this field to false. + // If all of the snapshots in the list of snapshots in this message + // have ready_to_use set to true, the SP SHOULD set this field to + // true. + // This field is REQUIRED. + ReadyToUse bool `protobuf:"varint,4,opt,name=ready_to_use,json=readyToUse,proto3" json:"ready_to_use,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VolumeGroupSnapshot) Reset() { *m = VolumeGroupSnapshot{} } +func (m *VolumeGroupSnapshot) String() string { return proto.CompactTextString(m) } +func (*VolumeGroupSnapshot) ProtoMessage() {} +func (*VolumeGroupSnapshot) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{65} +} + +func (m *VolumeGroupSnapshot) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VolumeGroupSnapshot.Unmarshal(m, b) +} +func (m *VolumeGroupSnapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VolumeGroupSnapshot.Marshal(b, m, deterministic) +} +func (m *VolumeGroupSnapshot) XXX_Merge(src proto.Message) { + xxx_messageInfo_VolumeGroupSnapshot.Merge(m, src) +} +func (m *VolumeGroupSnapshot) XXX_Size() int { + return xxx_messageInfo_VolumeGroupSnapshot.Size(m) +} +func (m *VolumeGroupSnapshot) XXX_DiscardUnknown() { + xxx_messageInfo_VolumeGroupSnapshot.DiscardUnknown(m) +} + +var xxx_messageInfo_VolumeGroupSnapshot proto.InternalMessageInfo + +func (m *VolumeGroupSnapshot) GetGroupSnapshotId() string { + if m != nil { + return m.GroupSnapshotId + } + return "" +} + +func (m *VolumeGroupSnapshot) GetSnapshots() []*Snapshot { + if m != nil { + return m.Snapshots + } + return nil +} + +func (m *VolumeGroupSnapshot) GetCreationTime() *timestamp.Timestamp { + if m != nil { + return m.CreationTime + } + return nil +} + +func (m *VolumeGroupSnapshot) GetReadyToUse() bool { + if m != nil { + return m.ReadyToUse + } + return false +} + +type DeleteVolumeGroupSnapshotRequest struct { + // The ID of the group snapshot to be deleted. + // This field is REQUIRED. + GroupSnapshotId string `protobuf:"bytes,1,opt,name=group_snapshot_id,json=groupSnapshotId,proto3" json:"group_snapshot_id,omitempty"` + // A list of snapshot IDs that are part of this group snapshot. + // If SP does not need to rely on this field to delete the snapshots + // in the group, it SHOULD check this field and report an error + // if it has the ability to detect a mismatch. + // Some SPs require this list to delete the snapshots in the group. + // If SP needs to use this field to delete the snapshots in the + // group, it MUST report an error if it has the ability to detect + // a mismatch. + // This field is REQUIRED. + SnapshotIds []string `protobuf:"bytes,2,rep,name=snapshot_ids,json=snapshotIds,proto3" json:"snapshot_ids,omitempty"` + // Secrets required by plugin to complete group snapshot deletion + // request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + // The secrets provided in this field SHOULD be the same for + // all group snapshot operations on the same group snapshot. + Secrets map[string]string `protobuf:"bytes,3,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteVolumeGroupSnapshotRequest) Reset() { *m = DeleteVolumeGroupSnapshotRequest{} } +func (m *DeleteVolumeGroupSnapshotRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteVolumeGroupSnapshotRequest) ProtoMessage() {} +func (*DeleteVolumeGroupSnapshotRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{66} +} + +func (m *DeleteVolumeGroupSnapshotRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteVolumeGroupSnapshotRequest.Unmarshal(m, b) +} +func (m *DeleteVolumeGroupSnapshotRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteVolumeGroupSnapshotRequest.Marshal(b, m, deterministic) +} +func (m *DeleteVolumeGroupSnapshotRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteVolumeGroupSnapshotRequest.Merge(m, src) +} +func (m *DeleteVolumeGroupSnapshotRequest) XXX_Size() int { + return xxx_messageInfo_DeleteVolumeGroupSnapshotRequest.Size(m) +} +func (m *DeleteVolumeGroupSnapshotRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteVolumeGroupSnapshotRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteVolumeGroupSnapshotRequest proto.InternalMessageInfo + +func (m *DeleteVolumeGroupSnapshotRequest) GetGroupSnapshotId() string { + if m != nil { + return m.GroupSnapshotId + } + return "" +} + +func (m *DeleteVolumeGroupSnapshotRequest) GetSnapshotIds() []string { + if m != nil { + return m.SnapshotIds + } + return nil +} + +func (m *DeleteVolumeGroupSnapshotRequest) GetSecrets() map[string]string { + if m != nil { + return m.Secrets + } + return nil +} + +type DeleteVolumeGroupSnapshotResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteVolumeGroupSnapshotResponse) Reset() { *m = DeleteVolumeGroupSnapshotResponse{} } +func (m *DeleteVolumeGroupSnapshotResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteVolumeGroupSnapshotResponse) ProtoMessage() {} +func (*DeleteVolumeGroupSnapshotResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{67} +} + +func (m *DeleteVolumeGroupSnapshotResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteVolumeGroupSnapshotResponse.Unmarshal(m, b) +} +func (m *DeleteVolumeGroupSnapshotResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteVolumeGroupSnapshotResponse.Marshal(b, m, deterministic) +} +func (m *DeleteVolumeGroupSnapshotResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteVolumeGroupSnapshotResponse.Merge(m, src) +} +func (m *DeleteVolumeGroupSnapshotResponse) XXX_Size() int { + return xxx_messageInfo_DeleteVolumeGroupSnapshotResponse.Size(m) +} +func (m *DeleteVolumeGroupSnapshotResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteVolumeGroupSnapshotResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteVolumeGroupSnapshotResponse proto.InternalMessageInfo + +type GetVolumeGroupSnapshotRequest struct { + // The ID of the group snapshot to fetch current group snapshot + // information for. + // This field is REQUIRED. + GroupSnapshotId string `protobuf:"bytes,1,opt,name=group_snapshot_id,json=groupSnapshotId,proto3" json:"group_snapshot_id,omitempty"` + // A list of snapshot IDs that are part of this group snapshot. + // If SP does not need to rely on this field to get the snapshots + // in the group, it SHOULD check this field and report an error + // if it has the ability to detect a mismatch. + // Some SPs require this list to get the snapshots in the group. + // If SP needs to use this field to get the snapshots in the + // group, it MUST report an error if it has the ability to detect + // a mismatch. + // This field is REQUIRED. + SnapshotIds []string `protobuf:"bytes,2,rep,name=snapshot_ids,json=snapshotIds,proto3" json:"snapshot_ids,omitempty"` + // Secrets required by plugin to complete + // GetVolumeGroupSnapshot request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + // The secrets provided in this field SHOULD be the same for + // all group snapshot operations on the same group snapshot. + Secrets map[string]string `protobuf:"bytes,3,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetVolumeGroupSnapshotRequest) Reset() { *m = GetVolumeGroupSnapshotRequest{} } +func (m *GetVolumeGroupSnapshotRequest) String() string { return proto.CompactTextString(m) } +func (*GetVolumeGroupSnapshotRequest) ProtoMessage() {} +func (*GetVolumeGroupSnapshotRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{68} +} + +func (m *GetVolumeGroupSnapshotRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetVolumeGroupSnapshotRequest.Unmarshal(m, b) +} +func (m *GetVolumeGroupSnapshotRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetVolumeGroupSnapshotRequest.Marshal(b, m, deterministic) +} +func (m *GetVolumeGroupSnapshotRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetVolumeGroupSnapshotRequest.Merge(m, src) +} +func (m *GetVolumeGroupSnapshotRequest) XXX_Size() int { + return xxx_messageInfo_GetVolumeGroupSnapshotRequest.Size(m) +} +func (m *GetVolumeGroupSnapshotRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetVolumeGroupSnapshotRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetVolumeGroupSnapshotRequest proto.InternalMessageInfo + +func (m *GetVolumeGroupSnapshotRequest) GetGroupSnapshotId() string { + if m != nil { + return m.GroupSnapshotId + } + return "" +} + +func (m *GetVolumeGroupSnapshotRequest) GetSnapshotIds() []string { + if m != nil { + return m.SnapshotIds + } + return nil +} + +func (m *GetVolumeGroupSnapshotRequest) GetSecrets() map[string]string { + if m != nil { + return m.Secrets + } + return nil +} + +type GetVolumeGroupSnapshotResponse struct { + // This field is REQUIRED + GroupSnapshot *VolumeGroupSnapshot `protobuf:"bytes,1,opt,name=group_snapshot,json=groupSnapshot,proto3" json:"group_snapshot,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetVolumeGroupSnapshotResponse) Reset() { *m = GetVolumeGroupSnapshotResponse{} } +func (m *GetVolumeGroupSnapshotResponse) String() string { return proto.CompactTextString(m) } +func (*GetVolumeGroupSnapshotResponse) ProtoMessage() {} +func (*GetVolumeGroupSnapshotResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9cdb00adce470e01, []int{69} +} + +func (m *GetVolumeGroupSnapshotResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetVolumeGroupSnapshotResponse.Unmarshal(m, b) +} +func (m *GetVolumeGroupSnapshotResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetVolumeGroupSnapshotResponse.Marshal(b, m, deterministic) +} +func (m *GetVolumeGroupSnapshotResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetVolumeGroupSnapshotResponse.Merge(m, src) +} +func (m *GetVolumeGroupSnapshotResponse) XXX_Size() int { + return xxx_messageInfo_GetVolumeGroupSnapshotResponse.Size(m) +} +func (m *GetVolumeGroupSnapshotResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetVolumeGroupSnapshotResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetVolumeGroupSnapshotResponse proto.InternalMessageInfo + +func (m *GetVolumeGroupSnapshotResponse) GetGroupSnapshot() *VolumeGroupSnapshot { + if m != nil { + return m.GroupSnapshot + } + return nil +} + var E_AlphaEnum = &proto.ExtensionDesc{ ExtendedType: (*descriptor.EnumOptions)(nil), ExtensionType: (*bool)(nil), @@ -4944,6 +5646,7 @@ func init() { proto.RegisterEnum("csi.v1.ControllerServiceCapability_RPC_Type", ControllerServiceCapability_RPC_Type_name, ControllerServiceCapability_RPC_Type_value) proto.RegisterEnum("csi.v1.VolumeUsage_Unit", VolumeUsage_Unit_name, VolumeUsage_Unit_value) proto.RegisterEnum("csi.v1.NodeServiceCapability_RPC_Type", NodeServiceCapability_RPC_Type_name, NodeServiceCapability_RPC_Type_value) + proto.RegisterEnum("csi.v1.GroupControllerServiceCapability_RPC_Type", GroupControllerServiceCapability_RPC_Type_name, GroupControllerServiceCapability_RPC_Type_value) proto.RegisterType((*GetPluginInfoRequest)(nil), "csi.v1.GetPluginInfoRequest") proto.RegisterType((*GetPluginInfoResponse)(nil), "csi.v1.GetPluginInfoResponse") proto.RegisterMapType((map[string]string)(nil), "csi.v1.GetPluginInfoResponse.ManifestEntry") @@ -5046,6 +5749,21 @@ func init() { proto.RegisterType((*NodeExpandVolumeRequest)(nil), "csi.v1.NodeExpandVolumeRequest") proto.RegisterMapType((map[string]string)(nil), "csi.v1.NodeExpandVolumeRequest.SecretsEntry") proto.RegisterType((*NodeExpandVolumeResponse)(nil), "csi.v1.NodeExpandVolumeResponse") + proto.RegisterType((*GroupControllerGetCapabilitiesRequest)(nil), "csi.v1.GroupControllerGetCapabilitiesRequest") + proto.RegisterType((*GroupControllerGetCapabilitiesResponse)(nil), "csi.v1.GroupControllerGetCapabilitiesResponse") + proto.RegisterType((*GroupControllerServiceCapability)(nil), "csi.v1.GroupControllerServiceCapability") + proto.RegisterType((*GroupControllerServiceCapability_RPC)(nil), "csi.v1.GroupControllerServiceCapability.RPC") + proto.RegisterType((*CreateVolumeGroupSnapshotRequest)(nil), "csi.v1.CreateVolumeGroupSnapshotRequest") + proto.RegisterMapType((map[string]string)(nil), "csi.v1.CreateVolumeGroupSnapshotRequest.ParametersEntry") + proto.RegisterMapType((map[string]string)(nil), "csi.v1.CreateVolumeGroupSnapshotRequest.SecretsEntry") + proto.RegisterType((*CreateVolumeGroupSnapshotResponse)(nil), "csi.v1.CreateVolumeGroupSnapshotResponse") + proto.RegisterType((*VolumeGroupSnapshot)(nil), "csi.v1.VolumeGroupSnapshot") + proto.RegisterType((*DeleteVolumeGroupSnapshotRequest)(nil), "csi.v1.DeleteVolumeGroupSnapshotRequest") + proto.RegisterMapType((map[string]string)(nil), "csi.v1.DeleteVolumeGroupSnapshotRequest.SecretsEntry") + proto.RegisterType((*DeleteVolumeGroupSnapshotResponse)(nil), "csi.v1.DeleteVolumeGroupSnapshotResponse") + proto.RegisterType((*GetVolumeGroupSnapshotRequest)(nil), "csi.v1.GetVolumeGroupSnapshotRequest") + proto.RegisterMapType((map[string]string)(nil), "csi.v1.GetVolumeGroupSnapshotRequest.SecretsEntry") + proto.RegisterType((*GetVolumeGroupSnapshotResponse)(nil), "csi.v1.GetVolumeGroupSnapshotResponse") proto.RegisterExtension(E_AlphaEnum) proto.RegisterExtension(E_AlphaEnumValue) proto.RegisterExtension(E_CsiSecret) @@ -5060,245 +5778,269 @@ func init() { } var fileDescriptor_9cdb00adce470e01 = []byte{ - // 3796 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x3b, 0x4b, 0x6c, 0x23, 0x47, - 0x76, 0x6a, 0xfe, 0x24, 0x3d, 0x4a, 0x1a, 0xaa, 0x28, 0x69, 0x38, 0x2d, 0x69, 0xa4, 0xe9, 0xf1, - 0x78, 0xe5, 0xf1, 0x0c, 0x67, 0xad, 0xb5, 0x8d, 0x58, 0x1e, 0xef, 0x9a, 0xa4, 0x38, 0x12, 0x77, - 0x28, 0x52, 0x6e, 0x52, 0x33, 0x3b, 0x93, 0x18, 0xed, 0x16, 0x59, 0xe2, 0x34, 0x4c, 0x76, 0xd3, - 0xdd, 0x4d, 0x45, 0xda, 0x4b, 0x82, 0x04, 0x39, 0x04, 0xb9, 0xe4, 0xb6, 0xce, 0x29, 0x8b, 0x24, - 0xc7, 0x5d, 0xec, 0x21, 0x08, 0x72, 0x0c, 0x90, 0x5b, 0x02, 0xe4, 0x73, 0x4b, 0x90, 0xcb, 0x1e, - 0x02, 0xe4, 0x60, 0x24, 0x80, 0xcf, 0x39, 0x04, 0x41, 0x57, 0x55, 0x37, 0xfb, 0xcb, 0xcf, 0x48, - 0x03, 0x1f, 0xf6, 0x24, 0xf6, 0xab, 0xf7, 0x5e, 0xbd, 0xaa, 0x7a, 0xef, 0xd5, 0xfb, 0x94, 0xe0, - 0x83, 0x8e, 0x62, 0xbe, 0x1a, 0x9c, 0xe6, 0x5b, 0x5a, 0xef, 0x51, 0x4b, 0x53, 0x4d, 0x59, 0x51, - 0xb1, 0xfe, 0xd0, 0x30, 0x35, 0x5d, 0xee, 0xe0, 0x87, 0x8a, 0x6a, 0x62, 0xfd, 0x4c, 0x6e, 0xe1, - 0x47, 0x46, 0x1f, 0xb7, 0x1e, 0xb5, 0x0c, 0x25, 0xdf, 0xd7, 0x35, 0x53, 0x43, 0x29, 0xeb, 0xe7, - 0xf9, 0x7b, 0xfc, 0x76, 0x47, 0xd3, 0x3a, 0x5d, 0xfc, 0x88, 0x40, 0x4f, 0x07, 0x67, 0x8f, 0xda, - 0xd8, 0x68, 0xe9, 0x4a, 0xdf, 0xd4, 0x74, 0x8a, 0xc9, 0x6f, 0xf9, 0x31, 0x4c, 0xa5, 0x87, 0x0d, - 0x53, 0xee, 0xf5, 0x19, 0xc2, 0x6d, 0x3f, 0xc2, 0xef, 0xea, 0x72, 0xbf, 0x8f, 0x75, 0x83, 0x8e, - 0x0b, 0x6b, 0xb0, 0x72, 0x80, 0xcd, 0xe3, 0xee, 0xa0, 0xa3, 0xa8, 0x15, 0xf5, 0x4c, 0x13, 0xf1, - 0x57, 0x03, 0x6c, 0x98, 0xc2, 0xbf, 0x73, 0xb0, 0xea, 0x1b, 0x30, 0xfa, 0x9a, 0x6a, 0x60, 0x84, - 0x20, 0xa1, 0xca, 0x3d, 0x9c, 0xe3, 0xb6, 0xb9, 0x9d, 0x79, 0x91, 0xfc, 0x46, 0xf7, 0x60, 0xe9, - 0x1c, 0xab, 0x6d, 0x4d, 0x97, 0xce, 0xb1, 0x6e, 0x28, 0x9a, 0x9a, 0x8b, 0x91, 0xd1, 0x45, 0x0a, - 0x7d, 0x46, 0x81, 0xe8, 0x00, 0xe6, 0x7a, 0xb2, 0xaa, 0x9c, 0x61, 0xc3, 0xcc, 0xc5, 0xb7, 0xe3, - 0x3b, 0xe9, 0xdd, 0x77, 0xf3, 0x74, 0xa9, 0xf9, 0xd0, 0xb9, 0xf2, 0x47, 0x0c, 0xbb, 0xac, 0x9a, - 0xfa, 0xa5, 0xe8, 0x10, 0xf3, 0x1f, 0xc3, 0xa2, 0x67, 0x08, 0x65, 0x20, 0xfe, 0x25, 0xbe, 0x64, - 0x32, 0x59, 0x3f, 0xd1, 0x0a, 0x24, 0xcf, 0xe5, 0xee, 0x00, 0x33, 0x49, 0xe8, 0xc7, 0x5e, 0xec, - 0xb7, 0x38, 0xe1, 0x36, 0x6c, 0x38, 0xb3, 0x95, 0xe4, 0xbe, 0x7c, 0xaa, 0x74, 0x15, 0x53, 0xc1, - 0x86, 0xbd, 0xf4, 0xcf, 0x61, 0x33, 0x62, 0x9c, 0xed, 0xc0, 0x63, 0x58, 0x68, 0xb9, 0xe0, 0x39, - 0x8e, 0x2c, 0x25, 0x67, 0x2f, 0xc5, 0x47, 0x79, 0x29, 0x7a, 0xb0, 0x85, 0x7f, 0x8e, 0x43, 0xc6, - 0x8f, 0x82, 0x1e, 0xc3, 0xac, 0x81, 0xf5, 0x73, 0xa5, 0x45, 0xf7, 0x35, 0xbd, 0xbb, 0x1d, 0xc5, - 0x2d, 0xdf, 0xa0, 0x78, 0x87, 0x33, 0xa2, 0x4d, 0x82, 0x4e, 0x20, 0x73, 0xae, 0x75, 0x07, 0x3d, - 0x2c, 0xe1, 0x8b, 0xbe, 0xac, 0x3a, 0x07, 0x90, 0xde, 0xdd, 0x89, 0x64, 0xf3, 0x8c, 0x10, 0x94, - 0x6d, 0xfc, 0xc3, 0x19, 0xf1, 0xc6, 0xb9, 0x17, 0xc4, 0xff, 0x8c, 0x83, 0x59, 0x36, 0x1b, 0xfa, - 0x08, 0x12, 0xe6, 0x65, 0x9f, 0x4a, 0xb7, 0xb4, 0x7b, 0x6f, 0x9c, 0x74, 0xf9, 0xe6, 0x65, 0x1f, - 0x8b, 0x84, 0x44, 0xf8, 0x0c, 0x12, 0xd6, 0x17, 0x4a, 0xc3, 0xec, 0x49, 0xed, 0x69, 0xad, 0xfe, - 0xbc, 0x96, 0x99, 0x41, 0x6b, 0x80, 0x4a, 0xf5, 0x5a, 0x53, 0xac, 0x57, 0xab, 0x65, 0x51, 0x6a, - 0x94, 0xc5, 0x67, 0x95, 0x52, 0x39, 0xc3, 0xa1, 0xb7, 0x60, 0xfb, 0x59, 0xbd, 0x7a, 0x72, 0x54, - 0x96, 0x0a, 0xa5, 0x52, 0xb9, 0xd1, 0xa8, 0x14, 0x2b, 0xd5, 0x4a, 0xf3, 0x85, 0x54, 0xaa, 0xd7, - 0x1a, 0x4d, 0xb1, 0x50, 0xa9, 0x35, 0x1b, 0x99, 0x18, 0xff, 0x07, 0x1c, 0xdc, 0xf0, 0x2d, 0x00, - 0x15, 0x3c, 0x12, 0x3e, 0x9c, 0x74, 0xe1, 0x6e, 0x49, 0x1f, 0x84, 0x49, 0x0a, 0x90, 0xaa, 0xd7, - 0xaa, 0x95, 0x9a, 0x25, 0x5d, 0x1a, 0x66, 0xeb, 0x4f, 0x9e, 0x90, 0x8f, 0x58, 0x31, 0x45, 0x27, - 0x14, 0x96, 0x60, 0xe1, 0x58, 0xd7, 0x4e, 0xb1, 0xad, 0x3f, 0x05, 0x58, 0x64, 0xdf, 0x4c, 0x5f, - 0xbe, 0x0f, 0x49, 0x1d, 0xcb, 0xed, 0x4b, 0x76, 0xb4, 0x7c, 0x9e, 0xda, 0x64, 0xde, 0xb6, 0xc9, - 0x7c, 0x51, 0xd3, 0xba, 0xcf, 0x2c, 0xfd, 0x14, 0x29, 0xa2, 0xf0, 0x6d, 0x02, 0xb2, 0x25, 0x1d, - 0xcb, 0x26, 0xa6, 0xd2, 0x32, 0xd6, 0xa1, 0xb6, 0xf7, 0x18, 0x96, 0x2c, 0xfd, 0x6a, 0x29, 0xe6, - 0xa5, 0xa4, 0xcb, 0x6a, 0x07, 0xb3, 0xa3, 0x5f, 0xb5, 0x77, 0xa0, 0xc4, 0x46, 0x45, 0x6b, 0x50, - 0x5c, 0x6c, 0xb9, 0x3f, 0x51, 0x05, 0xb2, 0x4c, 0x75, 0x3c, 0x2a, 0x1d, 0xf7, 0xaa, 0x34, 0x95, - 0xc2, 0xa5, 0xd2, 0xe8, 0xdc, 0x0b, 0x51, 0xb0, 0x81, 0x9e, 0x02, 0xf4, 0x65, 0x5d, 0xee, 0x61, - 0x13, 0xeb, 0x46, 0x2e, 0xe1, 0xb5, 0xef, 0x90, 0xd5, 0xe4, 0x8f, 0x1d, 0x6c, 0x6a, 0xdf, 0x2e, - 0x72, 0x74, 0x60, 0x19, 0x44, 0x4b, 0xc7, 0xa6, 0x91, 0x4b, 0x12, 0x4e, 0x3b, 0xa3, 0x38, 0x35, - 0x28, 0x2a, 0x61, 0x53, 0x8c, 0x7f, 0x5d, 0xe4, 0x44, 0x9b, 0x1a, 0xd5, 0x61, 0xd5, 0x5e, 0xa0, - 0xa6, 0x9a, 0x58, 0x35, 0x25, 0x43, 0x1b, 0xe8, 0x2d, 0x9c, 0x4b, 0x91, 0x5d, 0x5a, 0xf7, 0x2d, - 0x91, 0xe2, 0x34, 0x08, 0x8a, 0xc8, 0xb6, 0xc6, 0x03, 0x44, 0x2f, 0x81, 0x97, 0x5b, 0x2d, 0x6c, - 0x18, 0x0a, 0xdd, 0x0b, 0x49, 0xc7, 0x5f, 0x0d, 0x14, 0x1d, 0xf7, 0xb0, 0x6a, 0x1a, 0xb9, 0x59, - 0x2f, 0xd7, 0xa6, 0xd6, 0xd7, 0xba, 0x5a, 0xe7, 0x52, 0x1c, 0xe2, 0x88, 0xb7, 0x3c, 0xe4, 0xae, - 0x11, 0x83, 0xff, 0x04, 0x6e, 0xf8, 0x36, 0x65, 0x1a, 0xcf, 0xc6, 0xef, 0xc1, 0x82, 0x7b, 0x27, - 0xa6, 0xf2, 0x8a, 0x7f, 0x12, 0x83, 0x6c, 0xc8, 0x1e, 0xa0, 0x43, 0x98, 0x33, 0x54, 0xb9, 0x6f, - 0xbc, 0xd2, 0x4c, 0xa6, 0xbf, 0xf7, 0x47, 0x6c, 0x59, 0xbe, 0xc1, 0x70, 0xe9, 0xe7, 0xe1, 0x8c, - 0xe8, 0x50, 0xa3, 0x22, 0xa4, 0xe8, 0x7e, 0xfa, 0x7d, 0x53, 0x18, 0x1f, 0x0a, 0x73, 0xb8, 0x30, - 0x4a, 0xfe, 0x3d, 0x58, 0xf2, 0xce, 0x80, 0xb6, 0x20, 0x6d, 0xcf, 0x20, 0x29, 0x6d, 0xb6, 0x56, - 0xb0, 0x41, 0x95, 0x36, 0xff, 0x2e, 0x2c, 0xb8, 0x99, 0xa1, 0x75, 0x98, 0x67, 0x0a, 0xe1, 0xa0, - 0xcf, 0x51, 0x40, 0xa5, 0xed, 0xd8, 0xf4, 0x0f, 0x61, 0xc5, 0xab, 0x67, 0xcc, 0x94, 0xdf, 0x76, - 0xd6, 0x40, 0xf7, 0x62, 0xc9, 0xbb, 0x06, 0x5b, 0x4e, 0xe1, 0xcf, 0x93, 0x90, 0xf1, 0x1b, 0x0d, - 0x7a, 0x0c, 0xc9, 0xd3, 0xae, 0xd6, 0xfa, 0x92, 0xd1, 0xbe, 0x15, 0x65, 0x5d, 0xf9, 0xa2, 0x85, - 0x45, 0xa1, 0x87, 0x33, 0x22, 0x25, 0xb2, 0xa8, 0x7b, 0xda, 0x40, 0x35, 0xd9, 0xee, 0x45, 0x53, - 0x1f, 0x59, 0x58, 0x43, 0x6a, 0x42, 0x84, 0xf6, 0x21, 0x4d, 0xd5, 0x4e, 0xea, 0x69, 0x6d, 0x9c, - 0x8b, 0x13, 0x1e, 0x77, 0x23, 0x79, 0x14, 0x08, 0xee, 0x91, 0xd6, 0xc6, 0x22, 0xc8, 0xce, 0x6f, - 0x7e, 0x11, 0xd2, 0x2e, 0xd9, 0xf8, 0x01, 0xa4, 0x5d, 0x93, 0xa1, 0x9b, 0x30, 0x7b, 0x66, 0x48, - 0x8e, 0x13, 0x9e, 0x17, 0x53, 0x67, 0x06, 0xf1, 0xa7, 0x5b, 0x90, 0x26, 0x52, 0x48, 0x67, 0x5d, - 0xb9, 0x63, 0xe4, 0x62, 0xdb, 0x71, 0xeb, 0x8c, 0x08, 0xe8, 0x89, 0x05, 0x41, 0x0f, 0x80, 0x39, - 0x14, 0x89, 0xe2, 0x75, 0x74, 0x6d, 0xd0, 0x27, 0x42, 0xce, 0x8b, 0xec, 0x6a, 0x23, 0x13, 0x1d, - 0x58, 0x70, 0xfe, 0xaf, 0x63, 0x00, 0x43, 0x01, 0xd1, 0x63, 0x48, 0x90, 0x35, 0x51, 0xc7, 0xbf, - 0x33, 0xc1, 0x9a, 0xf2, 0x64, 0x61, 0x84, 0x4a, 0xf8, 0x2f, 0x0e, 0x12, 0x84, 0x8d, 0xff, 0x7a, - 0x6a, 0x54, 0x6a, 0x07, 0xd5, 0xb2, 0x54, 0xab, 0xef, 0x97, 0xa5, 0xe7, 0x62, 0xa5, 0x59, 0x16, - 0x33, 0x1c, 0x5a, 0x87, 0x9b, 0x6e, 0xb8, 0x58, 0x2e, 0xec, 0x97, 0x45, 0xa9, 0x5e, 0xab, 0xbe, - 0xc8, 0xc4, 0x10, 0x0f, 0x6b, 0x47, 0x27, 0xd5, 0x66, 0x25, 0x38, 0x16, 0x47, 0x1b, 0x90, 0x73, - 0x8d, 0x31, 0x1e, 0x8c, 0x6d, 0xc2, 0x62, 0xeb, 0x1a, 0xa5, 0x3f, 0xd9, 0x60, 0x12, 0x09, 0x70, - 0xcb, 0x3d, 0xa7, 0x97, 0x36, 0xc5, 0xc7, 0x7f, 0x5e, 0xe4, 0xd0, 0x1d, 0xc8, 0xb9, 0x71, 0x3c, - 0x1c, 0x66, 0x09, 0x4a, 0x71, 0xd1, 0xd1, 0x00, 0xa2, 0xe1, 0xcf, 0x61, 0xd1, 0x73, 0x31, 0x58, - 0x31, 0x1c, 0xf3, 0x64, 0x6d, 0xe9, 0xf4, 0xd2, 0x24, 0x71, 0x0d, 0xb7, 0x13, 0x17, 0x17, 0x6d, - 0x68, 0xd1, 0x02, 0x5a, 0x67, 0xd9, 0x55, 0x7a, 0x8a, 0xc9, 0x70, 0x62, 0x04, 0x07, 0x08, 0x88, - 0x20, 0x08, 0xbf, 0x8e, 0x41, 0x8a, 0x29, 0xc4, 0x3d, 0xd7, 0xd5, 0xe4, 0x61, 0x69, 0x43, 0x29, - 0x4b, 0x8f, 0x45, 0xc6, 0xbc, 0x16, 0x89, 0x0e, 0x61, 0xc9, 0xed, 0xbf, 0x2f, 0xec, 0xc8, 0xf1, - 0x8e, 0xf7, 0x9c, 0xdd, 0x4e, 0xe4, 0x82, 0xc5, 0x8b, 0x8b, 0xe7, 0x6e, 0x18, 0x2a, 0xc2, 0x92, - 0xef, 0x0a, 0x48, 0x8c, 0xbf, 0x02, 0x16, 0x5b, 0x1e, 0x6f, 0x58, 0x80, 0xac, 0xed, 0xbd, 0xbb, - 0x58, 0x32, 0x99, 0x77, 0x67, 0x57, 0x54, 0x26, 0xe0, 0xf5, 0xd1, 0x10, 0xd9, 0x86, 0xf1, 0x9f, - 0x02, 0x0a, 0xca, 0x3a, 0x95, 0xab, 0x1e, 0x40, 0x36, 0xe4, 0x5e, 0x41, 0x79, 0x98, 0x27, 0x47, - 0x65, 0x28, 0x26, 0x66, 0x31, 0x69, 0x50, 0xa2, 0x21, 0x8a, 0x85, 0xdf, 0xd7, 0xf1, 0x19, 0xd6, - 0x75, 0xdc, 0x26, 0x36, 0x19, 0x8a, 0xef, 0xa0, 0x08, 0x7f, 0xc8, 0xc1, 0x9c, 0x0d, 0x47, 0x7b, - 0x30, 0x67, 0xe0, 0x0e, 0xbd, 0xf3, 0xe8, 0x5c, 0xb7, 0xfd, 0xb4, 0xf9, 0x06, 0x43, 0x60, 0xd1, - 0xbb, 0x8d, 0x6f, 0x45, 0xef, 0x9e, 0xa1, 0xa9, 0x16, 0xff, 0xb7, 0x1c, 0x64, 0xf7, 0x71, 0x17, - 0xfb, 0x43, 0xa3, 0x51, 0x6e, 0xdd, 0x1d, 0x4d, 0xc4, 0xbc, 0xd1, 0x44, 0x08, 0xab, 0x11, 0xd1, - 0xc4, 0x95, 0x6e, 0xd8, 0x35, 0x58, 0xf1, 0xce, 0x46, 0xef, 0x14, 0xe1, 0x7f, 0xe2, 0x70, 0xdb, - 0xd2, 0x05, 0x5d, 0xeb, 0x76, 0xb1, 0x7e, 0x3c, 0x38, 0xed, 0x2a, 0xc6, 0xab, 0x29, 0x16, 0x77, - 0x13, 0x66, 0x55, 0xad, 0xed, 0x32, 0x9e, 0x94, 0xf5, 0x59, 0x69, 0xa3, 0x32, 0x2c, 0xfb, 0x63, - 0xbb, 0x4b, 0xe6, 0xf9, 0xa3, 0x23, 0xbb, 0xcc, 0xb9, 0xff, 0xda, 0xe2, 0x61, 0xce, 0x8a, 0x4a, - 0x35, 0xb5, 0x7b, 0x49, 0x2c, 0x66, 0x4e, 0x74, 0xbe, 0x91, 0xe8, 0x0f, 0xd3, 0x7e, 0xe0, 0x84, - 0x69, 0x23, 0x57, 0x34, 0x2a, 0x62, 0xfb, 0x22, 0x60, 0xf1, 0x29, 0xc2, 0xfa, 0xa3, 0x09, 0x59, - 0x8f, 0xf5, 0x04, 0x57, 0x39, 0xc5, 0x6b, 0x30, 0xdf, 0x7f, 0xe4, 0x60, 0x2b, 0x72, 0x09, 0x2c, - 0xce, 0x68, 0xc3, 0x8d, 0x3e, 0x1d, 0x70, 0x36, 0x81, 0x5a, 0xd9, 0xc7, 0x63, 0x37, 0x81, 0xa5, - 0xce, 0x0c, 0xea, 0xd9, 0x86, 0xa5, 0xbe, 0x07, 0xc8, 0x17, 0x20, 0x1b, 0x82, 0x36, 0xd5, 0x62, - 0xbe, 0xe1, 0x60, 0x7b, 0x28, 0xca, 0x89, 0xda, 0xbf, 0x3e, 0xf5, 0x6d, 0x0e, 0x75, 0x8b, 0xba, - 0xfc, 0x0f, 0x82, 0x6b, 0x0f, 0x9f, 0xf0, 0x4d, 0x59, 0xf0, 0x5d, 0xb8, 0x33, 0x62, 0x6a, 0x66, - 0xce, 0xbf, 0x4e, 0xc0, 0x9d, 0x67, 0x72, 0x57, 0x69, 0x3b, 0xd1, 0x63, 0x48, 0x91, 0x61, 0xf4, - 0x96, 0xb4, 0x02, 0x16, 0x40, 0xbd, 0xd6, 0x63, 0xc7, 0x6a, 0xc7, 0xf1, 0x9f, 0xe0, 0x3a, 0xbc, - 0xc6, 0xcc, 0xef, 0x45, 0x48, 0xe6, 0xf7, 0xd1, 0xe4, 0xb2, 0x8e, 0xca, 0x03, 0x4f, 0xfc, 0x0e, - 0xe6, 0xc3, 0xc9, 0xf9, 0x8e, 0xd0, 0x82, 0x2b, 0x5b, 0xf1, 0x77, 0x99, 0xaa, 0xfd, 0x7d, 0x02, - 0x84, 0x51, 0xab, 0x67, 0x3e, 0x44, 0x84, 0xf9, 0x96, 0xa6, 0x9e, 0x29, 0x7a, 0x0f, 0xb7, 0x59, - 0xca, 0xf1, 0xfe, 0x24, 0x9b, 0xc7, 0x1c, 0x48, 0xc9, 0xa6, 0x15, 0x87, 0x6c, 0x50, 0x0e, 0x66, - 0x7b, 0xd8, 0x30, 0xe4, 0x8e, 0x2d, 0x96, 0xfd, 0xc9, 0xff, 0x32, 0x0e, 0xf3, 0x0e, 0x09, 0x52, - 0x03, 0x1a, 0x4c, 0xdd, 0xd7, 0xc1, 0xeb, 0x08, 0xf0, 0xfa, 0xca, 0x1c, 0x7b, 0x0d, 0x65, 0x6e, - 0x7b, 0x94, 0x99, 0x9a, 0xc3, 0xfe, 0x6b, 0x89, 0x3d, 0x42, 0xaf, 0xbf, 0x73, 0x05, 0x14, 0x7e, - 0x07, 0x50, 0x55, 0x31, 0x58, 0xea, 0xe6, 0xb8, 0x25, 0x2b, 0x53, 0x93, 0x2f, 0x24, 0xac, 0x9a, - 0xba, 0xc2, 0xc2, 0xf5, 0xa4, 0x08, 0x3d, 0xf9, 0xa2, 0x4c, 0x21, 0x56, 0x48, 0x6f, 0x98, 0xb2, - 0x6e, 0x2a, 0x6a, 0x47, 0x32, 0xb5, 0x2f, 0xb1, 0x53, 0xe9, 0xb5, 0xa1, 0x4d, 0x0b, 0x28, 0xfc, - 0x77, 0x0c, 0xb2, 0x1e, 0xf6, 0x4c, 0x27, 0x3f, 0x86, 0xd9, 0x21, 0x6f, 0x4f, 0x18, 0x1f, 0x82, - 0x9d, 0xa7, 0xdb, 0x66, 0x53, 0xa0, 0x4d, 0x00, 0x15, 0x5f, 0x98, 0x9e, 0x79, 0xe7, 0x2d, 0x08, - 0x99, 0x93, 0xff, 0x23, 0xce, 0xc9, 0xf4, 0x4d, 0xd9, 0x1c, 0x90, 0xac, 0x92, 0xb9, 0x68, 0xdc, - 0x96, 0xd8, 0x1d, 0x43, 0xe7, 0x9d, 0x17, 0x33, 0xce, 0x48, 0x8d, 0xdc, 0x36, 0x06, 0x3a, 0x70, - 0x8a, 0xa8, 0x2d, 0x4d, 0x6d, 0x2b, 0xe6, 0xb0, 0x88, 0x7a, 0x33, 0x90, 0x20, 0xd0, 0xe1, 0xa2, - 0x95, 0x57, 0xd9, 0x65, 0x53, 0x07, 0xca, 0x7f, 0x05, 0x49, 0x7a, 0x1c, 0x13, 0x16, 0x0b, 0xd0, - 0xa7, 0x90, 0x32, 0x88, 0xc4, 0xfe, 0xc2, 0x48, 0xd8, 0x9e, 0xb8, 0x57, 0x28, 0x32, 0x3a, 0xe1, - 0x87, 0xc0, 0x0f, 0x2f, 0xa6, 0x03, 0x6c, 0x4e, 0x7e, 0xfd, 0xee, 0x59, 0x6b, 0x10, 0x7e, 0x16, - 0x83, 0xf5, 0x50, 0x06, 0xd3, 0x95, 0x3d, 0xd0, 0xa1, 0x6f, 0x25, 0xdf, 0x0f, 0xde, 0xd8, 0x01, - 0xe6, 0xa1, 0x2b, 0xe2, 0x7f, 0xff, 0x6a, 0x87, 0x59, 0x9c, 0xfa, 0x30, 0x03, 0xe7, 0x48, 0x77, - 0xe6, 0x97, 0x31, 0x40, 0x07, 0xd8, 0x74, 0x52, 0x65, 0xb6, 0xa5, 0x11, 0xfe, 0x86, 0x7b, 0x0d, - 0x7f, 0xf3, 0x63, 0x8f, 0xbf, 0xa1, 0x1e, 0xeb, 0xbe, 0xab, 0x2d, 0xe2, 0x9b, 0x7a, 0xe4, 0x6d, - 0x19, 0x91, 0x9e, 0xd2, 0x98, 0x7f, 0xb2, 0xf4, 0xf4, 0x8a, 0x6e, 0xe5, 0x3f, 0x39, 0xc8, 0x7a, - 0x84, 0x66, 0x1a, 0xf4, 0x10, 0x90, 0x7c, 0x2e, 0x2b, 0x5d, 0xd9, 0x12, 0xcc, 0x4e, 0xff, 0x59, - 0x39, 0x60, 0xd9, 0x19, 0xb1, 0xc9, 0xd0, 0x53, 0xc8, 0xf6, 0xe4, 0x0b, 0xa5, 0x37, 0xe8, 0x49, - 0x6c, 0x9f, 0x0d, 0xe5, 0xa7, 0x76, 0xe1, 0x70, 0x3d, 0x50, 0x40, 0xaf, 0xa8, 0xe6, 0x87, 0xef, - 0xd3, 0x0a, 0xfa, 0x32, 0xa3, 0x63, 0xca, 0xa3, 0xfc, 0x14, 0xa3, 0x63, 0xc8, 0xf6, 0x14, 0x35, - 0xc0, 0x2c, 0x3e, 0x96, 0x19, 0x35, 0xf0, 0x65, 0x46, 0x3c, 0xe4, 0x28, 0x08, 0xee, 0xa0, 0x97, - 0x2d, 0xd7, 0xdf, 0x46, 0xea, 0xba, 0x83, 0xc5, 0x00, 0x0e, 0xdb, 0x96, 0x83, 0xd0, 0x56, 0xd2, - 0xdd, 0xa0, 0xd9, 0xb0, 0xbe, 0x4a, 0x64, 0x57, 0xe9, 0xff, 0xe2, 0x6e, 0x0b, 0x0e, 0x60, 0xa3, - 0x8f, 0x21, 0xae, 0xf7, 0x5b, 0xcc, 0x7c, 0xbf, 0x37, 0x01, 0xff, 0xbc, 0x78, 0x5c, 0x3a, 0x9c, - 0x11, 0x2d, 0x2a, 0xfe, 0xcf, 0xe2, 0x10, 0x17, 0x8f, 0x4b, 0xe8, 0x53, 0x4f, 0x8b, 0xe5, 0xc1, - 0x84, 0x5c, 0xdc, 0x1d, 0x96, 0x7f, 0x89, 0x85, 0xb5, 0x58, 0x72, 0xb0, 0x52, 0x12, 0xcb, 0x85, - 0x66, 0x59, 0xda, 0x2f, 0x57, 0xcb, 0xcd, 0xb2, 0x44, 0x5b, 0x40, 0x19, 0x0e, 0x6d, 0x40, 0xee, - 0xf8, 0xa4, 0x58, 0xad, 0x34, 0x0e, 0xa5, 0x93, 0x9a, 0xfd, 0x8b, 0x8d, 0xc6, 0x50, 0x06, 0x16, - 0xaa, 0x95, 0x46, 0x93, 0x01, 0x1a, 0x99, 0xb8, 0x05, 0x39, 0x28, 0x37, 0xa5, 0x52, 0xe1, 0xb8, - 0x50, 0xaa, 0x34, 0x5f, 0x64, 0x12, 0x88, 0x87, 0x35, 0x2f, 0xef, 0x46, 0xad, 0x70, 0xdc, 0x38, - 0xac, 0x37, 0x33, 0x49, 0x84, 0x60, 0x89, 0xd0, 0xdb, 0xa0, 0x46, 0x26, 0x65, 0x71, 0x28, 0x55, - 0xeb, 0x35, 0x47, 0x86, 0x59, 0xb4, 0x02, 0x19, 0x7b, 0x66, 0xb1, 0x5c, 0xd8, 0x27, 0x05, 0xbd, - 0x39, 0xb4, 0x0c, 0x8b, 0xe5, 0x9f, 0x1c, 0x17, 0x6a, 0xfb, 0x36, 0xe2, 0x3c, 0xda, 0x86, 0x0d, - 0xb7, 0x38, 0x12, 0xa3, 0x2a, 0xef, 0x93, 0xa2, 0x5c, 0x23, 0x03, 0xe8, 0x16, 0x64, 0x58, 0x77, - 0xab, 0x54, 0xaf, 0xed, 0x57, 0x9a, 0x95, 0x7a, 0x2d, 0x93, 0xa6, 0x15, 0xbc, 0x2c, 0x80, 0x25, - 0x39, 0x63, 0xb6, 0x30, 0xbe, 0xac, 0xb7, 0x48, 0xcb, 0x7a, 0x76, 0xc5, 0xfa, 0x9b, 0x18, 0xac, - 0xd2, 0x92, 0xb5, 0x5d, 0x20, 0xb7, 0x7d, 0xd5, 0x0e, 0x64, 0x68, 0xbd, 0x4b, 0xf2, 0xdf, 0x02, - 0x4b, 0x14, 0xfe, 0xcc, 0xce, 0x3b, 0xec, 0xf6, 0x52, 0xcc, 0xd5, 0x5e, 0xaa, 0xf8, 0xb3, 0xb0, - 0xfb, 0xde, 0x46, 0x8c, 0x6f, 0xb6, 0x51, 0x89, 0xfd, 0x51, 0x48, 0x9a, 0xf0, 0x70, 0x34, 0xb7, - 0x51, 0x21, 0xd4, 0x55, 0xb2, 0xf8, 0x2b, 0x7a, 0xb9, 0x27, 0xb0, 0xe6, 0x97, 0x97, 0x19, 0xf4, - 0x83, 0x40, 0xbb, 0xc4, 0x71, 0xbb, 0x0e, 0xae, 0x83, 0x21, 0xfc, 0x1b, 0x07, 0x73, 0x36, 0xd8, - 0x0a, 0x6f, 0x2c, 0xbf, 0xe4, 0xa9, 0x94, 0xce, 0x5b, 0x10, 0xa7, 0xf0, 0xea, 0x6e, 0x74, 0xc4, - 0xfc, 0x8d, 0x8e, 0xd0, 0x73, 0x8e, 0x87, 0x9e, 0xf3, 0x8f, 0x60, 0xb1, 0x65, 0x89, 0xaf, 0x68, - 0xaa, 0x64, 0x2a, 0x3d, 0xbb, 0x10, 0x1a, 0x6c, 0x4c, 0x36, 0xed, 0xd7, 0x04, 0xe2, 0x82, 0x4d, - 0x60, 0x81, 0xd0, 0x36, 0x2c, 0x90, 0x46, 0xa5, 0x64, 0x6a, 0xd2, 0xc0, 0xc0, 0xb9, 0x24, 0x29, - 0x0b, 0x01, 0x81, 0x35, 0xb5, 0x13, 0x03, 0x0b, 0x7f, 0xc7, 0xc1, 0x2a, 0xad, 0x76, 0xf9, 0xd5, - 0x71, 0x5c, 0xc3, 0xc6, 0xad, 0x71, 0xbe, 0xdb, 0x30, 0x94, 0xe1, 0x9b, 0x4a, 0xf6, 0x73, 0xb0, - 0xe6, 0x9f, 0x8f, 0x65, 0xf8, 0xbf, 0x8a, 0xc1, 0x8a, 0x15, 0x9a, 0xd9, 0x03, 0xd7, 0x1d, 0x3d, - 0x4f, 0x71, 0x92, 0xbe, 0xcd, 0x4c, 0x04, 0x36, 0xf3, 0xd0, 0x9f, 0x3f, 0xbf, 0xe3, 0x0e, 0x2e, - 0xfd, 0x2b, 0x78, 0x53, 0x7b, 0xf9, 0x0b, 0x0e, 0x56, 0x7d, 0xf3, 0x31, 0x7b, 0xf9, 0xc4, 0x9f, - 0x10, 0xdc, 0x8d, 0x90, 0xef, 0xb5, 0x52, 0x82, 0x0f, 0xec, 0x50, 0x7c, 0x3a, 0xb3, 0xfc, 0xd7, - 0x18, 0x6c, 0x0e, 0x2f, 0x35, 0xf2, 0x54, 0xa0, 0x3d, 0x45, 0x45, 0xeb, 0x6a, 0x1d, 0xf9, 0xcf, - 0xfc, 0x0e, 0x77, 0x37, 0x78, 0xcf, 0x86, 0x88, 0x34, 0xca, 0xf1, 0x86, 0x16, 0x82, 0x13, 0xd3, - 0x16, 0x82, 0xaf, 0xa4, 0x01, 0xbf, 0xe7, 0xae, 0x71, 0x7b, 0xc5, 0x67, 0x9a, 0x30, 0x61, 0xb3, - 0xe8, 0x43, 0xb8, 0x49, 0xa2, 0x7f, 0xe7, 0xa5, 0x8b, 0xdd, 0x7f, 0xa7, 0x2e, 0x71, 0x4e, 0x5c, - 0xb5, 0x86, 0x9d, 0xe7, 0x1d, 0xac, 0x41, 0xd2, 0x16, 0xbe, 0x4d, 0xc0, 0x9a, 0x95, 0x1d, 0x34, - 0x4c, 0xb9, 0x33, 0x4d, 0xeb, 0xe0, 0xb7, 0x83, 0x95, 0xd8, 0x98, 0xf7, 0x58, 0xc2, 0xb9, 0x4e, - 0x52, 0x80, 0x45, 0x79, 0xc8, 0x1a, 0xa6, 0xdc, 0x21, 0xee, 0x40, 0xd6, 0x3b, 0xd8, 0x94, 0xfa, - 0xb2, 0xf9, 0x8a, 0xd9, 0xfa, 0x32, 0x1b, 0x6a, 0x92, 0x91, 0x63, 0xd9, 0x7c, 0x75, 0x4d, 0x07, - 0x89, 0x7e, 0xec, 0x77, 0x0a, 0xef, 0x8e, 0x59, 0xcb, 0x08, 0xdd, 0xfa, 0x49, 0x44, 0xb5, 0xfe, - 0xbd, 0x31, 0x2c, 0xc7, 0x57, 0xe9, 0xaf, 0x5e, 0x9d, 0xfe, 0x8e, 0x0b, 0xfd, 0xb7, 0xe0, 0x66, - 0x60, 0xf1, 0xec, 0x0a, 0xe9, 0x40, 0xce, 0x1a, 0x3a, 0x51, 0x8d, 0x29, 0xd5, 0x31, 0x42, 0x63, - 0x62, 0x11, 0x1a, 0x23, 0xac, 0xc3, 0xad, 0x90, 0x89, 0x98, 0x14, 0x7f, 0x93, 0xa4, 0x62, 0x4c, - 0xdf, 0x73, 0xfa, 0x3c, 0xca, 0x2a, 0xde, 0x77, 0x1f, 0x7b, 0x68, 0x7b, 0xe6, 0x4d, 0xd8, 0xc5, - 0x16, 0xa4, 0xdd, 0x78, 0xec, 0x1a, 0x34, 0xc7, 0x18, 0x4e, 0xf2, 0x4a, 0xad, 0xb0, 0x94, 0xaf, - 0x15, 0x56, 0x1d, 0x1a, 0xd5, 0xac, 0x37, 0xb4, 0x8d, 0xdc, 0x8a, 0x11, 0x66, 0xf5, 0x32, 0x60, - 0x56, 0x73, 0xde, 0xfe, 0x5a, 0x24, 0xd3, 0xdf, 0x00, 0xc3, 0x62, 0x4a, 0x1d, 0xda, 0xf8, 0x12, - 0x5e, 0x02, 0x4f, 0x35, 0x7e, 0xfa, 0x56, 0x94, 0x4f, 0x8d, 0x62, 0x7e, 0x35, 0x12, 0x36, 0x61, - 0x3d, 0x94, 0x37, 0x9b, 0xfa, 0x8f, 0x39, 0x2a, 0x98, 0x53, 0xe3, 0x6a, 0x98, 0xb2, 0x69, 0x4c, - 0x3a, 0x35, 0x1b, 0x74, 0x4f, 0x4d, 0x41, 0x44, 0x83, 0xa7, 0x34, 0x09, 0xe1, 0x4f, 0x39, 0xba, - 0x0f, 0x7e, 0x59, 0xd8, 0x6d, 0xfb, 0x0e, 0x24, 0x07, 0xa4, 0x8c, 0x4f, 0xa3, 0xae, 0xac, 0xd7, - 0x08, 0x4e, 0xac, 0x21, 0x91, 0x62, 0x5c, 0x5b, 0x61, 0x54, 0xf8, 0x15, 0x07, 0x69, 0x17, 0x7f, - 0xb4, 0x01, 0xf3, 0x4e, 0xe5, 0xc7, 0xce, 0x77, 0x1c, 0x80, 0x75, 0xfc, 0xa6, 0x66, 0xca, 0x5d, - 0xf6, 0xc4, 0x84, 0x7e, 0x58, 0x29, 0xea, 0xc0, 0xc0, 0x34, 0x1c, 0x8e, 0x8b, 0xe4, 0x37, 0x7a, - 0x00, 0x89, 0x81, 0xaa, 0x98, 0xc4, 0xec, 0x97, 0xfc, 0xf6, 0x4c, 0xa6, 0xca, 0x9f, 0xa8, 0x8a, - 0x29, 0x12, 0x2c, 0xe1, 0x3e, 0x24, 0xac, 0x2f, 0x6f, 0x05, 0x62, 0x1e, 0x92, 0xc5, 0x17, 0xcd, - 0x72, 0x23, 0xc3, 0x21, 0x80, 0x54, 0x85, 0xe6, 0xeb, 0x31, 0xa1, 0x6a, 0x3f, 0x33, 0x75, 0x16, - 0x61, 0xb9, 0x00, 0xf9, 0x54, 0xd5, 0xf4, 0x9e, 0xdc, 0x25, 0x32, 0xcf, 0x89, 0xce, 0x77, 0x74, - 0x77, 0x84, 0xd6, 0x12, 0x37, 0x9c, 0x13, 0x09, 0xab, 0x17, 0x7d, 0x41, 0x75, 0x2b, 0xaa, 0x52, - 0x54, 0x08, 0xad, 0x14, 0x6d, 0x7a, 0x6e, 0xd9, 0x31, 0x35, 0xa2, 0x7f, 0x88, 0xc1, 0x6a, 0x28, - 0x1e, 0xfa, 0xc0, 0x5d, 0x1d, 0xba, 0x33, 0x92, 0xa7, 0xbb, 0x2e, 0xf4, 0x2d, 0x47, 0xeb, 0x42, - 0x7b, 0x9e, 0xba, 0xd0, 0xdb, 0x63, 0xe9, 0xdd, 0x15, 0xa1, 0x5f, 0x70, 0x11, 0x15, 0xa1, 0x46, - 0xb3, 0x70, 0x50, 0x96, 0x4e, 0x6a, 0xf4, 0xaf, 0x53, 0x11, 0x5a, 0x81, 0xcc, 0xb0, 0x4e, 0x22, - 0x35, 0x9a, 0x85, 0x66, 0x23, 0x13, 0x0b, 0x56, 0x63, 0xe2, 0xa1, 0xb5, 0x96, 0xc4, 0xf8, 0xb2, - 0x4a, 0x92, 0xa2, 0xac, 0x01, 0x62, 0xd4, 0x47, 0xf5, 0x93, 0x5a, 0x53, 0x3a, 0x10, 0xeb, 0x27, - 0xc7, 0x99, 0x94, 0x53, 0x6e, 0x59, 0x01, 0xc4, 0x4e, 0xcb, 0xfd, 0x6a, 0xfe, 0x2f, 0x38, 0xc8, - 0x7a, 0xc0, 0xec, 0xf0, 0x5c, 0x3d, 0x6e, 0xce, 0xd3, 0xe3, 0x7e, 0x04, 0x2b, 0x56, 0xc6, 0x48, - 0x2d, 0xc5, 0x90, 0xfa, 0x58, 0x27, 0xb5, 0x6d, 0xa6, 0xf3, 0xcb, 0x3d, 0xf9, 0x82, 0xd5, 0xff, - 0x8f, 0xb1, 0x6e, 0x31, 0xbe, 0x86, 0x0a, 0xaf, 0xf0, 0x75, 0x9c, 0xc6, 0x25, 0x53, 0xe7, 0x35, - 0x63, 0x7d, 0x54, 0x30, 0xf1, 0x89, 0x4f, 0x91, 0xf8, 0x44, 0x78, 0xb8, 0xc4, 0x54, 0xc1, 0xf0, - 0xf4, 0x77, 0x7a, 0x6d, 0x78, 0x6f, 0xd3, 0xc8, 0xf5, 0x81, 0x5b, 0x7f, 0xc7, 0x66, 0x5a, 0xa9, - 0xaf, 0x8b, 0xdc, 0xcf, 0xaf, 0x2b, 0x4f, 0x2e, 0xd0, 0x78, 0xec, 0x0a, 0xf9, 0xd1, 0xee, 0xff, - 0x72, 0x30, 0x57, 0x69, 0x63, 0xd5, 0xa4, 0x6b, 0x5b, 0xf4, 0xfc, 0x63, 0x05, 0xda, 0x88, 0xf8, - 0x7f, 0x0b, 0xb2, 0x30, 0x7e, 0x73, 0xe4, 0x7f, 0x63, 0x08, 0x33, 0xe8, 0xcc, 0xf5, 0x4f, 0x21, - 0x9e, 0x26, 0xc6, 0x5b, 0x01, 0xca, 0x10, 0x17, 0xc7, 0xdf, 0x1b, 0x83, 0xe5, 0xcc, 0xf3, 0x21, - 0x24, 0xc9, 0x13, 0x7a, 0xb4, 0xe2, 0x3c, 0xe3, 0x77, 0xbd, 0xb0, 0xe7, 0x57, 0x7d, 0x50, 0x9b, - 0x6e, 0xf7, 0x9f, 0xe6, 0x01, 0x86, 0x69, 0x26, 0x7a, 0x0a, 0x0b, 0xee, 0x57, 0xbc, 0x68, 0x7d, - 0xc4, 0x1b, 0x72, 0x7e, 0x23, 0x7c, 0xd0, 0x91, 0xe9, 0x29, 0x2c, 0xb8, 0x9f, 0x6f, 0x0d, 0x99, - 0x85, 0x3c, 0x21, 0x1b, 0x32, 0x0b, 0x7d, 0xf1, 0x35, 0x83, 0xba, 0x70, 0x33, 0xe2, 0x01, 0x0f, - 0x7a, 0x7b, 0xb2, 0x67, 0x4e, 0xfc, 0xf7, 0x26, 0x7c, 0x09, 0x24, 0xcc, 0x20, 0x1d, 0x6e, 0x45, - 0xbe, 0x5b, 0x41, 0x3b, 0x93, 0xbe, 0xaa, 0xe1, 0xdf, 0x99, 0x00, 0xd3, 0x99, 0x73, 0x00, 0x7c, - 0x74, 0xb3, 0x1c, 0xbd, 0x33, 0xf1, 0x2b, 0x0e, 0xfe, 0xfe, 0xe4, 0xbd, 0x77, 0x61, 0x06, 0x1d, - 0x42, 0xda, 0xd5, 0x35, 0x45, 0x7c, 0x68, 0x2b, 0x95, 0x32, 0x5e, 0x1f, 0xd1, 0x66, 0xa5, 0x9c, - 0x5c, 0x8d, 0xac, 0x21, 0xa7, 0x60, 0x4b, 0x6e, 0xc8, 0x29, 0xa4, 0xf3, 0xe5, 0xdf, 0x7e, 0xdf, - 0xfd, 0x1e, 0xb6, 0xfd, 0xe1, 0x01, 0x42, 0xd8, 0xf6, 0x47, 0x04, 0x0b, 0xc2, 0x0c, 0xfa, 0x0c, - 0x96, 0xbc, 0x15, 0x6a, 0xb4, 0x39, 0xb2, 0xd2, 0xce, 0xdf, 0x8e, 0x1a, 0x76, 0xb3, 0xf4, 0x16, - 0x44, 0x87, 0x2c, 0x43, 0x0b, 0xb3, 0x43, 0x96, 0x11, 0x75, 0xd4, 0x19, 0xcb, 0x3f, 0x79, 0xca, - 0x7c, 0x43, 0xff, 0x14, 0x56, 0x9d, 0x1c, 0xfa, 0xa7, 0xd0, 0xda, 0xa0, 0x30, 0x83, 0x14, 0x58, - 0x0b, 0xaf, 0x32, 0xa1, 0x7b, 0x13, 0x15, 0xd1, 0xf8, 0xb7, 0xc7, 0xa1, 0x39, 0x53, 0xb5, 0x20, - 0x1b, 0xd2, 0xd4, 0x46, 0xc2, 0xc8, 0x8e, 0x37, 0x9d, 0xe4, 0xee, 0x04, 0x5d, 0x71, 0xc1, 0x8a, - 0x42, 0x76, 0xff, 0x23, 0x09, 0x09, 0x72, 0xed, 0x37, 0xe1, 0x86, 0xaf, 0x94, 0x80, 0x6e, 0x8f, - 0x2e, 0xb0, 0xf0, 0x5b, 0x91, 0xe3, 0xce, 0x1a, 0x5e, 0xc2, 0x72, 0xa0, 0x38, 0x80, 0xb6, 0xdd, - 0x74, 0x61, 0x05, 0x0a, 0xfe, 0xce, 0x08, 0x0c, 0x3f, 0x6f, 0xaf, 0x6f, 0xdb, 0x1e, 0x97, 0xbd, - 0x7a, 0x79, 0x47, 0xf9, 0xb3, 0x2f, 0x68, 0x94, 0xe5, 0xf7, 0x64, 0x82, 0x57, 0xae, 0x50, 0x1f, - 0x76, 0x77, 0x24, 0x8e, 0x33, 0xc3, 0xe7, 0x4e, 0x78, 0xe7, 0x4a, 0x9e, 0x90, 0x47, 0xb8, 0xd0, - 0x24, 0x8f, 0x17, 0x46, 0xa1, 0x38, 0xec, 0x9f, 0x43, 0xc6, 0x7f, 0xcf, 0xa3, 0xad, 0x31, 0x61, - 0x07, 0xbf, 0x1d, 0x8d, 0xe0, 0xdf, 0x19, 0xbf, 0x93, 0xf1, 0x4b, 0x15, 0xe6, 0x5e, 0xee, 0x8e, - 0xc4, 0x71, 0xbb, 0x45, 0x57, 0x84, 0x3b, 0x74, 0x8b, 0xc1, 0x68, 0x78, 0xe8, 0x16, 0x43, 0x42, - 0x62, 0x61, 0x66, 0xef, 0x31, 0x80, 0xdc, 0xed, 0xbf, 0x92, 0x25, 0xac, 0x0e, 0x7a, 0x68, 0x23, - 0xd0, 0x7c, 0x2a, 0xab, 0x83, 0x5e, 0xbd, 0x6f, 0x25, 0x5d, 0x46, 0xee, 0xaf, 0xe6, 0x48, 0xaa, - 0x35, 0x4f, 0x08, 0xac, 0x81, 0xbd, 0x2a, 0x64, 0x86, 0xd4, 0x12, 0x09, 0xa1, 0xd0, 0x9d, 0x50, - 0x1e, 0xa4, 0x95, 0xef, 0x63, 0xb4, 0xe4, 0x30, 0x22, 0xa3, 0x7b, 0x9f, 0x00, 0xb4, 0x0c, 0x45, - 0xa2, 0x31, 0x1c, 0xda, 0x0c, 0xf0, 0x79, 0xa2, 0xe0, 0x6e, 0xdb, 0xe6, 0xf1, 0x97, 0x4c, 0x98, - 0x96, 0xa1, 0xd0, 0x48, 0x6f, 0xef, 0x47, 0x90, 0xa6, 0xc2, 0x9c, 0x59, 0x78, 0xe3, 0xe8, 0x99, - 0x0c, 0x74, 0xf5, 0x64, 0x64, 0xaf, 0x0c, 0x8b, 0x94, 0x01, 0x4b, 0x18, 0xd1, 0x56, 0x80, 0xc5, - 0x11, 0x1d, 0xf1, 0x31, 0x59, 0x20, 0x64, 0x6c, 0x6c, 0xaf, 0x08, 0x0b, 0x36, 0x1b, 0xf3, 0x95, - 0xd6, 0x46, 0xb7, 0x43, 0xb8, 0x58, 0x03, 0x3e, 0x26, 0x69, 0xc6, 0xc4, 0x1a, 0x1a, 0x8a, 0x62, - 0xff, 0x77, 0x69, 0x50, 0x14, 0x96, 0xd4, 0x85, 0x8a, 0xc2, 0xc6, 0x8a, 0xc9, 0x97, 0xf1, 0x96, - 0xa1, 0x9c, 0xa6, 0x08, 0xd1, 0x0f, 0xfe, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x6f, 0x0a, 0xad, 0x10, - 0x0a, 0x3d, 0x00, 0x00, + // 4182 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5c, 0x4d, 0x6c, 0x1b, 0x49, + 0x76, 0x56, 0xf3, 0x4f, 0xd2, 0xa3, 0x24, 0x53, 0xa5, 0x1f, 0xd3, 0x2d, 0x59, 0x96, 0xda, 0xe3, + 0x19, 0x8d, 0xc7, 0xa6, 0x67, 0xbc, 0x33, 0x83, 0x1d, 0x8d, 0x67, 0x77, 0x48, 0x89, 0x96, 0xb8, + 0xa6, 0x49, 0x6d, 0x93, 0xf2, 0xac, 0x9d, 0x0c, 0x7a, 0x5a, 0x64, 0x49, 0x6e, 0x0c, 0xd9, 0xcd, + 0xe9, 0x6e, 0x2a, 0xd6, 0xe6, 0x90, 0x64, 0x83, 0x20, 0x1b, 0xe4, 0x12, 0x24, 0x87, 0x4c, 0x4e, + 0x59, 0x24, 0x39, 0xee, 0x62, 0x0f, 0x41, 0x10, 0x20, 0x97, 0x00, 0xb9, 0x25, 0x40, 0x90, 0x1c, + 0x93, 0x5c, 0xf6, 0x10, 0x20, 0x87, 0x45, 0x02, 0x4c, 0x2e, 0x39, 0xe4, 0x10, 0x04, 0x5d, 0x55, + 0xfd, 0xff, 0x43, 0xd2, 0x92, 0x33, 0x01, 0xf6, 0x64, 0x75, 0xd5, 0xab, 0x57, 0xaf, 0xaa, 0xde, + 0x7b, 0xf5, 0xde, 0xf7, 0x8a, 0x86, 0xf7, 0x4e, 0x15, 0xf3, 0xf9, 0xf0, 0xb8, 0xd4, 0xd1, 0xfa, + 0xf7, 0x3a, 0x9a, 0x6a, 0xca, 0x8a, 0x8a, 0xf5, 0xbb, 0x86, 0xa9, 0xe9, 0xf2, 0x29, 0xbe, 0xab, + 0xa8, 0x26, 0xd6, 0x4f, 0xe4, 0x0e, 0xbe, 0x67, 0x0c, 0x70, 0xe7, 0x5e, 0xc7, 0x50, 0x4a, 0x03, + 0x5d, 0x33, 0x35, 0x94, 0xb3, 0xfe, 0x3c, 0x7b, 0x87, 0xdf, 0x3c, 0xd5, 0xb4, 0xd3, 0x1e, 0xbe, + 0x47, 0x5a, 0x8f, 0x87, 0x27, 0xf7, 0xba, 0xd8, 0xe8, 0xe8, 0xca, 0xc0, 0xd4, 0x74, 0x4a, 0xc9, + 0xdf, 0x08, 0x52, 0x98, 0x4a, 0x1f, 0x1b, 0xa6, 0xdc, 0x1f, 0x30, 0x82, 0x8d, 0x20, 0xc1, 0xaf, + 0xe8, 0xf2, 0x60, 0x80, 0x75, 0x83, 0xf6, 0x0b, 0xab, 0xb0, 0xbc, 0x8f, 0xcd, 0xc3, 0xde, 0xf0, + 0x54, 0x51, 0x6b, 0xea, 0x89, 0x26, 0xe2, 0x2f, 0x86, 0xd8, 0x30, 0x85, 0x7f, 0xe2, 0x60, 0x25, + 0xd0, 0x61, 0x0c, 0x34, 0xd5, 0xc0, 0x08, 0x41, 0x46, 0x95, 0xfb, 0xb8, 0xc8, 0x6d, 0x72, 0xdb, + 0xb3, 0x22, 0xf9, 0x1b, 0xdd, 0x82, 0x85, 0x33, 0xac, 0x76, 0x35, 0x5d, 0x3a, 0xc3, 0xba, 0xa1, + 0x68, 0x6a, 0x31, 0x45, 0x7a, 0xe7, 0x69, 0xeb, 0x13, 0xda, 0x88, 0xf6, 0x61, 0xa6, 0x2f, 0xab, + 0xca, 0x09, 0x36, 0xcc, 0x62, 0x7a, 0x33, 0xbd, 0x9d, 0xbf, 0xff, 0x56, 0x89, 0x2e, 0xb5, 0x14, + 0x39, 0x57, 0xe9, 0x31, 0xa3, 0xae, 0xaa, 0xa6, 0x7e, 0x2e, 0x3a, 0x83, 0xf9, 0x0f, 0x61, 0xde, + 0xd7, 0x85, 0x0a, 0x90, 0xfe, 0x1c, 0x9f, 0x33, 0x99, 0xac, 0x3f, 0xd1, 0x32, 0x64, 0xcf, 0xe4, + 0xde, 0x10, 0x33, 0x49, 0xe8, 0xc7, 0x4e, 0xea, 0x9b, 0x9c, 0xb0, 0x01, 0xeb, 0xce, 0x6c, 0xbb, + 0xf2, 0x40, 0x3e, 0x56, 0x7a, 0x8a, 0xa9, 0x60, 0xc3, 0x5e, 0xfa, 0xa7, 0x70, 0x3d, 0xa6, 0x9f, + 0xed, 0xc0, 0x03, 0x98, 0xeb, 0x78, 0xda, 0x8b, 0x1c, 0x59, 0x4a, 0xd1, 0x5e, 0x4a, 0x60, 0xe4, + 0xb9, 0xe8, 0xa3, 0x16, 0xfe, 0x33, 0x0d, 0x85, 0x20, 0x09, 0x7a, 0x00, 0xd3, 0x06, 0xd6, 0xcf, + 0x94, 0x0e, 0xdd, 0xd7, 0xfc, 0xfd, 0xcd, 0x38, 0x6e, 0xa5, 0x16, 0xa5, 0x3b, 0x98, 0x12, 0xed, + 0x21, 0xe8, 0x08, 0x0a, 0x67, 0x5a, 0x6f, 0xd8, 0xc7, 0x12, 0x7e, 0x31, 0x90, 0x55, 0xe7, 0x00, + 0xf2, 0xf7, 0xb7, 0x63, 0xd9, 0x3c, 0x21, 0x03, 0xaa, 0x36, 0xfd, 0xc1, 0x94, 0x78, 0xe5, 0xcc, + 0xdf, 0xc4, 0xff, 0x15, 0x07, 0xd3, 0x6c, 0x36, 0xf4, 0x01, 0x64, 0xcc, 0xf3, 0x01, 0x95, 0x6e, + 0xe1, 0xfe, 0xad, 0x51, 0xd2, 0x95, 0xda, 0xe7, 0x03, 0x2c, 0x92, 0x21, 0x82, 0x09, 0x19, 0xeb, + 0x0b, 0xe5, 0x61, 0xfa, 0xa8, 0xf1, 0xa8, 0xd1, 0xfc, 0xa4, 0x51, 0x98, 0x42, 0xab, 0x80, 0x76, + 0x9b, 0x8d, 0xb6, 0xd8, 0xac, 0xd7, 0xab, 0xa2, 0xd4, 0xaa, 0x8a, 0x4f, 0x6a, 0xbb, 0xd5, 0x02, + 0x87, 0x5e, 0x83, 0xcd, 0x27, 0xcd, 0xfa, 0xd1, 0xe3, 0xaa, 0x54, 0xde, 0xdd, 0xad, 0xb6, 0x5a, + 0xb5, 0x4a, 0xad, 0x5e, 0x6b, 0x3f, 0x95, 0x76, 0x9b, 0x8d, 0x56, 0x5b, 0x2c, 0xd7, 0x1a, 0xed, + 0x56, 0x21, 0x85, 0xb6, 0xa0, 0xb8, 0x2f, 0x36, 0x8f, 0x0e, 0xa5, 0x08, 0x1e, 0x69, 0x3e, 0xfd, + 0xa3, 0x0a, 0xc7, 0xff, 0x80, 0x83, 0x2b, 0x81, 0x35, 0xa2, 0xb2, 0x6f, 0x11, 0x77, 0xc7, 0xdd, + 0x1b, 0xef, 0x62, 0xee, 0x44, 0x2d, 0x06, 0x20, 0xd7, 0x6c, 0xd4, 0x6b, 0x0d, 0x6b, 0x01, 0x79, + 0x98, 0x6e, 0x3e, 0x7c, 0x48, 0x3e, 0x52, 0x95, 0x1c, 0x9d, 0x50, 0x58, 0x80, 0xb9, 0x43, 0x5d, + 0x3b, 0xc6, 0xb6, 0x8a, 0x95, 0x61, 0x9e, 0x7d, 0x33, 0x95, 0x7a, 0x1b, 0xb2, 0x3a, 0x96, 0xbb, + 0xe7, 0xec, 0xf4, 0xf9, 0x12, 0x35, 0xdb, 0x92, 0x6d, 0xb6, 0xa5, 0x8a, 0xa6, 0xf5, 0x9e, 0x58, + 0x2a, 0x2c, 0x52, 0x42, 0xe1, 0xab, 0x0c, 0x2c, 0xed, 0xea, 0x58, 0x36, 0x31, 0x95, 0x96, 0xb1, + 0x8e, 0x34, 0xcf, 0x07, 0xb0, 0x60, 0xa9, 0x60, 0x47, 0x31, 0xcf, 0x25, 0x5d, 0x56, 0x4f, 0x31, + 0xd3, 0x8e, 0x15, 0x7b, 0x07, 0x76, 0x59, 0xaf, 0x68, 0x75, 0x8a, 0xf3, 0x1d, 0xef, 0x27, 0xaa, + 0xc1, 0x12, 0xd3, 0x2e, 0x9f, 0xd6, 0xa7, 0xfd, 0x5a, 0x4f, 0xa5, 0xf0, 0x68, 0x3d, 0x3a, 0xf3, + 0xb7, 0x28, 0xd8, 0x40, 0x8f, 0x00, 0x06, 0xb2, 0x2e, 0xf7, 0xb1, 0x89, 0x75, 0xa3, 0x98, 0xf1, + 0xbb, 0x80, 0x88, 0xd5, 0x94, 0x0e, 0x1d, 0x6a, 0xea, 0x02, 0x3c, 0xc3, 0xd1, 0xbe, 0x65, 0x33, + 0x1d, 0x1d, 0x9b, 0x46, 0x31, 0x4b, 0x38, 0x6d, 0x27, 0x71, 0x6a, 0x51, 0x52, 0xc2, 0xa6, 0x92, + 0xfe, 0xb2, 0xc2, 0x89, 0xf6, 0x68, 0xd4, 0x84, 0x15, 0x7b, 0x81, 0x9a, 0x6a, 0x62, 0xd5, 0x94, + 0x0c, 0x6d, 0xa8, 0x77, 0x70, 0x31, 0x47, 0x76, 0x69, 0x2d, 0xb0, 0x44, 0x4a, 0xd3, 0x22, 0x24, + 0x22, 0xdb, 0x1a, 0x5f, 0x23, 0x7a, 0x06, 0xbc, 0xdc, 0xe9, 0x60, 0xc3, 0x50, 0xe8, 0x5e, 0x48, + 0x3a, 0xfe, 0x62, 0xa8, 0xe8, 0xb8, 0x8f, 0x55, 0xd3, 0x28, 0x4e, 0xfb, 0xb9, 0xb6, 0xb5, 0x81, + 0xd6, 0xd3, 0x4e, 0xcf, 0x45, 0x97, 0x46, 0xbc, 0xe6, 0x1b, 0xee, 0xe9, 0x31, 0xf8, 0x8f, 0xe0, + 0x4a, 0x60, 0x53, 0x26, 0x71, 0x7e, 0xfc, 0x0e, 0xcc, 0x79, 0x77, 0x62, 0x22, 0xc7, 0xf9, 0xbb, + 0x29, 0x58, 0x8a, 0xd8, 0x03, 0x74, 0x00, 0x33, 0x86, 0x2a, 0x0f, 0x8c, 0xe7, 0x9a, 0xc9, 0xf4, + 0xf7, 0x76, 0xc2, 0x96, 0x95, 0x5a, 0x8c, 0x96, 0x7e, 0x1e, 0x4c, 0x89, 0xce, 0x68, 0x54, 0x81, + 0x1c, 0xdd, 0xcf, 0xa0, 0xfb, 0x8a, 0xe2, 0x43, 0xdb, 0x1c, 0x2e, 0x6c, 0x24, 0xff, 0x0e, 0x2c, + 0xf8, 0x67, 0x40, 0x37, 0x20, 0x6f, 0xcf, 0x20, 0x29, 0x5d, 0xb6, 0x56, 0xb0, 0x9b, 0x6a, 0x5d, + 0xfe, 0x2d, 0x98, 0xf3, 0x32, 0x43, 0x6b, 0x30, 0xcb, 0x14, 0xc2, 0x21, 0x9f, 0xa1, 0x0d, 0xb5, + 0xae, 0x63, 0xd3, 0xdf, 0x82, 0x65, 0xbf, 0x9e, 0x31, 0x53, 0x7e, 0xdd, 0x59, 0x03, 0xdd, 0x8b, + 0x05, 0xff, 0x1a, 0x6c, 0x39, 0x85, 0x3f, 0xce, 0x42, 0x21, 0x68, 0x34, 0xe8, 0x01, 0x64, 0x8f, + 0x7b, 0x5a, 0xe7, 0x73, 0x36, 0xf6, 0xb5, 0x38, 0xeb, 0x2a, 0x55, 0x2c, 0x2a, 0xda, 0x7a, 0x30, + 0x25, 0xd2, 0x41, 0xd6, 0xe8, 0xbe, 0x36, 0x54, 0x4d, 0xb6, 0x7b, 0xf1, 0xa3, 0x1f, 0x5b, 0x54, + 0xee, 0x68, 0x32, 0x08, 0xed, 0x41, 0x9e, 0xaa, 0x9d, 0xd4, 0xd7, 0xba, 0xb8, 0x98, 0x26, 0x3c, + 0x6e, 0xc6, 0xf2, 0x28, 0x13, 0xda, 0xc7, 0x5a, 0x17, 0x8b, 0x20, 0x3b, 0x7f, 0xf3, 0xf3, 0x90, + 0xf7, 0xc8, 0xc6, 0x0f, 0x21, 0xef, 0x99, 0x0c, 0x5d, 0x85, 0xe9, 0x13, 0x43, 0x72, 0x9c, 0xf0, + 0xac, 0x98, 0x3b, 0x31, 0x88, 0x3f, 0xbd, 0x01, 0x79, 0x22, 0x85, 0x74, 0xd2, 0x93, 0x4f, 0x8d, + 0x62, 0x6a, 0x33, 0x6d, 0x9d, 0x11, 0x69, 0x7a, 0x68, 0xb5, 0xa0, 0x3b, 0xc0, 0x1c, 0x8a, 0x44, + 0xe9, 0x4e, 0x75, 0x6d, 0x38, 0x20, 0x42, 0xce, 0x8a, 0xec, 0xf6, 0x23, 0x13, 0xed, 0x5b, 0xed, + 0xfc, 0x9f, 0xa7, 0x00, 0x5c, 0x01, 0xd1, 0x03, 0xc8, 0x90, 0x35, 0x51, 0xc7, 0xbf, 0x3d, 0xc6, + 0x9a, 0x4a, 0x64, 0x61, 0x64, 0x94, 0xf0, 0x6f, 0x1c, 0x64, 0x08, 0x9b, 0xe0, 0x0d, 0xd6, 0xaa, + 0x35, 0xf6, 0xeb, 0x55, 0xa9, 0xd1, 0xdc, 0xab, 0x4a, 0x9f, 0x88, 0xb5, 0x76, 0x55, 0x2c, 0x70, + 0x68, 0x0d, 0xae, 0x7a, 0xdb, 0xc5, 0x6a, 0x79, 0xaf, 0x2a, 0x4a, 0xcd, 0x46, 0xfd, 0x69, 0x21, + 0x85, 0x78, 0x58, 0x7d, 0x7c, 0x54, 0x6f, 0xd7, 0xc2, 0x7d, 0x69, 0xb4, 0x0e, 0x45, 0x4f, 0x1f, + 0xe3, 0xc1, 0xd8, 0x66, 0x2c, 0xb6, 0x9e, 0x5e, 0xfa, 0x27, 0xeb, 0xcc, 0x22, 0x01, 0xae, 0x79, + 0xe7, 0xf4, 0x8f, 0xcd, 0x91, 0x0b, 0xd1, 0xba, 0x33, 0xbd, 0x34, 0x3e, 0x0e, 0xd3, 0x84, 0xa4, + 0x32, 0xef, 0x68, 0x00, 0xd1, 0xf0, 0x4f, 0x60, 0xde, 0x77, 0x31, 0x58, 0x61, 0x1e, 0xf3, 0x64, + 0x5d, 0xe9, 0xf8, 0xdc, 0x24, 0xa1, 0x0f, 0xb7, 0x9d, 0x16, 0xe7, 0xed, 0xd6, 0x8a, 0xd5, 0x68, + 0x9d, 0x65, 0x4f, 0xe9, 0x2b, 0x26, 0xa3, 0x49, 0x11, 0x1a, 0x20, 0x4d, 0x84, 0x40, 0xf8, 0x59, + 0x0a, 0x72, 0x4c, 0x21, 0x6e, 0x79, 0xae, 0x26, 0x1f, 0x4b, 0xbb, 0x95, 0xb2, 0xf4, 0x59, 0x64, + 0xca, 0x6f, 0x91, 0xe8, 0x00, 0x16, 0xbc, 0xfe, 0xfb, 0x85, 0x1d, 0x5c, 0x6e, 0xf9, 0xcf, 0xd9, + 0xeb, 0x44, 0x5e, 0xb0, 0x90, 0x72, 0xfe, 0xcc, 0xdb, 0x86, 0x2a, 0xb0, 0x10, 0xb8, 0x02, 0x32, + 0xa3, 0xaf, 0x80, 0xf9, 0x8e, 0xcf, 0x1b, 0x96, 0x61, 0xc9, 0xf6, 0xde, 0x3d, 0x2c, 0x99, 0xcc, + 0xbb, 0xb3, 0x2b, 0xaa, 0x10, 0xf2, 0xfa, 0xc8, 0x25, 0xb6, 0xdb, 0xf8, 0x8f, 0x01, 0x85, 0x65, + 0x9d, 0xc8, 0x55, 0x0f, 0x61, 0x29, 0xe2, 0x5e, 0x41, 0x25, 0x98, 0x25, 0x47, 0x65, 0x28, 0x26, + 0x66, 0x61, 0x6b, 0x58, 0x22, 0x97, 0xc4, 0xa2, 0x1f, 0xe8, 0xf8, 0x04, 0xeb, 0x3a, 0xee, 0x12, + 0x9b, 0x8c, 0xa4, 0x77, 0x48, 0x84, 0xdf, 0xe4, 0x60, 0xc6, 0x6e, 0x47, 0x3b, 0x30, 0x63, 0xe0, + 0x53, 0x7a, 0xe7, 0xd1, 0xb9, 0x36, 0x82, 0x63, 0x4b, 0x2d, 0x46, 0xc0, 0x02, 0x7c, 0x9b, 0xde, + 0x0a, 0xf0, 0x7d, 0x5d, 0x13, 0x2d, 0xfe, 0x2f, 0x39, 0x58, 0xda, 0xc3, 0x3d, 0x1c, 0x0c, 0x8d, + 0x92, 0xdc, 0xba, 0x37, 0x9a, 0x48, 0xf9, 0xa3, 0x89, 0x08, 0x56, 0x09, 0xd1, 0xc4, 0x85, 0x6e, + 0xd8, 0x55, 0x58, 0xf6, 0xcf, 0x46, 0xef, 0x14, 0xe1, 0x3f, 0xd2, 0xb0, 0x61, 0xe9, 0x82, 0xae, + 0xf5, 0x7a, 0x58, 0x3f, 0x1c, 0x1e, 0xf7, 0x14, 0xe3, 0xf9, 0x04, 0x8b, 0xbb, 0x0a, 0xd3, 0xaa, + 0xd6, 0xf5, 0x18, 0x4f, 0xce, 0xfa, 0xac, 0x75, 0x51, 0x15, 0x16, 0x83, 0xb1, 0xdd, 0x39, 0xf3, + 0xfc, 0xf1, 0x91, 0x5d, 0xe1, 0x2c, 0x78, 0x6d, 0xf1, 0x30, 0x63, 0x45, 0xa5, 0x9a, 0xda, 0x3b, + 0x27, 0x16, 0x33, 0x23, 0x3a, 0xdf, 0x48, 0x0c, 0x86, 0x69, 0xdf, 0x70, 0xc2, 0xb4, 0xc4, 0x15, + 0x25, 0x45, 0x6c, 0x9f, 0x85, 0x2c, 0x3e, 0x47, 0x58, 0x7f, 0x30, 0x26, 0xeb, 0x91, 0x9e, 0xe0, + 0x22, 0xa7, 0x78, 0x09, 0xe6, 0xfb, 0x77, 0x1c, 0xdc, 0x88, 0x5d, 0x02, 0x8b, 0x33, 0xba, 0x70, + 0x65, 0x40, 0x3b, 0x9c, 0x4d, 0xa0, 0x56, 0xf6, 0xe1, 0xc8, 0x4d, 0x60, 0xd9, 0x35, 0x6b, 0xf5, + 0x6d, 0xc3, 0xc2, 0xc0, 0xd7, 0xc8, 0x97, 0x61, 0x29, 0x82, 0x6c, 0xa2, 0xc5, 0xfc, 0x9c, 0x83, + 0x4d, 0x57, 0x94, 0x23, 0x75, 0x70, 0x79, 0xea, 0xdb, 0x76, 0x75, 0x8b, 0xba, 0xfc, 0xf7, 0xc2, + 0x6b, 0x8f, 0x9e, 0xf0, 0x55, 0x59, 0xf0, 0x4d, 0xd8, 0x4a, 0x98, 0x9a, 0x99, 0xf3, 0xcf, 0x32, + 0xb0, 0xf5, 0x44, 0xee, 0x29, 0x5d, 0x27, 0x7a, 0x8c, 0xc0, 0x21, 0x92, 0xb7, 0xa4, 0x13, 0xb2, + 0x00, 0xea, 0xb5, 0x1e, 0x38, 0x56, 0x3b, 0x8a, 0xff, 0x18, 0xd7, 0xe1, 0x25, 0x66, 0x7e, 0x4f, + 0x23, 0x32, 0xbf, 0x0f, 0xc6, 0x97, 0x35, 0x29, 0x0f, 0x3c, 0x0a, 0x3a, 0x98, 0xf7, 0xc7, 0xe7, + 0x9b, 0xa0, 0x05, 0x17, 0xb6, 0xe2, 0xaf, 0x33, 0x55, 0xfb, 0x9b, 0x0c, 0x08, 0x49, 0xab, 0x67, + 0x3e, 0x44, 0x84, 0xd9, 0x8e, 0xa6, 0x9e, 0x28, 0x7a, 0x1f, 0x77, 0x59, 0xca, 0xf1, 0xee, 0x38, + 0x9b, 0xc7, 0x1c, 0xc8, 0xae, 0x3d, 0x56, 0x74, 0xd9, 0xa0, 0x22, 0x4c, 0xf7, 0xb1, 0x61, 0xc8, + 0xa7, 0xb6, 0x58, 0xf6, 0x27, 0xff, 0x93, 0x34, 0xcc, 0x3a, 0x43, 0x90, 0x1a, 0xd2, 0x60, 0xea, + 0xbe, 0xf6, 0x5f, 0x46, 0x80, 0x97, 0x57, 0xe6, 0xd4, 0x4b, 0x28, 0x73, 0xd7, 0xa7, 0xcc, 0xd4, + 0x1c, 0xf6, 0x5e, 0x4a, 0xec, 0x04, 0xbd, 0xfe, 0xda, 0x15, 0x50, 0xf8, 0x65, 0x40, 0x75, 0xc5, + 0x60, 0xa9, 0x9b, 0xe3, 0x96, 0xac, 0x4c, 0x4d, 0x7e, 0x21, 0x61, 0xd5, 0xd4, 0x15, 0x16, 0xae, + 0x67, 0x45, 0xe8, 0xcb, 0x2f, 0xaa, 0xb4, 0xc5, 0x0a, 0xe9, 0x0d, 0x53, 0xd6, 0x4d, 0x45, 0x3d, + 0x95, 0x4c, 0xed, 0x73, 0xec, 0x80, 0xc1, 0x76, 0x6b, 0xdb, 0x6a, 0x14, 0xfe, 0x3d, 0x05, 0x4b, + 0x3e, 0xf6, 0x4c, 0x27, 0x3f, 0x84, 0x69, 0x97, 0xb7, 0x2f, 0x8c, 0x8f, 0xa0, 0x2e, 0xd1, 0x6d, + 0xb3, 0x47, 0xa0, 0xeb, 0x00, 0x2a, 0x7e, 0x61, 0xfa, 0xe6, 0x9d, 0xb5, 0x5a, 0xc8, 0x9c, 0xfc, + 0x6f, 0x71, 0x4e, 0xa6, 0x6f, 0xca, 0xe6, 0x90, 0x64, 0x95, 0xcc, 0x45, 0xe3, 0xae, 0xc4, 0xee, + 0x18, 0x3a, 0xef, 0xac, 0x58, 0x70, 0x7a, 0x1a, 0xe4, 0xb6, 0x31, 0xd0, 0xbe, 0x83, 0xb3, 0x76, + 0x34, 0xb5, 0xab, 0x98, 0x2e, 0xce, 0x7a, 0x35, 0x94, 0x20, 0xd0, 0xee, 0x8a, 0x95, 0x57, 0xd9, + 0xc8, 0xaa, 0xd3, 0xca, 0x7f, 0x01, 0x59, 0x7a, 0x1c, 0x63, 0x82, 0x05, 0xe8, 0x63, 0xc8, 0x19, + 0x44, 0xe2, 0x20, 0x30, 0x12, 0xb5, 0x27, 0xde, 0x15, 0x8a, 0x6c, 0x9c, 0xf0, 0x2d, 0xe0, 0xdd, + 0x8b, 0x69, 0x1f, 0x9b, 0xe3, 0x5f, 0xbf, 0x3b, 0xd6, 0x1a, 0x84, 0x3f, 0x4c, 0xc1, 0x5a, 0x24, + 0x83, 0xc9, 0x60, 0x0f, 0x74, 0x10, 0x58, 0xc9, 0xdb, 0xe1, 0x1b, 0x3b, 0xc4, 0x3c, 0x72, 0x45, + 0xfc, 0xaf, 0x5f, 0xec, 0x30, 0x2b, 0x13, 0x1f, 0x66, 0xe8, 0x1c, 0xe9, 0xce, 0xfc, 0x24, 0x05, + 0x68, 0x1f, 0x9b, 0x4e, 0xaa, 0xcc, 0xb6, 0x34, 0xc6, 0xdf, 0x70, 0x2f, 0xe1, 0x6f, 0xbe, 0xe3, + 0xf3, 0x37, 0xd4, 0x63, 0xdd, 0xf6, 0x54, 0x4e, 0x02, 0x53, 0x27, 0xde, 0x96, 0x31, 0xe9, 0x29, + 0x8d, 0xf9, 0xc7, 0x4b, 0x4f, 0x2f, 0xe8, 0x56, 0xfe, 0x95, 0x83, 0x25, 0x9f, 0xd0, 0x4c, 0x83, + 0xee, 0x02, 0x92, 0xcf, 0x64, 0xa5, 0x27, 0x5b, 0x82, 0xd9, 0xe9, 0x3f, 0x83, 0x03, 0x16, 0x9d, + 0x1e, 0x7b, 0x18, 0x7a, 0x04, 0x4b, 0x7d, 0xf9, 0x85, 0xd2, 0x1f, 0xf6, 0x25, 0xb6, 0xcf, 0x86, + 0xf2, 0x7d, 0x1b, 0x38, 0x5c, 0x0b, 0x01, 0xe8, 0x35, 0xd5, 0x7c, 0xff, 0x5d, 0x8a, 0xa0, 0x2f, + 0xb2, 0x71, 0x4c, 0x79, 0x94, 0xef, 0x63, 0x74, 0x08, 0x4b, 0x7d, 0x45, 0x0d, 0x31, 0x4b, 0x8f, + 0x64, 0x46, 0x0d, 0x7c, 0x91, 0x0d, 0x76, 0x39, 0x0a, 0x82, 0x37, 0xe8, 0x65, 0xcb, 0x0d, 0x56, + 0x9a, 0x7a, 0xde, 0x60, 0x31, 0x44, 0xc3, 0xb6, 0x65, 0x3f, 0xb2, 0xda, 0x74, 0x33, 0x6c, 0x36, + 0xac, 0xf4, 0x12, 0x5b, 0x78, 0xfa, 0x9f, 0xb4, 0xd7, 0x82, 0x43, 0xd4, 0xe8, 0x43, 0x48, 0xeb, + 0x83, 0x0e, 0x33, 0xdf, 0x37, 0xc6, 0xe0, 0x5f, 0x12, 0x0f, 0x77, 0x0f, 0xa6, 0x44, 0x6b, 0x14, + 0xff, 0x47, 0x69, 0x48, 0x8b, 0x87, 0xbb, 0xe8, 0x63, 0x5f, 0x89, 0xe5, 0xce, 0x98, 0x5c, 0xbc, + 0x15, 0x96, 0x7f, 0x48, 0x45, 0x95, 0x58, 0x8a, 0xb0, 0xbc, 0x2b, 0x56, 0xcb, 0xed, 0xaa, 0xb4, + 0x57, 0xad, 0x57, 0xdb, 0x55, 0x89, 0x56, 0x89, 0x0a, 0x1c, 0x5a, 0x87, 0xe2, 0xe1, 0x51, 0xa5, + 0x5e, 0x6b, 0x1d, 0x48, 0x47, 0x0d, 0xfb, 0x2f, 0xd6, 0x9b, 0x42, 0x05, 0x98, 0xab, 0xd7, 0x5a, + 0x6d, 0xd6, 0xd0, 0x2a, 0xa4, 0xad, 0x96, 0xfd, 0x6a, 0x5b, 0xda, 0x2d, 0x1f, 0x96, 0x77, 0x6b, + 0xed, 0xa7, 0x85, 0x0c, 0xe2, 0x61, 0xd5, 0xcf, 0xbb, 0xd5, 0x28, 0x1f, 0xb6, 0x0e, 0x9a, 0xed, + 0x42, 0x16, 0x21, 0x58, 0x20, 0xe3, 0xed, 0xa6, 0x56, 0x21, 0x67, 0x71, 0xd8, 0xad, 0x37, 0x1b, + 0x8e, 0x0c, 0xd3, 0x68, 0x19, 0x0a, 0xf6, 0xcc, 0x62, 0xb5, 0xbc, 0x47, 0x00, 0xbd, 0x19, 0xb4, + 0x08, 0xf3, 0xd5, 0xef, 0x1d, 0x96, 0x1b, 0x7b, 0x36, 0xe1, 0x2c, 0xda, 0x84, 0x75, 0xaf, 0x38, + 0x12, 0x1b, 0x55, 0xdd, 0x23, 0xa0, 0x5c, 0xab, 0x00, 0xe8, 0x1a, 0x14, 0x58, 0x01, 0x6c, 0xb7, + 0xd9, 0xd8, 0xab, 0xb5, 0x6b, 0xcd, 0x46, 0x21, 0x4f, 0x11, 0xbc, 0x25, 0x00, 0x4b, 0x72, 0xc6, + 0x6c, 0x6e, 0x34, 0xac, 0x37, 0x4f, 0x61, 0x3d, 0x1b, 0xb1, 0xfe, 0x79, 0x0a, 0x56, 0x28, 0x64, + 0x6d, 0x03, 0xe4, 0xb6, 0xaf, 0xda, 0x86, 0x02, 0xc5, 0xbb, 0xa4, 0xe0, 0x2d, 0xb0, 0x40, 0xdb, + 0x9f, 0xd8, 0x79, 0x87, 0x5d, 0x5e, 0x4a, 0x79, 0xca, 0x4b, 0xb5, 0x60, 0x16, 0x76, 0xdb, 0x5f, + 0x88, 0x09, 0xcc, 0x96, 0x94, 0xd8, 0x3f, 0x8e, 0x48, 0x13, 0xee, 0x26, 0x73, 0x4b, 0x0a, 0xa1, + 0x2e, 0x92, 0xc5, 0x5f, 0xd0, 0xcb, 0x3d, 0x84, 0xd5, 0xa0, 0xbc, 0xcc, 0xa0, 0xef, 0x84, 0xca, + 0x25, 0x8e, 0xdb, 0x75, 0x68, 0x1d, 0x0a, 0xe1, 0x87, 0x29, 0x98, 0xb1, 0x9b, 0xad, 0xf0, 0xc6, + 0xf2, 0x4b, 0x3e, 0xa4, 0x74, 0xd6, 0x6a, 0x71, 0x80, 0x57, 0x6f, 0xa1, 0x23, 0x15, 0x2c, 0x74, + 0x44, 0x9e, 0x73, 0x3a, 0xf2, 0x9c, 0xbf, 0x0d, 0xf3, 0x1d, 0x4b, 0x7c, 0x45, 0x53, 0x25, 0x53, + 0xe9, 0xdb, 0x40, 0x68, 0xb8, 0x30, 0xd9, 0xb6, 0x1f, 0x1c, 0x88, 0x73, 0xf6, 0x00, 0xab, 0x09, + 0x6d, 0xc2, 0x1c, 0x29, 0x54, 0x4a, 0xa6, 0x26, 0x0d, 0x0d, 0x5c, 0xcc, 0x12, 0x58, 0x08, 0x48, + 0x5b, 0x5b, 0x3b, 0x32, 0x30, 0xba, 0x07, 0x8b, 0x04, 0xc4, 0x97, 0xbc, 0x32, 0xe7, 0x2c, 0x69, + 0x58, 0xd4, 0x44, 0x7a, 0x5b, 0x8e, 0xf4, 0xc2, 0x5f, 0x73, 0xb0, 0x42, 0xe1, 0xb1, 0xa0, 0xfe, + 0x8e, 0xaa, 0xf0, 0x78, 0x55, 0x34, 0x70, 0x7d, 0x46, 0x32, 0x7c, 0x55, 0xe8, 0x40, 0x11, 0x56, + 0x83, 0xf3, 0x31, 0x48, 0xe0, 0xa7, 0x29, 0x58, 0xb6, 0x62, 0x39, 0xbb, 0xe3, 0xb2, 0xc3, 0xed, + 0x09, 0x8e, 0x3e, 0xb0, 0x99, 0x99, 0xd0, 0x66, 0x1e, 0x04, 0x13, 0xee, 0x37, 0xbd, 0xd1, 0x68, + 0x70, 0x05, 0xaf, 0x6a, 0x2f, 0x7f, 0xcc, 0xc1, 0x4a, 0x60, 0x3e, 0x66, 0x60, 0x1f, 0x05, 0x33, + 0x88, 0x9b, 0x31, 0xf2, 0xbd, 0x54, 0x0e, 0xf1, 0x9e, 0x1d, 0xbb, 0x4f, 0x66, 0xc7, 0xff, 0x98, + 0x82, 0xeb, 0xee, 0x2d, 0x48, 0xde, 0x16, 0x74, 0x27, 0x80, 0xc0, 0x2e, 0x56, 0xc2, 0xff, 0x6e, + 0xd0, 0x43, 0xdf, 0x0f, 0x5f, 0xcc, 0x11, 0x22, 0x25, 0x79, 0xea, 0x48, 0xe4, 0x38, 0x33, 0x29, + 0x72, 0x7c, 0x21, 0x0d, 0xf8, 0x35, 0x2f, 0x28, 0xee, 0x17, 0x9f, 0x69, 0xc2, 0x98, 0xd5, 0xa5, + 0xf7, 0xe1, 0x2a, 0x49, 0x17, 0x9c, 0xd7, 0x33, 0x76, 0xc1, 0x9e, 0xfa, 0xd0, 0x19, 0x71, 0xc5, + 0xea, 0x76, 0xde, 0x83, 0xb0, 0x8a, 0x4a, 0x57, 0xf8, 0x2a, 0x03, 0xab, 0x56, 0x3a, 0xd1, 0x32, + 0xe5, 0xd3, 0x49, 0x6a, 0x0d, 0xbf, 0x14, 0x86, 0x6e, 0x53, 0xfe, 0x63, 0x89, 0xe6, 0x3a, 0x0e, + 0x62, 0x8b, 0x4a, 0xb0, 0x64, 0x98, 0xf2, 0x29, 0x71, 0x07, 0xb2, 0x7e, 0x8a, 0x4d, 0x69, 0x20, + 0x9b, 0xcf, 0x99, 0xad, 0x2f, 0xb2, 0xae, 0x36, 0xe9, 0x39, 0x94, 0xcd, 0xe7, 0x97, 0x74, 0x90, + 0xe8, 0x3b, 0x41, 0xa7, 0xf0, 0xd6, 0x88, 0xb5, 0x24, 0xe8, 0xd6, 0xf7, 0x62, 0xe0, 0xfd, 0x77, + 0x46, 0xb0, 0x1c, 0x0d, 0xeb, 0x5f, 0x1c, 0xce, 0xfe, 0x9a, 0x2b, 0x03, 0xd7, 0xe0, 0x6a, 0x68, + 0xf1, 0xec, 0x0a, 0x39, 0x85, 0xa2, 0xd5, 0x75, 0xa4, 0x1a, 0x13, 0xaa, 0x63, 0x8c, 0xc6, 0xa4, + 0x62, 0x34, 0x46, 0x58, 0x83, 0x6b, 0x11, 0x13, 0x31, 0x29, 0xfe, 0x22, 0x4b, 0xc5, 0x98, 0xbc, + 0x48, 0xf5, 0x69, 0x9c, 0x55, 0xbc, 0xeb, 0x3d, 0xf6, 0xc8, 0x7a, 0xce, 0xab, 0xb0, 0x8b, 0x1b, + 0x90, 0xf7, 0xd2, 0xb1, 0x6b, 0xd0, 0x1c, 0x61, 0x38, 0xd9, 0x0b, 0xd5, 0xce, 0x72, 0x81, 0xda, + 0x59, 0xdd, 0x35, 0xaa, 0x69, 0x7f, 0x2c, 0x1c, 0xbb, 0x15, 0x09, 0x66, 0xf5, 0x2c, 0x64, 0x56, + 0x33, 0xfe, 0x82, 0x5c, 0x2c, 0xd3, 0x5f, 0x00, 0xc3, 0x62, 0x4a, 0x1d, 0x59, 0x29, 0x13, 0x9e, + 0x01, 0x4f, 0x35, 0x7e, 0xf2, 0xda, 0x55, 0x40, 0x8d, 0x52, 0x41, 0x35, 0x12, 0xae, 0xc3, 0x5a, + 0x24, 0x6f, 0x36, 0xf5, 0xef, 0x70, 0x54, 0x30, 0x07, 0x14, 0x6b, 0x99, 0xb2, 0x69, 0x8c, 0x3b, + 0x35, 0xeb, 0xf4, 0x4e, 0x4d, 0x9b, 0x88, 0x06, 0x4f, 0x68, 0x12, 0xc2, 0xef, 0x71, 0x74, 0x1f, + 0x82, 0xb2, 0xb0, 0xdb, 0xf6, 0x4d, 0xc8, 0x0e, 0x09, 0xee, 0x4f, 0xa3, 0xae, 0x25, 0xbf, 0x11, + 0x1c, 0x59, 0x5d, 0x22, 0xa5, 0xb8, 0x34, 0x24, 0x55, 0xf8, 0x29, 0x07, 0x79, 0x0f, 0x7f, 0xb4, + 0x0e, 0xb3, 0x0e, 0x54, 0x64, 0x27, 0x48, 0x4e, 0x83, 0x75, 0xfc, 0xa6, 0x66, 0xca, 0x3d, 0xf6, + 0x26, 0x85, 0x7e, 0x58, 0x39, 0xed, 0xd0, 0xc0, 0x34, 0x1c, 0x4e, 0x8b, 0xe4, 0x6f, 0x74, 0x07, + 0x32, 0x43, 0x55, 0x31, 0x89, 0xd9, 0x2f, 0x04, 0xed, 0x99, 0x4c, 0x55, 0x3a, 0x52, 0x15, 0x53, + 0x24, 0x54, 0xc2, 0x6d, 0xc8, 0x58, 0x5f, 0x7e, 0xc8, 0x62, 0x16, 0xb2, 0x95, 0xa7, 0xed, 0x6a, + 0xab, 0xc0, 0x21, 0x80, 0x5c, 0x8d, 0x26, 0xf8, 0x29, 0xa1, 0x6e, 0xbf, 0x4b, 0x75, 0x16, 0x61, + 0xb9, 0x00, 0xf9, 0x58, 0xd5, 0xf4, 0xbe, 0xdc, 0x23, 0x32, 0xcf, 0x88, 0xce, 0x77, 0x7c, 0x39, + 0x85, 0x82, 0x8f, 0xeb, 0xce, 0x89, 0x44, 0x01, 0x4c, 0x9f, 0x51, 0xdd, 0x8a, 0x83, 0x96, 0xca, + 0x91, 0xd0, 0xd2, 0x75, 0xdf, 0x2d, 0x3b, 0x02, 0x54, 0xfa, 0xdb, 0x14, 0xac, 0x44, 0xd2, 0xa1, + 0xf7, 0xbc, 0x70, 0xd2, 0x56, 0x22, 0x4f, 0x2f, 0x90, 0xf4, 0x15, 0x47, 0x81, 0xa4, 0x1d, 0x1f, + 0x90, 0xf4, 0xfa, 0xc8, 0xf1, 0x5e, 0x08, 0xe9, 0xc7, 0x5c, 0x0c, 0x84, 0xd4, 0x6a, 0x97, 0xf7, + 0xab, 0xd2, 0x51, 0x83, 0xfe, 0xeb, 0x40, 0x48, 0xcb, 0x50, 0x70, 0x81, 0x15, 0xa9, 0xd5, 0x2e, + 0x93, 0x47, 0xc6, 0x21, 0xf8, 0x26, 0x1d, 0x09, 0xce, 0x64, 0x46, 0xe3, 0x30, 0x59, 0x4a, 0xb2, + 0x0a, 0x88, 0x8d, 0x7e, 0xdc, 0x3c, 0x6a, 0xb4, 0x25, 0xf2, 0x84, 0xb9, 0x90, 0x73, 0xf0, 0x99, + 0x65, 0x40, 0xec, 0xb4, 0xbc, 0x2f, 0xf1, 0xff, 0x84, 0x83, 0x25, 0x5f, 0x33, 0x3b, 0x3c, 0x4f, + 0x51, 0x9c, 0xf3, 0x15, 0xc5, 0xef, 0xc1, 0xb2, 0x95, 0x31, 0x52, 0x4b, 0x31, 0xa4, 0x01, 0xd6, + 0x09, 0x18, 0xce, 0x74, 0x7e, 0xb1, 0x2f, 0xbf, 0x60, 0x05, 0x83, 0x43, 0xac, 0x5b, 0x8c, 0x2f, + 0x01, 0x12, 0x16, 0xbe, 0x4c, 0xd3, 0xb8, 0x64, 0xe2, 0xbc, 0x66, 0xa4, 0x8f, 0x0a, 0x27, 0x3e, + 0xe9, 0x09, 0x12, 0x9f, 0x18, 0x0f, 0x97, 0x99, 0x28, 0x18, 0x9e, 0xfc, 0x4e, 0x6f, 0xb8, 0xf7, + 0x36, 0x8d, 0x5c, 0xef, 0x78, 0xf5, 0x77, 0x64, 0xa6, 0x95, 0xfb, 0xb2, 0xc2, 0xfd, 0xe8, 0xb2, + 0xf2, 0xe4, 0x32, 0x8d, 0xc7, 0x2e, 0x90, 0x1f, 0x09, 0x77, 0xe0, 0x16, 0x79, 0x56, 0x39, 0x0a, + 0xd0, 0xa6, 0x2e, 0xe9, 0x57, 0xe1, 0xf5, 0x51, 0xd4, 0x6c, 0xfa, 0x7a, 0xa4, 0xff, 0x71, 0x6a, + 0x5b, 0x01, 0x2e, 0x23, 0x5c, 0x11, 0x9d, 0xfc, 0xb7, 0x53, 0xb0, 0x39, 0x6a, 0x1c, 0xfa, 0xd8, + 0xeb, 0x9a, 0xee, 0x8c, 0x3b, 0x9d, 0xd7, 0x4b, 0xfd, 0x01, 0xf3, 0x52, 0x55, 0x9f, 0x97, 0x7a, + 0x67, 0x12, 0x56, 0x5e, 0x87, 0x55, 0x8d, 0xf2, 0x57, 0x6f, 0xc3, 0x1b, 0x7e, 0x58, 0xda, 0xe3, + 0xa3, 0xe8, 0xaf, 0x1f, 0x1c, 0x9c, 0x9a, 0x23, 0x0e, 0x66, 0xc7, 0x87, 0xf6, 0xfe, 0x7e, 0x1a, + 0x36, 0xbd, 0x0f, 0x94, 0xf7, 0xbd, 0x68, 0x5a, 0xd2, 0xaf, 0x05, 0x6e, 0xc3, 0x62, 0x10, 0x29, + 0xb2, 0x1f, 0xe4, 0x5e, 0xf1, 0x43, 0x45, 0x46, 0xd2, 0x03, 0x9c, 0x11, 0x53, 0x27, 0xe7, 0x7f, + 0x61, 0x14, 0xf8, 0x9b, 0x63, 0x33, 0xfe, 0xff, 0x09, 0x08, 0x53, 0xf5, 0xec, 0xc1, 0x56, 0x82, + 0xfc, 0xcc, 0x2c, 0x2a, 0xb0, 0xe0, 0x07, 0x46, 0x99, 0xa6, 0x06, 0x5e, 0xa1, 0xfa, 0x07, 0xcf, + 0xfb, 0xd0, 0x52, 0x3a, 0xdb, 0x3f, 0x73, 0xf6, 0x83, 0x7d, 0x1f, 0xad, 0x75, 0xc2, 0x61, 0xe4, + 0x95, 0x2e, 0x22, 0x08, 0xba, 0xa2, 0x12, 0xcc, 0xda, 0x54, 0x46, 0xf0, 0x09, 0xa8, 0x33, 0xb9, + 0x4b, 0x12, 0x06, 0x8e, 0xd3, 0x17, 0x04, 0x8e, 0x33, 0x41, 0xe0, 0x98, 0xae, 0xed, 0x87, 0x29, + 0xd8, 0xf4, 0xbe, 0x95, 0x8c, 0x54, 0xef, 0x49, 0x16, 0xba, 0x05, 0x73, 0x1e, 0x2a, 0x5b, 0xe3, + 0xf3, 0x2e, 0xee, 0x99, 0xa4, 0xed, 0xa3, 0x24, 0x79, 0x45, 0x20, 0x28, 0xdd, 0x8a, 0x6d, 0xd8, + 0x4a, 0x98, 0x9f, 0x2a, 0x15, 0xa5, 0xfc, 0x41, 0x8a, 0xfc, 0xb6, 0xed, 0xff, 0x6e, 0xc7, 0xe2, + 0x81, 0xc7, 0x44, 0x31, 0x5e, 0xe9, 0x76, 0x29, 0xb0, 0x11, 0x37, 0xf9, 0x25, 0x1b, 0xe0, 0xfd, + 0xff, 0xe6, 0x60, 0xa6, 0xd6, 0xc5, 0xaa, 0x49, 0x83, 0x82, 0x79, 0xdf, 0xaf, 0x1c, 0xd1, 0x7a, + 0xcc, 0x8f, 0x1f, 0xc9, 0x16, 0xf0, 0xd7, 0x13, 0x7f, 0x1a, 0x29, 0x4c, 0xa1, 0x13, 0xcf, 0x2f, + 0x34, 0x7d, 0xcf, 0x05, 0x5e, 0x0b, 0x8d, 0x8c, 0xb8, 0xab, 0xf9, 0x5b, 0x23, 0xa8, 0x9c, 0x79, + 0xde, 0x87, 0x2c, 0xf9, 0xb1, 0x1a, 0x5a, 0x76, 0x7e, 0x30, 0xe7, 0xf9, 0x2d, 0x1b, 0xbf, 0x12, + 0x68, 0xb5, 0xc7, 0xdd, 0xff, 0xfb, 0x59, 0x00, 0xf7, 0x0e, 0x44, 0x8f, 0x60, 0xce, 0xeb, 0xfa, + 0xd0, 0x5a, 0xc2, 0xaf, 0xb5, 0xf8, 0xf5, 0xe8, 0x4e, 0x47, 0xa6, 0x47, 0x30, 0xe7, 0x55, 0x79, + 0x97, 0x59, 0xc4, 0x63, 0x6d, 0x97, 0x59, 0xe4, 0xdb, 0xea, 0x29, 0xd4, 0x83, 0xab, 0x31, 0x4f, + 0x65, 0xd1, 0xeb, 0xe3, 0x3d, 0x28, 0xe6, 0xdf, 0x18, 0xf3, 0xcd, 0xad, 0x30, 0x85, 0x74, 0xb8, + 0x16, 0xfb, 0x42, 0x14, 0x6d, 0x8f, 0xfb, 0x7e, 0x95, 0x7f, 0x73, 0x0c, 0x4a, 0x67, 0xce, 0x21, + 0xf0, 0xf1, 0xcf, 0xd2, 0xd0, 0x9b, 0x63, 0xbf, 0x97, 0xe4, 0x6f, 0x8f, 0xff, 0xca, 0x4d, 0x98, + 0x42, 0x07, 0x90, 0xf7, 0xbc, 0x4f, 0x42, 0x7c, 0xe4, 0xa3, 0x25, 0xca, 0x78, 0x2d, 0xe1, 0x41, + 0x13, 0xe5, 0xe4, 0x79, 0x32, 0xe2, 0x72, 0x0a, 0x3f, 0x7e, 0x71, 0x39, 0x45, 0xbc, 0x31, 0x09, + 0x6e, 0x7f, 0x20, 0x30, 0x8d, 0xda, 0xfe, 0xe8, 0x48, 0x37, 0x6a, 0xfb, 0x63, 0xa2, 0x5c, 0x61, + 0x0a, 0x7d, 0x17, 0x16, 0xfc, 0xb5, 0x60, 0x74, 0x3d, 0xb1, 0xa6, 0xcd, 0x6f, 0xc4, 0x75, 0x7b, + 0x59, 0xfa, 0x2b, 0x89, 0x2e, 0xcb, 0xc8, 0x8a, 0xa6, 0xcb, 0x32, 0xa6, 0x00, 0x39, 0x65, 0xf9, + 0x27, 0x5f, 0x7d, 0xcc, 0xf5, 0x4f, 0x51, 0x65, 0x3d, 0xd7, 0x3f, 0x45, 0x16, 0xd5, 0x84, 0x29, + 0xa4, 0xc0, 0x6a, 0x74, 0x79, 0x06, 0xdd, 0x1a, 0xab, 0xfa, 0xc4, 0xbf, 0x3e, 0x8a, 0xcc, 0x99, + 0xaa, 0x03, 0x4b, 0x11, 0xcf, 0xc7, 0x90, 0x90, 0xf8, 0xb6, 0x8c, 0x4e, 0x72, 0x73, 0x8c, 0xf7, + 0x67, 0x02, 0x71, 0xe6, 0xff, 0x95, 0x86, 0x2b, 0x81, 0xc0, 0x1e, 0xfd, 0x06, 0x07, 0x1b, 0xc9, + 0xc9, 0x0e, 0xba, 0x1b, 0x93, 0x14, 0xc4, 0x28, 0x56, 0x69, 0x5c, 0x72, 0x8f, 0x71, 0x5f, 0x8b, + 0x8d, 0x29, 0xd1, 0xf6, 0xb8, 0x61, 0xb3, 0x47, 0xa3, 0x47, 0x05, 0xa8, 0x64, 0x3b, 0xac, 0x69, + 0x63, 0xa3, 0x0e, 0xb4, 0x3d, 0x6e, 0x60, 0xe4, 0x4e, 0x3b, 0x32, 0x84, 0xa1, 0xd3, 0xf6, 0x60, + 0x35, 0xfa, 0xf6, 0x46, 0xb7, 0xc6, 0x0a, 0x2d, 0x5c, 0xad, 0x4a, 0x0e, 0x02, 0xc8, 0x6c, 0x24, + 0xad, 0xba, 0xff, 0x2f, 0x59, 0xc8, 0x10, 0xa0, 0xa4, 0x0d, 0x57, 0x02, 0xc5, 0x17, 0xb4, 0x91, + 0x5c, 0x92, 0xe2, 0x6f, 0xc4, 0xf6, 0x3b, 0xe7, 0xf7, 0x0c, 0x16, 0x43, 0xe5, 0x14, 0xb4, 0xe9, + 0x1d, 0x17, 0x55, 0xd2, 0xe1, 0xb7, 0x12, 0x28, 0x82, 0xbc, 0xfd, 0x97, 0xda, 0xe6, 0x28, 0xbc, + 0xdf, 0xcf, 0x3b, 0xee, 0x22, 0xfb, 0x8c, 0xe2, 0x52, 0xc1, 0x2b, 0x4c, 0xf0, 0xcb, 0x15, 0x79, + 0x79, 0xdd, 0x4c, 0xa4, 0x71, 0x66, 0xf8, 0xd4, 0x01, 0xc4, 0x3c, 0x70, 0x33, 0xf2, 0x09, 0x17, + 0x09, 0x8b, 0xf3, 0x42, 0x12, 0x89, 0xc3, 0xfe, 0x13, 0x28, 0x04, 0x91, 0x11, 0x74, 0x63, 0x04, + 0x50, 0xc3, 0x6f, 0xc6, 0x13, 0x04, 0x77, 0x26, 0xe8, 0x09, 0x82, 0x52, 0x45, 0x99, 0xff, 0xcd, + 0x44, 0x1a, 0xef, 0x7d, 0xe8, 0xc1, 0x04, 0xdd, 0xfb, 0x30, 0x8c, 0x1f, 0xba, 0xf7, 0x61, 0x04, + 0x88, 0x28, 0x4c, 0xed, 0x3c, 0x00, 0x90, 0x7b, 0x83, 0xe7, 0xb2, 0x84, 0xd5, 0x61, 0x1f, 0xad, + 0x87, 0xd2, 0xb4, 0xaa, 0x3a, 0xec, 0x37, 0x07, 0x56, 0x76, 0x66, 0x14, 0xff, 0x6c, 0x86, 0xe4, + 0x62, 0xb3, 0x64, 0x80, 0xd5, 0xb1, 0x53, 0x87, 0x82, 0x3b, 0x5a, 0x22, 0x81, 0x36, 0xda, 0x8a, + 0xe4, 0x41, 0x5e, 0x4b, 0x06, 0x18, 0x2d, 0x38, 0x8c, 0x48, 0xef, 0xce, 0x47, 0x00, 0x1d, 0x43, + 0x91, 0x68, 0xa4, 0x8f, 0xae, 0x87, 0xf8, 0x3c, 0x54, 0x70, 0xaf, 0x6b, 0xf3, 0xf8, 0x53, 0x26, + 0x4c, 0xc7, 0x50, 0x68, 0x3e, 0xb0, 0xf3, 0x6d, 0xc8, 0x53, 0x61, 0x4e, 0x2c, 0xba, 0x51, 0xe3, + 0x99, 0x0c, 0x74, 0xf5, 0xa4, 0x67, 0xa7, 0x0a, 0xf3, 0x94, 0x01, 0x83, 0xd8, 0xd1, 0x8d, 0x10, + 0x8b, 0xc7, 0xb4, 0x27, 0xc0, 0x64, 0x8e, 0x0c, 0x63, 0x7d, 0x3b, 0x15, 0x98, 0xb3, 0xd9, 0x98, + 0xcf, 0xb5, 0x2e, 0xda, 0x88, 0xe0, 0x62, 0x75, 0x04, 0x98, 0xe4, 0x19, 0x13, 0xab, 0xcb, 0x15, + 0xc5, 0xfe, 0x3f, 0x3e, 0xc2, 0xa2, 0x30, 0x54, 0x29, 0x52, 0x14, 0xd6, 0x57, 0xc9, 0x3e, 0x4b, + 0x77, 0x0c, 0xe5, 0x38, 0x47, 0x06, 0x7d, 0xe3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x0c, 0x79, + 0xd8, 0xd8, 0x90, 0x46, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -5957,6 +6699,186 @@ var _Controller_serviceDesc = grpc.ServiceDesc{ Metadata: "github.com/container-storage-interface/spec/csi.proto", } +// GroupControllerClient is the client API for GroupController service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type GroupControllerClient interface { + GroupControllerGetCapabilities(ctx context.Context, in *GroupControllerGetCapabilitiesRequest, opts ...grpc.CallOption) (*GroupControllerGetCapabilitiesResponse, error) + CreateVolumeGroupSnapshot(ctx context.Context, in *CreateVolumeGroupSnapshotRequest, opts ...grpc.CallOption) (*CreateVolumeGroupSnapshotResponse, error) + DeleteVolumeGroupSnapshot(ctx context.Context, in *DeleteVolumeGroupSnapshotRequest, opts ...grpc.CallOption) (*DeleteVolumeGroupSnapshotResponse, error) + GetVolumeGroupSnapshot(ctx context.Context, in *GetVolumeGroupSnapshotRequest, opts ...grpc.CallOption) (*GetVolumeGroupSnapshotResponse, error) +} + +type groupControllerClient struct { + cc *grpc.ClientConn +} + +func NewGroupControllerClient(cc *grpc.ClientConn) GroupControllerClient { + return &groupControllerClient{cc} +} + +func (c *groupControllerClient) GroupControllerGetCapabilities(ctx context.Context, in *GroupControllerGetCapabilitiesRequest, opts ...grpc.CallOption) (*GroupControllerGetCapabilitiesResponse, error) { + out := new(GroupControllerGetCapabilitiesResponse) + err := c.cc.Invoke(ctx, "/csi.v1.GroupController/GroupControllerGetCapabilities", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *groupControllerClient) CreateVolumeGroupSnapshot(ctx context.Context, in *CreateVolumeGroupSnapshotRequest, opts ...grpc.CallOption) (*CreateVolumeGroupSnapshotResponse, error) { + out := new(CreateVolumeGroupSnapshotResponse) + err := c.cc.Invoke(ctx, "/csi.v1.GroupController/CreateVolumeGroupSnapshot", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *groupControllerClient) DeleteVolumeGroupSnapshot(ctx context.Context, in *DeleteVolumeGroupSnapshotRequest, opts ...grpc.CallOption) (*DeleteVolumeGroupSnapshotResponse, error) { + out := new(DeleteVolumeGroupSnapshotResponse) + err := c.cc.Invoke(ctx, "/csi.v1.GroupController/DeleteVolumeGroupSnapshot", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *groupControllerClient) GetVolumeGroupSnapshot(ctx context.Context, in *GetVolumeGroupSnapshotRequest, opts ...grpc.CallOption) (*GetVolumeGroupSnapshotResponse, error) { + out := new(GetVolumeGroupSnapshotResponse) + err := c.cc.Invoke(ctx, "/csi.v1.GroupController/GetVolumeGroupSnapshot", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// GroupControllerServer is the server API for GroupController service. +type GroupControllerServer interface { + GroupControllerGetCapabilities(context.Context, *GroupControllerGetCapabilitiesRequest) (*GroupControllerGetCapabilitiesResponse, error) + CreateVolumeGroupSnapshot(context.Context, *CreateVolumeGroupSnapshotRequest) (*CreateVolumeGroupSnapshotResponse, error) + DeleteVolumeGroupSnapshot(context.Context, *DeleteVolumeGroupSnapshotRequest) (*DeleteVolumeGroupSnapshotResponse, error) + GetVolumeGroupSnapshot(context.Context, *GetVolumeGroupSnapshotRequest) (*GetVolumeGroupSnapshotResponse, error) +} + +// UnimplementedGroupControllerServer can be embedded to have forward compatible implementations. +type UnimplementedGroupControllerServer struct { +} + +func (*UnimplementedGroupControllerServer) GroupControllerGetCapabilities(ctx context.Context, req *GroupControllerGetCapabilitiesRequest) (*GroupControllerGetCapabilitiesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GroupControllerGetCapabilities not implemented") +} +func (*UnimplementedGroupControllerServer) CreateVolumeGroupSnapshot(ctx context.Context, req *CreateVolumeGroupSnapshotRequest) (*CreateVolumeGroupSnapshotResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateVolumeGroupSnapshot not implemented") +} +func (*UnimplementedGroupControllerServer) DeleteVolumeGroupSnapshot(ctx context.Context, req *DeleteVolumeGroupSnapshotRequest) (*DeleteVolumeGroupSnapshotResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteVolumeGroupSnapshot not implemented") +} +func (*UnimplementedGroupControllerServer) GetVolumeGroupSnapshot(ctx context.Context, req *GetVolumeGroupSnapshotRequest) (*GetVolumeGroupSnapshotResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetVolumeGroupSnapshot not implemented") +} + +func RegisterGroupControllerServer(s *grpc.Server, srv GroupControllerServer) { + s.RegisterService(&_GroupController_serviceDesc, srv) +} + +func _GroupController_GroupControllerGetCapabilities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GroupControllerGetCapabilitiesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GroupControllerServer).GroupControllerGetCapabilities(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/csi.v1.GroupController/GroupControllerGetCapabilities", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GroupControllerServer).GroupControllerGetCapabilities(ctx, req.(*GroupControllerGetCapabilitiesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GroupController_CreateVolumeGroupSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateVolumeGroupSnapshotRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GroupControllerServer).CreateVolumeGroupSnapshot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/csi.v1.GroupController/CreateVolumeGroupSnapshot", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GroupControllerServer).CreateVolumeGroupSnapshot(ctx, req.(*CreateVolumeGroupSnapshotRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GroupController_DeleteVolumeGroupSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteVolumeGroupSnapshotRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GroupControllerServer).DeleteVolumeGroupSnapshot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/csi.v1.GroupController/DeleteVolumeGroupSnapshot", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GroupControllerServer).DeleteVolumeGroupSnapshot(ctx, req.(*DeleteVolumeGroupSnapshotRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GroupController_GetVolumeGroupSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetVolumeGroupSnapshotRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GroupControllerServer).GetVolumeGroupSnapshot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/csi.v1.GroupController/GetVolumeGroupSnapshot", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GroupControllerServer).GetVolumeGroupSnapshot(ctx, req.(*GetVolumeGroupSnapshotRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _GroupController_serviceDesc = grpc.ServiceDesc{ + ServiceName: "csi.v1.GroupController", + HandlerType: (*GroupControllerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GroupControllerGetCapabilities", + Handler: _GroupController_GroupControllerGetCapabilities_Handler, + }, + { + MethodName: "CreateVolumeGroupSnapshot", + Handler: _GroupController_CreateVolumeGroupSnapshot_Handler, + }, + { + MethodName: "DeleteVolumeGroupSnapshot", + Handler: _GroupController_DeleteVolumeGroupSnapshot_Handler, + }, + { + MethodName: "GetVolumeGroupSnapshot", + Handler: _GroupController_GetVolumeGroupSnapshot_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "github.com/container-storage-interface/spec/csi.proto", +} + // NodeClient is the client API for Node service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. diff --git a/vendor/modules.txt b/vendor/modules.txt index 9d48cb8d..942414e1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -7,7 +7,7 @@ github.com/blang/semver/v4 # github.com/cespare/xxhash/v2 v2.1.2 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/container-storage-interface/spec v1.7.0 +# github.com/container-storage-interface/spec v1.8.0 ## explicit; go 1.18 github.com/container-storage-interface/spec/lib/go/csi # github.com/davecgh/go-spew v1.1.1