azure: update blockstore to allow storing snaps in different resource group

Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
Steve Kriss
2018-10-15 14:21:39 -06:00
parent 35bb533c2d
commit 0ec2de55c0
6 changed files with 43 additions and 26 deletions

View File

@@ -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

View File

@@ -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
} }

View File

@@ -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)
} }

View File

@@ -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

View File

@@ -33,7 +33,6 @@ import (
) )
const ( const (
resourceGroupConfigKey = "resourceGroup"
storageAccountConfigKey = "storageAccount" storageAccountConfigKey = "storageAccount"
) )