mirror of
https://github.com/vmware-tanzu/velero.git
synced 2025-12-23 14:25:22 +00:00
azure: update blockstore to allow storing snaps in different resource group
Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
@@ -48,6 +48,7 @@ The configurable parameters are as follows:
|
|||||||
| Key | Type | Default | Meaning |
|
| Key | Type | Default | Meaning |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `apiTimeout` | metav1.Duration | 2m0s | How long to wait for an Azure API request to complete before timeout. |
|
| `apiTimeout` | metav1.Duration | 2m0s | How long to wait for an Azure API request to complete before timeout. |
|
||||||
|
| `resourceGroup` | string | Optional | The name of the resource group where volume snapshots should be stored, if different from the cluster's resource group. |
|
||||||
|
|
||||||
#### GCP
|
#### GCP
|
||||||
|
|
||||||
|
|||||||
@@ -40,18 +40,21 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
resourceGroupEnvVar = "AZURE_RESOURCE_GROUP"
|
resourceGroupEnvVar = "AZURE_RESOURCE_GROUP"
|
||||||
|
|
||||||
apiTimeoutConfigKey = "apiTimeout"
|
apiTimeoutConfigKey = "apiTimeout"
|
||||||
snapshotsResource = "snapshots"
|
|
||||||
disksResource = "disks"
|
snapshotsResource = "snapshots"
|
||||||
|
disksResource = "disks"
|
||||||
)
|
)
|
||||||
|
|
||||||
type blockStore struct {
|
type blockStore struct {
|
||||||
log logrus.FieldLogger
|
log logrus.FieldLogger
|
||||||
disks *disk.DisksClient
|
disks *disk.DisksClient
|
||||||
snaps *disk.SnapshotsClient
|
snaps *disk.SnapshotsClient
|
||||||
subscription string
|
subscription string
|
||||||
resourceGroup string
|
disksResourceGroup string
|
||||||
apiTimeout time.Duration
|
snapsResourceGroup string
|
||||||
|
apiTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type snapshotIdentifier struct {
|
type snapshotIdentifier struct {
|
||||||
@@ -106,7 +109,16 @@ func (b *blockStore) Init(config map[string]string) error {
|
|||||||
b.disks = &disksClient
|
b.disks = &disksClient
|
||||||
b.snaps = &snapsClient
|
b.snaps = &snapsClient
|
||||||
b.subscription = envVars[subscriptionIDEnvVar]
|
b.subscription = envVars[subscriptionIDEnvVar]
|
||||||
b.resourceGroup = envVars[resourceGroupEnvVar]
|
b.disksResourceGroup = envVars[resourceGroupEnvVar]
|
||||||
|
b.snapsResourceGroup = config[resourceGroupConfigKey]
|
||||||
|
|
||||||
|
// if no resource group was explicitly specified in 'config',
|
||||||
|
// use the value from the env var (i.e. the same one as where
|
||||||
|
// the cluster & disks are)
|
||||||
|
if b.snapsResourceGroup == "" {
|
||||||
|
b.snapsResourceGroup = envVars[resourceGroupEnvVar]
|
||||||
|
}
|
||||||
|
|
||||||
b.apiTimeout = apiTimeout
|
b.apiTimeout = apiTimeout
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -142,7 +154,7 @@ func (b *blockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ s
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), b.apiTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), b.apiTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
_, errChan := b.disks.CreateOrUpdate(b.resourceGroup, *disk.Name, disk, ctx.Done())
|
_, errChan := b.disks.CreateOrUpdate(b.disksResourceGroup, *disk.Name, disk, ctx.Done())
|
||||||
|
|
||||||
err = <-errChan
|
err = <-errChan
|
||||||
|
|
||||||
@@ -153,7 +165,7 @@ func (b *blockStore) CreateVolumeFromSnapshot(snapshotID, volumeType, volumeAZ s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) {
|
func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, error) {
|
||||||
res, err := b.disks.Get(b.resourceGroup, volumeID)
|
res, err := b.disks.Get(b.disksResourceGroup, volumeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, errors.WithStack(err)
|
return "", nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
@@ -163,12 +175,12 @@ func (b *blockStore) GetVolumeInfo(volumeID, volumeAZ string) (string, *int64, e
|
|||||||
|
|
||||||
func (b *blockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) {
|
func (b *blockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]string) (string, error) {
|
||||||
// Lookup disk info for its Location
|
// Lookup disk info for its Location
|
||||||
diskInfo, err := b.disks.Get(b.resourceGroup, volumeID)
|
diskInfo, err := b.disks.Get(b.disksResourceGroup, volumeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.WithStack(err)
|
return "", errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fullDiskName := getComputeResourceName(b.subscription, b.resourceGroup, disksResource, volumeID)
|
fullDiskName := getComputeResourceName(b.subscription, b.disksResourceGroup, disksResource, volumeID)
|
||||||
// snapshot names must be <= 80 characters long
|
// snapshot names must be <= 80 characters long
|
||||||
var snapshotName string
|
var snapshotName string
|
||||||
suffix := "-" + uuid.NewV4().String()
|
suffix := "-" + uuid.NewV4().String()
|
||||||
@@ -194,14 +206,14 @@ func (b *blockStore) CreateSnapshot(volumeID, volumeAZ string, tags map[string]s
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), b.apiTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), b.apiTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
_, errChan := b.snaps.CreateOrUpdate(b.resourceGroup, *snap.Name, snap, ctx.Done())
|
_, errChan := b.snaps.CreateOrUpdate(b.snapsResourceGroup, *snap.Name, snap, ctx.Done())
|
||||||
err = <-errChan
|
err = <-errChan
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.WithStack(err)
|
return "", errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return getComputeResourceName(b.subscription, b.resourceGroup, snapshotsResource, snapshotName), nil
|
return getComputeResourceName(b.subscription, b.snapsResourceGroup, snapshotsResource, snapshotName), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSnapshotTags(arkTags map[string]string, diskTags *map[string]*string) *map[string]*string {
|
func getSnapshotTags(arkTags map[string]string, diskTags *map[string]*string) *map[string]*string {
|
||||||
@@ -279,8 +291,11 @@ func (b *blockStore) parseSnapshotName(name string) (*snapshotIdentifier, error)
|
|||||||
// legacy format - name only (not fully-qualified)
|
// legacy format - name only (not fully-qualified)
|
||||||
case !strings.Contains(name, "/"):
|
case !strings.Contains(name, "/"):
|
||||||
return &snapshotIdentifier{
|
return &snapshotIdentifier{
|
||||||
subscription: b.subscription,
|
subscription: b.subscription,
|
||||||
resourceGroup: b.resourceGroup,
|
// use the disksResourceGroup here because Ark only
|
||||||
|
// supported storing snapshots in that resource group
|
||||||
|
// when the legacy snapshot format was used.
|
||||||
|
resourceGroup: b.disksResourceGroup,
|
||||||
name: name,
|
name: name,
|
||||||
}, nil
|
}, nil
|
||||||
// current format - fully qualified
|
// current format - fully qualified
|
||||||
@@ -341,7 +356,7 @@ func (b *blockStore) SetVolumeID(pv runtime.Unstructured, volumeID string) (runt
|
|||||||
}
|
}
|
||||||
|
|
||||||
azure["diskName"] = volumeID
|
azure["diskName"] = volumeID
|
||||||
azure["diskURI"] = getComputeResourceName(b.subscription, b.resourceGroup, disksResource, volumeID)
|
azure["diskURI"] = getComputeResourceName(b.subscription, b.disksResourceGroup, disksResource, volumeID)
|
||||||
|
|
||||||
return pv, nil
|
return pv, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ func TestGetVolumeID(t *testing.T) {
|
|||||||
|
|
||||||
func TestSetVolumeID(t *testing.T) {
|
func TestSetVolumeID(t *testing.T) {
|
||||||
b := &blockStore{
|
b := &blockStore{
|
||||||
resourceGroup: "rg",
|
disksResourceGroup: "rg",
|
||||||
subscription: "sub",
|
subscription: "sub",
|
||||||
}
|
}
|
||||||
|
|
||||||
pv := &unstructured.Unstructured{
|
pv := &unstructured.Unstructured{
|
||||||
@@ -99,8 +99,8 @@ func TestSetVolumeID(t *testing.T) {
|
|||||||
// format
|
// format
|
||||||
func TestParseSnapshotName(t *testing.T) {
|
func TestParseSnapshotName(t *testing.T) {
|
||||||
b := &blockStore{
|
b := &blockStore{
|
||||||
subscription: "default-sub",
|
subscription: "default-sub",
|
||||||
resourceGroup: "default-rg",
|
disksResourceGroup: "default-rg-legacy",
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalid name
|
// invalid name
|
||||||
@@ -123,7 +123,7 @@ func TestParseSnapshotName(t *testing.T) {
|
|||||||
snap, err = b.parseSnapshotName(fullName)
|
snap, err = b.parseSnapshotName(fullName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, b.subscription, snap.subscription)
|
assert.Equal(t, b.subscription, snap.subscription)
|
||||||
assert.Equal(t, b.resourceGroup, snap.resourceGroup)
|
assert.Equal(t, b.disksResourceGroup, snap.resourceGroup)
|
||||||
assert.Equal(t, fullName, snap.name)
|
assert.Equal(t, fullName, snap.name)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ const (
|
|||||||
subscriptionIDEnvVar = "AZURE_SUBSCRIPTION_ID"
|
subscriptionIDEnvVar = "AZURE_SUBSCRIPTION_ID"
|
||||||
clientIDEnvVar = "AZURE_CLIENT_ID"
|
clientIDEnvVar = "AZURE_CLIENT_ID"
|
||||||
clientSecretEnvVar = "AZURE_CLIENT_SECRET"
|
clientSecretEnvVar = "AZURE_CLIENT_SECRET"
|
||||||
|
|
||||||
|
resourceGroupConfigKey = "resourceGroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetResticEnvVars gets the environment variables that restic
|
// GetResticEnvVars gets the environment variables that restic
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
resourceGroupConfigKey = "resourceGroup"
|
|
||||||
storageAccountConfigKey = "storageAccount"
|
storageAccountConfigKey = "storageAccount"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user