16623: Add NetworkResourceGroup option for Azure
[arvados.git] / lib / cloud / azure / azure.go
index d19e4bef2372ff87dfb13e26db1ffddb9726bdca..6de367aa251c4c034b77331befde540782dc89d5 100644 (file)
@@ -16,8 +16,8 @@ import (
        "sync"
        "time"
 
-       "git.curoverse.com/arvados.git/lib/cloud"
-       "git.curoverse.com/arvados.git/sdk/go/arvados"
+       "git.arvados.org/arvados.git/lib/cloud"
+       "git.arvados.org/arvados.git/sdk/go/arvados"
        "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute"
        "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-06-01/network"
        storageacct "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-02-01/storage"
@@ -43,6 +43,7 @@ type azureInstanceSetConfig struct {
        ResourceGroup                string
        Location                     string
        Network                      string
+       NetworkResourceGroup         string
        Subnet                       string
        StorageAccount               string
        BlobContainer                string
@@ -50,8 +51,6 @@ type azureInstanceSetConfig struct {
        AdminUsername                string
 }
 
-const tagKeyInstanceSecret = "InstanceSecret"
-
 type containerWrapper interface {
        GetBlobReference(name string) *storage.Blob
        ListBlobs(params storage.ListBlobsParameters) (storage.BlobListResponse, error)
@@ -213,7 +212,7 @@ type azureInstanceSet struct {
        logger       logrus.FieldLogger
 }
 
-func newAzureInstanceSet(config json.RawMessage, dispatcherID cloud.InstanceSetID, logger logrus.FieldLogger) (prv cloud.InstanceSet, err error) {
+func newAzureInstanceSet(config json.RawMessage, dispatcherID cloud.InstanceSetID, _ cloud.SharedResourceTags, logger logrus.FieldLogger) (prv cloud.InstanceSet, err error) {
        azcfg := azureInstanceSetConfig{}
        err = json.Unmarshal(config, &azcfg)
        if err != nil {
@@ -341,6 +340,10 @@ func (az *azureInstanceSet) Create(
        az.stopWg.Add(1)
        defer az.stopWg.Done()
 
+       if instanceType.AddedScratch > 0 {
+               return nil, fmt.Errorf("cannot create instance type %q: driver does not implement non-zero AddedScratch (%d)", instanceType.Name, instanceType.AddedScratch)
+       }
+
        name, err := randutil.String(15, "abcdefghijklmnopqrstuvwxyz0123456789")
        if err != nil {
                return nil, err
@@ -348,13 +351,15 @@ func (az *azureInstanceSet) Create(
 
        name = az.namePrefix + name
 
-       timestamp := time.Now().Format(time.RFC3339Nano)
-
-       tags := make(map[string]*string)
-       tags["created-at"] = &timestamp
+       tags := map[string]*string{}
        for k, v := range newTags {
-               newstr := v
-               tags["dispatch-"+k] = &newstr
+               tags[k] = to.StringPtr(v)
+       }
+       tags["created-at"] = to.StringPtr(time.Now().Format(time.RFC3339Nano))
+
+       networkResourceGroup := az.azconfig.NetworkResourceGroup
+       if networkResourceGroup == "" {
+               networkResourceGroup = az.azconfig.ResourceGroup
        }
 
        nicParameters := network.Interface{
@@ -369,7 +374,7 @@ func (az *azureInstanceSet) Create(
                                                        ID: to.StringPtr(fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers"+
                                                                "/Microsoft.Network/virtualnetworks/%s/subnets/%s",
                                                                az.azconfig.SubscriptionID,
-                                                               az.azconfig.ResourceGroup,
+                                                               networkResourceGroup,
                                                                az.azconfig.Network,
                                                                az.azconfig.Subnet)),
                                                },
@@ -478,26 +483,24 @@ func (az *azureInstanceSet) Instances(cloud.InstanceTags) ([]cloud.Instance, err
                return nil, wrapAzureError(err)
        }
 
-       instances := make([]cloud.Instance, 0)
-
+       var instances []cloud.Instance
        for ; result.NotDone(); err = result.Next() {
                if err != nil {
                        return nil, wrapAzureError(err)
                }
-               if strings.HasPrefix(*result.Value().Name, az.namePrefix) {
-                       instances = append(instances, &azureInstance{
-                               provider: az,
-                               vm:       result.Value(),
-                               nic:      interfaces[*(*result.Value().NetworkProfile.NetworkInterfaces)[0].ID]})
-               }
+               instances = append(instances, &azureInstance{
+                       provider: az,
+                       vm:       result.Value(),
+                       nic:      interfaces[*(*result.Value().NetworkProfile.NetworkInterfaces)[0].ID],
+               })
        }
        return instances, nil
 }
 
 // ManageNics returns a list of Azure network interface resources.
-// Also performs garbage collection of NICs which have "namePrefix", are
-// not associated with a virtual machine and have a "create-at" time
-// more than DeleteDanglingResourcesAfter (to prevent racing and
+// Also performs garbage collection of NICs which have "namePrefix",
+// are not associated with a virtual machine and have a "created-at"
+// time more than DeleteDanglingResourcesAfter (to prevent racing and
 // deleting newly created NICs) in the past are deleted.
 func (az *azureInstanceSet) manageNics() (map[string]network.Interface, error) {
        az.stopWg.Add(1)
@@ -599,16 +602,12 @@ func (ai *azureInstance) SetTags(newTags cloud.InstanceTags) error {
        ai.provider.stopWg.Add(1)
        defer ai.provider.stopWg.Done()
 
-       tags := make(map[string]*string)
-
+       tags := map[string]*string{}
        for k, v := range ai.vm.Tags {
-               if !strings.HasPrefix(k, "dispatch-") {
-                       tags[k] = v
-               }
+               tags[k] = v
        }
        for k, v := range newTags {
-               newstr := v
-               tags["dispatch-"+k] = &newstr
+               tags[k] = to.StringPtr(v)
        }
 
        vmParameters := compute.VirtualMachine{
@@ -625,14 +624,10 @@ func (ai *azureInstance) SetTags(newTags cloud.InstanceTags) error {
 }
 
 func (ai *azureInstance) Tags() cloud.InstanceTags {
-       tags := make(map[string]string)
-
+       tags := cloud.InstanceTags{}
        for k, v := range ai.vm.Tags {
-               if strings.HasPrefix(k, "dispatch-") {
-                       tags[k[9:]] = *v
-               }
+               tags[k] = *v
        }
-
        return tags
 }
 
@@ -645,13 +640,17 @@ func (ai *azureInstance) Destroy() error {
 }
 
 func (ai *azureInstance) Address() string {
-       if ai.nic.IPConfigurations != nil &&
-               len(*ai.nic.IPConfigurations) > 0 &&
-               (*ai.nic.IPConfigurations)[0].PrivateIPAddress != nil {
-
-               return *(*ai.nic.IPConfigurations)[0].PrivateIPAddress
+       if iprops := ai.nic.InterfacePropertiesFormat; iprops == nil {
+               return ""
+       } else if ipconfs := iprops.IPConfigurations; ipconfs == nil || len(*ipconfs) == 0 {
+               return ""
+       } else if ipconfprops := (*ipconfs)[0].InterfaceIPConfigurationPropertiesFormat; ipconfprops == nil {
+               return ""
+       } else if addr := ipconfprops.PrivateIPAddress; addr == nil {
+               return ""
+       } else {
+               return *addr
        }
-       return ""
 }
 
 func (ai *azureInstance) RemoteUser() string {