func (b *VolumeSnapshotter) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) {
	volumeInfo, err := b.describeVolume(volumeID, volumeAZ)
	if err != nil {
		return "", nil, err
	}
	iops := int64(volumeInfo.IOPS)
	return volumeInfo.Category, &iops, nil
}
GetVolumeInfo get a volume's details
package main
import (
	"fmt"
	"os"
	"regexp"
	"strings"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	veleroplugin "github.com/vmware-tanzu/velero/pkg/plugin/framework"
)
const (
	ackClusterNameKey = "ACK_CLUSTER_NAME"
)
type VolumeSnapshotter struct {
	log logrus.FieldLogger
	ecs *ecs.Client
}
func newVolumeSnapshotter(logger logrus.FieldLogger) *VolumeSnapshotter {
	return &VolumeSnapshotter{log: logger}
}
func (b *VolumeSnapshotter) Init(config map[string]string) error {
	if err := veleroplugin.ValidateVolumeSnapshotterConfigKeys(config, regionConfigKey); err != nil {
		return err
	}
	if err := loadEnv(); err != nil {
		return err
	}
	regionID := getEcsRegionID(config)
	accessKeyID := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
	accessKeySecret := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
	stsToken := os.Getenv("ALIBABA_CLOUD_ACCESS_STS_TOKEN")
	if len(accessKeyID) == 0 {
		return errors.Errorf("ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is not set")
	}
	if len(accessKeySecret) == 0 {
		return errors.Errorf("ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is not set")
	}
	var client *ecs.Client
	var err error
	if len(stsToken) == 0 {
		client, err = ecs.NewClientWithAccessKey(regionID, accessKeyID, accessKeySecret)
	} else {
		client, err = ecs.NewClientWithStsToken(regionID, accessKeyID, accessKeySecret, stsToken)
	}
	b.ecs = client
	return err
}
func getJSONArrayString(id string) string {
	return fmt.Sprintf("[\"%s\"]", id)
}
func (b *VolumeSnapshotter) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ string, iops *int64) (volumeID string, err error) {
	snapReq := ecs.CreateDescribeSnapshotsRequest()
	snapReq.SnapshotIds = getJSONArrayString(snapshotID)
	snapRes, err := b.ecs.DescribeSnapshots(snapReq)
	if err != nil {
		return "", errors.WithStack(err)
	}
	if count := len(snapRes.Snapshots.Snapshot); count != 1 {
		return "", errors.Errorf("expected 1 snapshot from DescribeSnapshots for %s, got %v", snapshotID, count)
	}
	tags := getTagsForCluster(snapRes.Snapshots.Snapshot[0].Tags.Tag)
	volumeAZ, err = getMetaData(metadataZoneKey)
	if err != nil {
		return "", errors.Errorf("failed to get zone-id, got %v", err)
	}
	req := ecs.CreateCreateDiskRequest()
	req.SnapshotId = snapshotID
	req.ZoneId = volumeAZ
	req.DiskCategory = volumeType
	req.Encrypted = requests.NewBoolean(snapRes.Snapshots.Snapshot[0].Encrypted)
	req.Tag = &tags
	res, err := b.ecs.CreateDisk(req)
	if err != nil {
		return "", errors.WithStack(err)
	}
	return res.DiskId, nil
}