14745: Updates drivers to use json.RawMessage instead of map[string]interface
authorEric Biagiotti <ebiagiotti@veritasgenetcs.com>
Tue, 12 Feb 2019 22:09:47 +0000 (17:09 -0500)
committerEric Biagiotti <ebiagiotti@veritasgenetcs.com>
Tue, 12 Feb 2019 22:09:47 +0000 (17:09 -0500)
Arvados-DCO-1.1-Signed-off-by: Eric Biagiotti <eric.biagiotti@gmail.com

lib/cloud/azure/azure.go
lib/cloud/azure/azure_test.go
lib/cloud/interfaces.go
sdk/go/arvados/config.go
sdk/go/arvados/duration.go

index c5a0ec5f4e08434c10c16251d4f430d267da57fb..0af2e43a6856060bd926acc43387f015bb552502 100644 (file)
@@ -7,6 +7,7 @@ package azure
 import (
        "context"
        "encoding/base64"
+       "encoding/json"
        "fmt"
        "net/http"
        "regexp"
@@ -26,7 +27,6 @@ import (
        "github.com/Azure/go-autorest/autorest/azure/auth"
        "github.com/Azure/go-autorest/autorest/to"
        "github.com/jmcvetta/randutil"
-       "github.com/mitchellh/mapstructure"
        "github.com/sirupsen/logrus"
        "golang.org/x/crypto/ssh"
 )
@@ -205,20 +205,12 @@ type azureInstanceSet struct {
        logger            logrus.FieldLogger
 }
 
-func newAzureInstanceSet(config map[string]interface{}, dispatcherID cloud.InstanceSetID, logger logrus.FieldLogger) (prv cloud.InstanceSet, err error) {
+func newAzureInstanceSet(config json.RawMessage, dispatcherID cloud.InstanceSetID, logger logrus.FieldLogger) (prv cloud.InstanceSet, err error) {
        azcfg := azureInstanceSetConfig{}
-
-       decoderConfig := mapstructure.DecoderConfig{
-               DecodeHook: arvados.DurationMapStructureDecodeHook(),
-               Result:     &azcfg}
-
-       decoder, err := mapstructure.NewDecoder(&decoderConfig)
+       err = json.Unmarshal(config, &azcfg)
        if err != nil {
                return nil, err
        }
-       if err = decoder.Decode(config); err != nil {
-               return nil, err
-       }
 
        ap := azureInstanceSet{logger: logger}
        err = ap.setup(azcfg, string(dispatcherID))
index 942b81dbc60e7aa36061826a3afed0b0ca449d6c..cf2ee82eb361badb4ec8e4bd61b34f6052bdb9e9 100644 (file)
@@ -3,30 +3,34 @@
 // SPDX-License-Identifier: AGPL-3.0
 //
 //
-// How to manually run individual tests against the real cloud
+// How to manually run individual tests against the real cloud:
 //
-// $ go test -v git.curoverse.com/arvados.git/lib/cloud/azure -live-azure-cfg azconfig.yml -check.f=TestListInstances
+// $ go test -v git.curoverse.com/arvados.git/lib/cloud/azure -live-azure-cfg azconfig.yml -check.f=TestListInstance
+//
+// Tests should be run individually and in the order they are listed in the file:
 //
 // Example azconfig.yml:
 //
 // ImageIDForTestSuite: "https://example.blob.core.windows.net/system/Microsoft.Compute/Images/images/zzzzz-compute-osDisk.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.vhd"
-// SubscriptionID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
-// ClientID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
-// Location: centralus
-// CloudEnvironment: AzurePublicCloud
-// ClientSecret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-// TenantId: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
-// ResourceGroup: zzzzz
-// Network: zzzzz0:10 / 3:26:1
-// Subnet: zzzzz-subnet-private
-// StorageAccount: example
-// BlobContainer: vhds
-// DeleteDanglingResourcesAfter: 20s
+// DriverParameters:
+//      SubscriptionID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+//      ClientID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+//      Location: centralus
+//      CloudEnvironment: AzurePublicCloud
+//      ClientSecret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+//      TenantId: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+//      ResourceGroup: zzzzz
+//      Network: zzzzz0:10 / 3:26:1
+//      Subnet: zzzzz-subnet-private
+//      StorageAccount: example
+//      BlobContainer: vhds
+//      DeleteDanglingResourcesAfter: 20s
 
 package azure
 
 import (
        "context"
+       "encoding/json"
        "errors"
        "flag"
        "io/ioutil"
@@ -101,6 +105,11 @@ func (*InterfacesClientStub) listComplete(ctx context.Context, resourceGroupName
        return network.InterfaceListResultIterator{}, nil
 }
 
+type testConfig struct {
+       ImageIDForTestSuite string
+       DriverParameters    json.RawMessage
+}
+
 var live = flag.String("live-azure-cfg", "", "Test with real azure API, provide config file")
 
 func GetInstanceSet() (cloud.InstanceSet, cloud.ImageID, arvados.Cluster, error) {
@@ -117,13 +126,20 @@ func GetInstanceSet() (cloud.InstanceSet, cloud.ImageID, arvados.Cluster, error)
                        },
                })}
        if *live != "" {
-               exampleCfg := make(map[string]interface{})
+               var exampleCfg testConfig
                err := config.LoadFile(&exampleCfg, *live)
                if err != nil {
                        return nil, cloud.ImageID(""), cluster, err
                }
-               ap, err := newAzureInstanceSet(exampleCfg, "test123", logrus.StandardLogger())
-               return ap, cloud.ImageID(exampleCfg["ImageIDForTestSuite"].(string)), cluster, err
+
+               var azcfg azureInstanceSetConfig
+               err = json.Unmarshal(exampleCfg.DriverParameters, &azcfg)
+               if err != nil {
+                       println(err.Error())
+               }
+
+               ap, err := newAzureInstanceSet(exampleCfg.DriverParameters, "test123", logrus.StandardLogger())
+               return ap, cloud.ImageID(exampleCfg.ImageIDForTestSuite), cluster, err
        }
        ap := azureInstanceSet{
                azconfig: azureInstanceSetConfig{
index 969a4bc2ddeb4b6389bf80912f9826009a56400c..46a2c1682404ec067bc7c332a77c469f0b353d57 100644 (file)
@@ -5,6 +5,7 @@
 package cloud
 
 import (
+       "encoding/json"
        "io"
        "time"
 
@@ -153,9 +154,9 @@ type InstanceSet interface {
 //
 //     type exampleDriver struct {}
 //
-//     func (*exampleDriver) InstanceSet(config map[string]interface{}, id InstanceSetID) (InstanceSet, error) {
+//     func (*exampleDriver) InstanceSet(config json.RawMessage, id InstanceSetID) (InstanceSet, error) {
 //             var is exampleInstanceSet
-//             if err := mapstructure.Decode(config, &is); err != nil {
+//             if err := json.Unmarshal(config, &is); err != nil {
 //                     return nil, err
 //             }
 //             is.ownID = id
@@ -164,17 +165,17 @@ type InstanceSet interface {
 //
 //     var _ = registerCloudDriver("example", &exampleDriver{})
 type Driver interface {
-       InstanceSet(config map[string]interface{}, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error)
+       InstanceSet(config json.RawMessage, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error)
 }
 
 // DriverFunc makes a Driver using the provided function as its
 // InstanceSet method. This is similar to http.HandlerFunc.
-func DriverFunc(fn func(config map[string]interface{}, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error)) Driver {
+func DriverFunc(fn func(config json.RawMessage, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error)) Driver {
        return driverFunc(fn)
 }
 
-type driverFunc func(config map[string]interface{}, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error)
+type driverFunc func(config json.RawMessage, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error)
 
-func (df driverFunc) InstanceSet(config map[string]interface{}, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error) {
+func (df driverFunc) InstanceSet(config json.RawMessage, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error) {
        return df(config, id, logger)
 }
index 1154f922ba45f0b76484e08ac182276c147641db..522eb41a72ddf991349fb1074b3a474be53a923e 100644 (file)
@@ -143,7 +143,7 @@ type CloudVMs struct {
        ImageID string
 
        Driver           string
-       DriverParameters map[string]interface{}
+       DriverParameters json.RawMessage
 }
 
 type InstanceTypeMap map[string]InstanceType
index d7dff6ddc75fca7d00fcf2db25a55ab7c40facef..fbbd53d50c452c9ab7d4b66ded69e7aa2d91bbe1 100644 (file)
@@ -7,7 +7,6 @@ package arvados
 import (
        "encoding/json"
        "fmt"
-       "reflect"
        "time"
 )
 
@@ -44,16 +43,3 @@ func (d *Duration) Set(s string) error {
        *d = Duration(dur)
        return err
 }
-
-// DurationMapStructureDecodeHook can be used to create a decoder for arvados.duration when using mapstructure
-func DurationMapStructureDecodeHook() interface{} {
-       return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
-               var duration Duration
-               if f.Kind() != reflect.String || t != reflect.TypeOf(duration) {
-                       return data, nil
-               }
-
-               duration.Set(data.(string))
-               return duration, nil
-       }
-}