From 8bae6cbba85c522b63bc3e7227fc75131ae6fec0 Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Mon, 2 Mar 2020 16:39:02 +0100 Subject: [PATCH 01/21] azurerm: scaffold provider and dummy resource create the boilerplate in order to implement azurerm TF provider --- azurerm/provider.go | 55 ++++++++++++++++++++++++++++++ azurerm/resources.go | 29 ++++++++++++++++ azurerm/resourcetype_enumer.go | 62 ++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 azurerm/provider.go create mode 100644 azurerm/resources.go create mode 100644 azurerm/resourcetype_enumer.go diff --git a/azurerm/provider.go b/azurerm/provider.go new file mode 100644 index 0000000000..e999d93ffa --- /dev/null +++ b/azurerm/provider.go @@ -0,0 +1,55 @@ +package azurerm + +import ( + "context" + + "github.com/cycloidio/terracognita/filter" + "github.com/cycloidio/terracognita/provider" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/pkg/errors" +) + +type azurerm struct {} + +// NewProvider returns a Gooogle Provider +func NewProvider(ctx context.Context, maxResults uint64, project, region, credentials string) (provider.Provider, error) { + return nil, nil +} + +func (g *azurerm) HasResourceType(t string) bool { + _, err := ResourceTypeString(t) + return err == nil +} + +func (g *azurerm) Region() string { return "a-region" } +func (g *azurerm) Project() string { return "a-project" } +func (g *azurerm) String() string { return "azurerm" } +func (g *azurerm) TagKey() string { return "n/a" } + +func (g *azurerm) ResourceTypes() []string { + return ResourceTypeStrings() +} + +func (g *azurerm) Resources(ctx context.Context, t string, f *filter.Filter) ([]provider.Resource, error) { + rt, err := ResourceTypeString(t) + if err != nil { + return nil, err + } + + rfn, ok := resources[rt] + if !ok { + return nil, errors.Errorf("the resource %q it's not implemented", t) + } + + resources, err := rfn(ctx, g, t, f.Tags) + if err != nil { + return nil, errors.Wrapf(err, "error while reading from resource %q", t) + } + + return resources, nil +} + +func (g *azurerm) TFClient() interface{} { return nil } + +func (g *azurerm) TFProvider() *schema.Provider { return nil } diff --git a/azurerm/resources.go b/azurerm/resources.go new file mode 100644 index 0000000000..e731e3e5a9 --- /dev/null +++ b/azurerm/resources.go @@ -0,0 +1,29 @@ +package azurerm + +import ( + "context" + + "github.com/cycloidio/terracognita/provider" + "github.com/cycloidio/terracognita/tag" +) + +// ResourceType is the type used to define all the Resources +// from the Provider +type ResourceType int + +//go:generate enumer -type ResourceType -addprefix azurerm_ -transform snake -linecomment +const ( + DummyResource ResourceType = iota +) + +type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) + +var ( + resources = map[ResourceType]rtFn{ + DummyResource: dummyResource, + } +) + +func dummyResource(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + return nil, nil +} diff --git a/azurerm/resourcetype_enumer.go b/azurerm/resourcetype_enumer.go new file mode 100644 index 0000000000..82c58ca0cb --- /dev/null +++ b/azurerm/resourcetype_enumer.go @@ -0,0 +1,62 @@ +// Code generated by "enumer -type ResourceType -addprefix azurerm_ -transform snake -linecomment"; DO NOT EDIT. + +package azurerm + +import ( + "fmt" +) + +const _ResourceTypeName = "azurerm_dummy_resource" + +var _ResourceTypeIndex = [...]uint8{0, 22} + +const _ResourceTypeLowerName = "azurerm_dummy_resource" + +func (i ResourceType) String() string { + if i < 0 || i >= ResourceType(len(_ResourceTypeIndex)-1) { + return fmt.Sprintf("ResourceType(%d)", i) + } + return _ResourceTypeName[_ResourceTypeIndex[i]:_ResourceTypeIndex[i+1]] +} + +var _ResourceTypeValues = []ResourceType{0} + +var _ResourceTypeNameToValueMap = map[string]ResourceType{ + _ResourceTypeName[0:22]: 0, + _ResourceTypeLowerName[0:22]: 0, +} + +var _ResourceTypeNames = []string{ + _ResourceTypeName[0:22], +} + +// ResourceTypeString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func ResourceTypeString(s string) (ResourceType, error) { + if val, ok := _ResourceTypeNameToValueMap[s]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to ResourceType values", s) +} + +// ResourceTypeValues returns all values of the enum +func ResourceTypeValues() []ResourceType { + return _ResourceTypeValues +} + +// ResourceTypeStrings returns a slice of all String values of the enum +func ResourceTypeStrings() []string { + strs := make([]string, len(_ResourceTypeNames)) + copy(strs, _ResourceTypeNames) + return strs +} + +// IsAResourceType returns "true" if the value is listed in the enum definition. "false" otherwise +func (i ResourceType) IsAResourceType() bool { + for _, v := range _ResourceTypeValues { + if i == v { + return true + } + } + return false +} From 647bac539fff63f1b3102048c1267c0e461883c3 Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Mon, 2 Mar 2020 16:37:48 +0100 Subject: [PATCH 02/21] cmd: add azurerm command and resources subcommand --- cmd/azurerm.go | 28 ++++++++++++++++++++++++++++ cmd/azurerm_resources.go | 21 +++++++++++++++++++++ cmd/root.go | 1 + 3 files changed, 50 insertions(+) create mode 100644 cmd/azurerm.go create mode 100644 cmd/azurerm_resources.go diff --git a/cmd/azurerm.go b/cmd/azurerm.go new file mode 100644 index 0000000000..75d41f2bfb --- /dev/null +++ b/cmd/azurerm.go @@ -0,0 +1,28 @@ +package cmd + +import ( + "github.com/cycloidio/terracognita/log" + kitlog "github.com/go-kit/kit/log" + "github.com/spf13/cobra" +) + +var ( + azurermCmd = &cobra.Command{ + Use: "azurerm", + Short: "Terracognita reads from Azure and generates hcl resources and/or terraform state", + Long: "Terracognita reads from Azure and generates hcl resources and/or terraform state", + PreRun: func(cmd *cobra.Command, args []string) { + preRunEOutput(cmd, args) + }, + PostRunE: postRunEOutput, + RunE: func(cmd *cobra.Command, args []string) error { + logger := log.Get() + logger = kitlog.With(logger, "func", "cmd.azure.RunE") + return nil + }, + } +) + +func init() { + azurermCmd.AddCommand(azurermResourcesCmd) +} diff --git a/cmd/azurerm_resources.go b/cmd/azurerm_resources.go new file mode 100644 index 0000000000..6d98a41cb0 --- /dev/null +++ b/cmd/azurerm_resources.go @@ -0,0 +1,21 @@ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cycloidio/terracognita/azurerm" +) + +var ( + azurermResourcesCmd = &cobra.Command{ + Use: "resources", + Short: "List of all the AzureRM supported resources", + Run: func(cmd *cobra.Command, args []string) { + for _, r := range azurerm.ResourceTypeStrings() { + fmt.Println(r) + } + }, + } +) diff --git a/cmd/root.go b/cmd/root.go index b0f1335c6c..e1704eeabe 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -91,6 +91,7 @@ func init() { cobra.OnInitialize(initViper) RootCmd.AddCommand(awsCmd) RootCmd.AddCommand(googleCmd) + RootCmd.AddCommand(azurermCmd) RootCmd.AddCommand(versionCmd) RootCmd.PersistentFlags().String("hcl", "", "HCL output file") From b18b5c56ef02772eedafadc593773e7f4a5d7c4e Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 13 Mar 2020 19:06:41 +0100 Subject: [PATCH 03/21] azurerm: implement AzureReader --- azurerm/reader.go | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 azurerm/reader.go diff --git a/azurerm/reader.go b/azurerm/reader.go new file mode 100644 index 0000000000..ebd4c0cf95 --- /dev/null +++ b/azurerm/reader.go @@ -0,0 +1,86 @@ +package azurerm + +import ( + "context" + "fmt" + + azureResourcesAPI "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-05-01/resources" + "github.com/Azure/go-autorest/autorest" + "github.com/hashicorp/go-azure-helpers/authentication" + "github.com/hashicorp/go-azure-helpers/sender" +) + +//go:generate go run ./cmd + +// AzureReader is the middleware between TC and AzureRM +type AzureReader struct { + config authentication.Config + authorizer autorest.Authorizer + + resourceGroup azureResourcesAPI.Group +} + +// NewAzureReader returns a AzureReader +func NewAzureReader(ctx context.Context, clientID, clientSecret, environment, resourceGroupName, subscriptionID, tenantID string) (*AzureReader, error) { + // Config + cfgBuilder := &authentication.Builder{ + ClientID: clientID, + ClientSecret: clientSecret, + Environment: environment, + SubscriptionID: subscriptionID, + TenantID: tenantID, + + SupportsClientSecretAuth: true, + } + + cfg, err := cfgBuilder.Build() + if err != nil { + return nil, fmt.Errorf("could not build 'azure/authentication.Config' because: %s", err) + } + + // Authorizer + env, err := authentication.DetermineEnvironment(cfg.Environment) + if err != nil { + return nil, fmt.Errorf("could not initialize 'azure.Environment.' because: %s", err) + } + + oauthConfig, err := cfg.BuildOAuthConfig(env.ActiveDirectoryEndpoint) + if err != nil { + return nil, fmt.Errorf("could not initialize 'azure/authentication.OAuthConfig.' because: %s", err) + } + // OAuthConfigForTenant returns a pointer, which can be nil. + if oauthConfig == nil { + return nil, fmt.Errorf("could not configure OAuthConfig for tenant %s", cfg.TenantID) + } + + azureSender := sender.BuildSender("AzureRM") + + auth, err := cfg.GetAuthorizationToken(azureSender, oauthConfig, env.ResourceManagerEndpoint) + if err != nil { + return nil, fmt.Errorf("could not initialize 'azure/autorest.Authorizer.' because: %s", err) + } + + // Resource Group + client := azureResourcesAPI.NewGroupsClient(cfg.SubscriptionID) + client.Authorizer = auth + resourceGroup, err := client.Get(ctx, resourceGroupName) + if err != nil { + return nil, fmt.Errorf("could not 'azure/resources.GroupsClient.Get' the resource group because: %s", err) + } + + return &AzureReader{ + config: *cfg, + authorizer: auth, + resourceGroup: resourceGroup, + }, nil +} + +// GetResourceGroupName returns the current Resource Group name +func (ar *AzureReader) GetResourceGroupName() string { + return *ar.resourceGroup.Name +} + +// GetLocation returns the current Resource Group location +func (ar *AzureReader) GetLocation() string { + return *ar.resourceGroup.Location +} From ab83614b3adb9fc20e838cfe44e6c39b54e504d7 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 13 Mar 2020 19:09:38 +0100 Subject: [PATCH 04/21] azurerm: provider implementation --- azurerm/provider.go | 76 ++++++++++++++++++++++++++++++++++---------- provider/resource.go | 6 ++-- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/azurerm/provider.go b/azurerm/provider.go index e999d93ffa..0207c53a8b 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -2,36 +2,74 @@ package azurerm import ( "context" + "fmt" - "github.com/cycloidio/terracognita/filter" - "github.com/cycloidio/terracognita/provider" - + "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" "github.com/pkg/errors" + tfazurerm "github.com/terraform-providers/terraform-provider-azurerm/azurerm" + + "github.com/cycloidio/terracognita/filter" + "github.com/cycloidio/terracognita/log" + "github.com/cycloidio/terracognita/provider" ) -type azurerm struct {} +type azurerm struct { + tfAzureRMClient interface{} + tfProvider *schema.Provider + azurer *AzureReader +} + +// NewProvider returns a AzureRM Provider +func NewProvider(ctx context.Context, clientID, clientSecret, environment, resourceGroupName, subscriptionID, tenantID string) (provider.Provider, error) { + log.Get().Log("func", "azurerm.NewProvider", "msg", "loading Azure reader") + reader, err := NewAzureReader(ctx, clientID, clientSecret, environment, resourceGroupName, subscriptionID, tenantID) + if err != nil { + return nil, fmt.Errorf("could not initialize AzureReader: %s", err) + } + + log.Get().Log("func", "azurerm.NewProvider", "msg", "loading TF provider") + tfp := tfazurerm.Provider().(*schema.Provider) + + rawCfg, err := config.NewRawConfig(map[string]interface{}{ + "client_id": clientID, + "client_secret": clientSecret, + "environment": environment, + "subscription_id": subscriptionID, + "tenant_id": tenantID, + }) + if err != nil { + return nil, fmt.Errorf("could not initialize 'terraform/config.NewRawConfig()' because: %s", err) + } -// NewProvider returns a Gooogle Provider -func NewProvider(ctx context.Context, maxResults uint64, project, region, credentials string) (provider.Provider, error) { - return nil, nil + log.Get().Log("func", "azurerm.NewProvider", "msg", "loading TF client") + if err := tfp.Configure(terraform.NewResourceConfig(rawCfg)); err != nil { + return nil, fmt.Errorf("could not initialize 'terraform/azurerm.Provider.Configure()' because: %s", err) + } + + return &azurerm{ + tfAzureRMClient: tfp.Meta(), + tfProvider: tfp, + azurer: reader, + }, nil } -func (g *azurerm) HasResourceType(t string) bool { +func (a *azurerm) HasResourceType(t string) bool { _, err := ResourceTypeString(t) return err == nil } -func (g *azurerm) Region() string { return "a-region" } -func (g *azurerm) Project() string { return "a-project" } -func (g *azurerm) String() string { return "azurerm" } -func (g *azurerm) TagKey() string { return "n/a" } +func (a *azurerm) ResourceGroup() string { return a.azurer.GetResourceGroupName() } +func (a *azurerm) Region() string { return a.azurer.GetLocation() } +func (a *azurerm) String() string { return "azurerm" } +func (a *azurerm) TagKey() string { return "tags" } -func (g *azurerm) ResourceTypes() []string { +func (a *azurerm) ResourceTypes() []string { return ResourceTypeStrings() } -func (g *azurerm) Resources(ctx context.Context, t string, f *filter.Filter) ([]provider.Resource, error) { +func (a *azurerm) Resources(ctx context.Context, t string, f *filter.Filter) ([]provider.Resource, error) { rt, err := ResourceTypeString(t) if err != nil { return nil, err @@ -42,7 +80,7 @@ func (g *azurerm) Resources(ctx context.Context, t string, f *filter.Filter) ([] return nil, errors.Errorf("the resource %q it's not implemented", t) } - resources, err := rfn(ctx, g, t, f.Tags) + resources, err := rfn(ctx, a, t, f.Tags) if err != nil { return nil, errors.Wrapf(err, "error while reading from resource %q", t) } @@ -50,6 +88,10 @@ func (g *azurerm) Resources(ctx context.Context, t string, f *filter.Filter) ([] return resources, nil } -func (g *azurerm) TFClient() interface{} { return nil } +func (a *azurerm) TFClient() interface{} { + return a.tfAzureRMClient +} -func (g *azurerm) TFProvider() *schema.Provider { return nil } +func (a *azurerm) TFProvider() *schema.Provider { + return a.tfProvider +} diff --git a/provider/resource.go b/provider/resource.go index 7b8145636b..e4f51d4899 100644 --- a/provider/resource.go +++ b/provider/resource.go @@ -15,6 +15,7 @@ import ( "github.com/cycloidio/terracognita/tag" "github.com/cycloidio/terracognita/writer" awsdocs "github.com/cycloidio/tfdocs/providers/aws" + azuredocs "github.com/cycloidio/tfdocs/providers/azurerm" googledocs "github.com/cycloidio/tfdocs/providers/google" tfdocs "github.com/cycloidio/tfdocs/resource" "github.com/hashicorp/terraform/configs/configschema" @@ -116,8 +117,9 @@ type resource struct { var ( autogeneratedAWSResourcesRe = regexp.MustCompile(`^aws:(?:autoscaling|cloudformation)`) providerResources = map[string]getResource{ - "aws": awsdocs.GetResource, - "google": googledocs.GetResource, + "aws": awsdocs.GetResource, + "azurerm": azuredocs.GetResource, + "google": googledocs.GetResource, } ) From b60e0e3232a922ef699ed9734c53a875ab19a492 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 13 Mar 2020 19:16:11 +0100 Subject: [PATCH 05/21] azurerm/cmd: implement azurerm reader functions generation --- azurerm/cmd/generate.go | 49 +++++++++++++++ azurerm/cmd/template.go | 132 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 azurerm/cmd/generate.go create mode 100644 azurerm/cmd/template.go diff --git a/azurerm/cmd/generate.go b/azurerm/cmd/generate.go new file mode 100644 index 0000000000..4204d5f307 --- /dev/null +++ b/azurerm/cmd/generate.go @@ -0,0 +1,49 @@ +package main + +import ( + "bytes" + "io" + "os" + "os/exec" + + "github.com/pkg/errors" +) + +var azureAPIs []AzureAPI + +var functions []Function + +func main() { + f, err := os.OpenFile("./reader_generated.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + panic(err) + } + defer f.Close() + + if err := generate(f, azureAPIs, functions); err != nil { + panic(err) + } +} + +func generate(opt io.Writer, azureAPIs []AzureAPI, fns []Function) error { + var fnBuff = bytes.Buffer{} + + if err := pkgTmpl.Execute(&fnBuff, struct{ AzureAPIs []AzureAPI }{AzureAPIs: azureAPIs}); err != nil { + return errors.Wrap(err, "unable to execute package template") + } + + for _, function := range fns { + if err := function.Execute(&fnBuff); err != nil { + return errors.Wrapf(err, "unable to execute function template for: %s", function.Resource) + } + } + + // format + cmd := exec.Command("goimports") + cmd.Stdin = &fnBuff + cmd.Stdout = opt + if err := cmd.Run(); err != nil { + return errors.Wrap(err, "unable to run goimports command") + } + return nil +} diff --git a/azurerm/cmd/template.go b/azurerm/cmd/template.go new file mode 100644 index 0000000000..f317eb08a4 --- /dev/null +++ b/azurerm/cmd/template.go @@ -0,0 +1,132 @@ +package main + +import ( + "io" + "text/template" + + "github.com/pkg/errors" +) + +const ( + // packageTmpl it's the package definition + packageTmpl = ` + package azurerm + // Code generated by 'go generate'; DO NOT EDIT + import ( + "context" + + "github.com/pkg/errors" + + {{ range .AzureAPIs -}} + "github.com/Azure/azure-sdk-for-go/services/{{ .API }}/mgmt/{{ .APIVersion }}/{{ .API }}" + {{ end }} + ) + ` + + // functionTmpl it's the implementation of a reader function + functionTmpl = ` + // List{{ .Name }} returns a list of {{ .Name }} within a subscription {{ if .Location }}and a location {{ end }}{{ if .ResourceGroup }}and a resource group {{ end }} + func (ar *AzureReader) List{{ .Name }}(ctx context.Context{{ range .ExtraArgs }},{{ . }} string{{ end }}) ([]{{ .API }}.{{ .Resource }}, error) { + client := {{ .API }}.New{{ .Resource }}sClient(ar.config.SubscriptionID) + client.Authorizer = ar.authorizer + + output, err := client.{{ .ListFunction }}(ctx{{ if .Location }}, ar.GetLocation(){{ end }}{{ if .ResourceGroup }}, ar.GetResourceGroupName(){{ end }}{{ range .ExtraArgs }},{{ . }}{{ end }}) + if err != nil { + return nil, errors.Wrap(err, "unable to list {{ .API }}.{{ .Resource }} from Azure APIs") + } + resources := make([]{{ .API }}.{{ .Resource }}, 0) + for output.NotDone() { + {{ if .Iterator }} + res = output.Value() + resources = append(resources, res) + {{ else }} + for _, res := range output.Values() { + resources = append(resources, res) + } + {{ end }} + if err := output.NextWithContext(ctx); err != nil { + break + } + } + return resources, nil + } + ` +) + +var ( + fnTmpl *template.Template + pkgTmpl *template.Template +) + +func init() { + var err error + fnTmpl, err = template.New("template").Parse(functionTmpl) + if err != nil { + panic(err) + } + pkgTmpl, err = template.New("template").Parse(packageTmpl) + if err != nil { + panic(err) + } +} + +// AzureAPI is the definition of one of the Azure APIs +type AzureAPI struct { + // API is used to determine the + // Azure API to use + // ex: compute, network + API string + + // APIVersion is used to determine the + // Azure API Version to use + // ex: 2019-07-01 + APIVersion string +} + +// Function is the definition of one of the functions +type Function struct { + // Resource is the Azure name of the entity, like + // VirtualMachine, VirtualNetwork, etc. + Resource string + + // Name is the function name to be generated + // it can be useful if you `Resource` is `SslCertificate`, which is not `go` + // compliant, `Name` will be `SSLCertificate`, your Function name will be + // `ListSSLCertificates` + Name string + + // API is used to determine the + // Azure API to use + // ex: compute, network + API string + + // Location is used to determine whether the resource should be filtered by Azure locations or not + Location bool + + // ResourceGroup is used to determine whether the resource should be filtered by Azure Resource Group or not + ResourceGroup bool + + // ListFunction is the Azure SKP list function to use + ListFunction string + + // Iterator should be true is the ListFunction returns an Iterator and not a Page + Iterator bool + + // ExtraArgs should be specified if extra arguments are required for the list function + ExtraArgs []string +} + +// Execute uses the fnTmpl to interpolate f +// and write the result to w +func (f Function) Execute(w io.Writer) error { + if len(f.Name) == 0 { + f.Name = f.Resource + "s" + } + if len(f.ListFunction) == 0 { + f.ListFunction = "List" + } + if err := fnTmpl.Execute(w, f); err != nil { + return errors.Wrapf(err, "failed to Execute with Function %+v", f) + } + return nil +} From 4c09095cb7842ff6a2625f4c2107ce74c3602407 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 13 Mar 2020 19:14:09 +0100 Subject: [PATCH 06/21] cmd: use azurerm implemented provider for the azurerm command --- cmd/aws.go | 4 +-- cmd/azurerm.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++- cmd/google.go | 4 +-- 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/cmd/aws.go b/cmd/aws.go index 81e4a2eb9a..290d17a084 100644 --- a/cmd/aws.go +++ b/cmd/aws.go @@ -70,12 +70,12 @@ var ( var hclW, stateW writer.Writer if hclOut != nil { - logger.Log("msg", "initialzing HCL writer") + logger.Log("msg", "initializing HCL writer") hclW = hcl.NewWriter(hclOut) } if stateOut != nil { - logger.Log("msg", "initialzing TFState writer") + logger.Log("msg", "initializing TFState writer") stateW = state.NewWriter(stateOut) } diff --git a/cmd/azurerm.go b/cmd/azurerm.go index 75d41f2bfb..2bf617f58c 100644 --- a/cmd/azurerm.go +++ b/cmd/azurerm.go @@ -1,9 +1,21 @@ package cmd import ( - "github.com/cycloidio/terracognita/log" + "context" + "fmt" + kitlog "github.com/go-kit/kit/log" + "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cycloidio/terracognita/azurerm" + "github.com/cycloidio/terracognita/filter" + "github.com/cycloidio/terracognita/hcl" + "github.com/cycloidio/terracognita/log" + "github.com/cycloidio/terracognita/provider" + "github.com/cycloidio/terracognita/state" + "github.com/cycloidio/terracognita/writer" ) var ( @@ -13,11 +25,66 @@ var ( Long: "Terracognita reads from Azure and generates hcl resources and/or terraform state", PreRun: func(cmd *cobra.Command, args []string) { preRunEOutput(cmd, args) + viper.BindPFlag("client-id", cmd.Flags().Lookup("client-id")) + viper.BindPFlag("client-secret", cmd.Flags().Lookup("client-secret")) + viper.BindPFlag("environment", cmd.Flags().Lookup("environment")) + viper.BindPFlag("resource-group-name", cmd.Flags().Lookup("resource-group-name")) + viper.BindPFlag("subscription-id", cmd.Flags().Lookup("subscription-id")) + viper.BindPFlag("tenant-id", cmd.Flags().Lookup("tenant-id")) }, PostRunE: postRunEOutput, RunE: func(cmd *cobra.Command, args []string) error { logger := log.Get() logger = kitlog.With(logger, "func", "cmd.azure.RunE") + // Validate required flags + if err := requiredStringFlags( + "client-id", "client-secret", "resource-group-name", "subscription-id", "tenant-id", + ); err != nil { + return err + } + + ctx := context.Background() + + azureRMP, err := azurerm.NewProvider( + ctx, + viper.GetString("client-id"), + viper.GetString("client-secret"), + viper.GetString("environment"), + viper.GetString("resource-group-name"), + viper.GetString("subscription-id"), + viper.GetString("tenant-id"), + ) + if err != nil { + return err + } + + f := &filter.Filter{ + Include: include, + Exclude: exclude, + Targets: targets, + } + + var hclW, stateW writer.Writer + + if hclOut != nil { + logger.Log("msg", "initializing HCL writer") + hclW = hcl.NewWriter(hclOut) + } + + if stateOut != nil { + logger.Log("msg", "initializing TFState writer") + stateW = state.NewWriter(stateOut) + } + + logger.Log("msg", "importing") + + fmt.Fprintf(logsOut, "Starting Terracognita with version %s\n", Version) + logger.Log("msg", "starting terracognita", "version", Version) + err = provider.Import(ctx, azureRMP, hclW, stateW, f, logsOut) + if err != nil { + return errors.Wrap(err, "could not import from Azure") + } + return nil }, } @@ -25,4 +92,14 @@ var ( func init() { azurermCmd.AddCommand(azurermResourcesCmd) + + // Required flags + azurermCmd.Flags().String("client-id", "", "Client ID (required)") + azurermCmd.Flags().String("client-secret", "", "Client Secret (required)") + azurermCmd.Flags().String("resource-group-name", "", "Resource Group Name (required)") + azurermCmd.Flags().String("subscription-id", "", "Subscription ID (required)") + azurermCmd.Flags().String("tenant-id", "", "Tenant ID (required)") + + // Optional flags + azurermCmd.Flags().String("environment", "public", "Environment") } diff --git a/cmd/google.go b/cmd/google.go index ddabec58e6..ef7f339405 100644 --- a/cmd/google.go +++ b/cmd/google.go @@ -75,12 +75,12 @@ var ( var hclW, stateW writer.Writer if hclOut != nil { - logger.Log("msg", "initialzing HCL writer") + logger.Log("msg", "initializing HCL writer") hclW = hcl.NewWriter(hclOut) } if stateOut != nil { - logger.Log("msg", "initialzing TFState writer") + logger.Log("msg", "initializing TFState writer") stateW = state.NewWriter(stateOut) } From 2cc3c1b87712b32d0db69f0716b31e58f0b4702d Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 13 Mar 2020 19:03:22 +0100 Subject: [PATCH 07/21] mod: add azure provider and dependencies --- go.mod | 22 ++++---- go.sum | 119 +++++++++++++++++++++++++++++++++++++++++++ state/writer_test.go | 2 +- 3 files changed, 131 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 7d60dc3b16..4c0f87d8a0 100644 --- a/go.mod +++ b/go.mod @@ -3,34 +3,34 @@ module github.com/cycloidio/terracognita require ( cloud.google.com/go/bigtable v1.0.0 // indirect cloud.google.com/go/storage v1.0.0 // indirect + github.com/Azure/azure-sdk-for-go v33.2.0+incompatible + github.com/Azure/go-autorest/autorest v0.9.3 + github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503 // indirect github.com/aws/aws-sdk-go v1.25.4 github.com/chr4/pwgen v1.1.0 github.com/cycloidio/tfdocs v0.0.0-20200111145532-e6a80a93d7cc github.com/go-kit/kit v0.9.0 github.com/golang/mock v1.3.1 - github.com/golang/snappy v0.0.1 // indirect - github.com/hashicorp/go-getter v1.4.0 // indirect - github.com/hashicorp/go-hclog v0.9.2 // indirect - github.com/hashicorp/go-plugin v1.0.1 // indirect + github.com/hashicorp/go-azure-helpers v0.9.0 github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/hil v0.0.0-20190212132231-97b3a9cdfa93 // indirect - github.com/hashicorp/terraform v0.12.7 + github.com/hashicorp/terraform v0.12.8 github.com/hashicorp/vault v1.0.3 // indirect - github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect - github.com/mitchellh/reflectwalk v1.0.1 // indirect github.com/pkg/errors v0.8.1 - github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cobra v0.0.5 github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.4.0 github.com/terraform-providers/terraform-provider-aws v1.60.1-0.20191003145700-f8707a46c6ec + github.com/terraform-providers/terraform-provider-azurerm v1.35.0 github.com/terraform-providers/terraform-provider-google v1.20.1-0.20190924213132-8cb5c9efd9d7 github.com/zclconf/go-cty v1.1.0 + golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 // indirect golang.org/x/exp v0.0.0-20190912063710-ac5d2bfcbfe0 // indirect - golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect - golang.org/x/tools v0.0.0-20191209225234-22774f7dae43 // indirect + golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect + golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect + golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect + golang.org/x/tools v0.0.0-20200312194400-c312e98713c2 // indirect google.golang.org/api v0.9.0 - google.golang.org/grpc v1.23.0 // indirect k8s.io/apimachinery v0.0.0-20190213030929-f84a4639d8e8 // indirect k8s.io/klog v0.2.0 // indirect ) diff --git a/go.sum b/go.sum index 44c43a3140..ba9bd1d79c 100644 --- a/go.sum +++ b/go.sum @@ -20,14 +20,52 @@ cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= github.com/Azure/azure-sdk-for-go v21.3.0+incompatible h1:YFvAka2WKAl2xnJkYV1e1b7E2z88AgFszDzWU18ejMY= github.com/Azure/azure-sdk-for-go v21.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v33.2.0+incompatible h1:eDPeIqsD1UxYEcrn/DMxhfA47QcvaOXGtj4MkGIHIio= +github.com/Azure/azure-sdk-for-go v33.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v38.1.0+incompatible h1:5AawcyRJqShKENbdf2ZWJsdOnr+dEt6bz91YStCUmT4= +github.com/Azure/azure-sdk-for-go v38.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v40.3.0+incompatible h1:NthZg3psrLxvQLN6rVm07pZ9mv2wvGNaBNGQ3fnPvLE= +github.com/Azure/azure-sdk-for-go v40.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v10.15.4+incompatible h1:q+DRrRdbCnkY7f2WxQBx58TwCGkEdMAK/hkZ10g0Pzk= github.com/Azure/go-autorest v10.15.4+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest v13.0.0+incompatible h1:56c11ykhsFSPNNQuS73Ri8h/ezqVhr2h6t9LJIEKVO0= +github.com/Azure/go-autorest v13.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.2/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.3 h1:OZEIaBbMdUE/Js+BQKlpO81XlISgipr6yDJ+PSwsgi4= +github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503 h1:Hxqlh1uAA8aGpa1dFhDNhll7U/rkWtG8ZItFvRMr7l0= +github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/azure/auth v0.3.0/go.mod h1:CI4BQYBct8NS7BXNBBX+RchsFsUu5+oz+OSyR/ZIi7U= +github.com/Azure/go-autorest/autorest/azure/cli v0.2.0/go.mod h1:WWTbGPvkAg3I4ms2j2s+Zr5xCGwGqTQh+6M2ZqOczkE= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.0 h1:5PAqnv+CSTwW9mlZWZAizmzrazFWEgZykEZXpr2hDtY= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.0/go.mod h1:rNYMNAefZMRowqCV0cVhr/YDW5dD7afFq9nXAXL4ykE= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.2.0 h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 h1:pSm8mp0T2OH2CPmPDPtwHPr3VAQaOwVF/JbllOPP4xA= github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= @@ -35,6 +73,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022 h1:y8Gs8CzNfDF5AZvjr+5UyGQvQEBL7pwo+v+wX6q9JI8= github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= @@ -52,6 +91,7 @@ github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXva github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 h1:LoeFxdq5zUCBQPhbQKE6zvoGwHMxCBlqwbH9+9kHoHA= github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= +github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= @@ -65,6 +105,8 @@ github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999/go.mod h1:cp2SuWMxlE github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apparentlymart/go-cidr v1.0.0 h1:lGDvXx8Lv9QHjrAVP7jyzleG4F9+FkRhJcEsDFxeb8w= github.com/apparentlymart/go-cidr v1.0.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= +github.com/apparentlymart/go-cidr v1.0.1 h1:NmIwLZ/KdsjIUlhf+/Np40atNXm/+lZ5txfTJ/SpF+U= +github.com/apparentlymart/go-cidr v1.0.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= @@ -82,9 +124,11 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.16.36/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.19.39/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.21.7 h1:ml+k7szyVaq4YD+3LhqOGl9tgMTqgMbpnuUSkB6UJvQ= github.com/aws/aws-sdk-go v1.21.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.22.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.4 h1:exwxtR517g6OKm2rtAD5EANtjbzmnjEAco189zy/Uhc= github.com/aws/aws-sdk-go v1.25.4/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= @@ -101,12 +145,17 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmatcuk/doublestar v1.1.5 h1:2bNwBOmhyFEFcoB3tGvTD5xanq+4kyOZlB8wFYbMjkk= +github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bsm/go-vlq v0.0.0-20150828105119-ec6e8d4f5f4e/go.mod h1:N+BjUcTjSxc2mtRGSCPsat1kze3CUtvJN3/jTXlp29k= +github.com/btubbs/datetime v0.1.0 h1:183iHRjmNAokYM5D8V3wbEOOEe/HYEYpm7E2oom3vhM= +github.com/btubbs/datetime v0.1.0/go.mod h1:n2BZ/2ltnRzNiz27aE3wUb2onNttQdC+WFxAoks5jJM= +github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chr4/pwgen v1.1.0 h1:duC/1iWyXRrd/Y0I1bjR2m16ijkfqp1AxBE4E3NVn0g= @@ -114,6 +163,7 @@ github.com/chr4/pwgen v1.1.0/go.mod h1:Q9w8E+RunSCgs/ZyHZA/rd3PITSWhc0HW0Ik/XLCB github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20161106042343-c914be64f07d h1:aG5FcWiZTOhPQzYIxwxSR1zEOxzL32fwr1CsaCfhO6w= github.com/chzyer/readline v0.0.0-20161106042343-c914be64f07d/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -141,6 +191,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.0.0 h1:fGC2kkf4qOoKqZ4q7iIh+Vef4ubC1c38UDsEyZynZPc= github.com/dimchansky/utfbom v1.0.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 h1:Dzuw9GtbmllUqEcoHfScT9YpKFUssSiZ5PgZkIGf/YQ= github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -164,6 +216,7 @@ github.com/gammazero/workerpool v0.0.0-20181230203049-86a96b5d5d92/go.mod h1:w9R github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db h1:GYXWx7Vr3+zv833u+8IoXbNnQY0AdXsxAgI0kX7xcwA= github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -269,6 +322,8 @@ github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -320,6 +375,12 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-azure-helpers v0.0.0-20190129193224-166dfd221bb2 h1:VBRx+yPYUZaobnn5ANBcOUf4hhWpTHSQgftG4TcDkhI= github.com/hashicorp/go-azure-helpers v0.0.0-20190129193224-166dfd221bb2/go.mod h1:lu62V//auUow6k0IykxLK2DCNW8qTmpm8KqhYVWattA= +github.com/hashicorp/go-azure-helpers v0.4.1/go.mod h1:lu62V//auUow6k0IykxLK2DCNW8qTmpm8KqhYVWattA= +github.com/hashicorp/go-azure-helpers v0.7.0/go.mod h1:3xdjhbL7qs69rnwxA0UENOzkPJjtTFIRb5aRyrEpbCU= +github.com/hashicorp/go-azure-helpers v0.9.0 h1:KERW4n9AukvQ6kXGJdqXLaR0S2yxH3Xwj+rio/3/uLI= +github.com/hashicorp/go-azure-helpers v0.9.0/go.mod h1:3xdjhbL7qs69rnwxA0UENOzkPJjtTFIRb5aRyrEpbCU= +github.com/hashicorp/go-azure-helpers v0.10.0 h1:KhjDnQhCqEMKlt4yH00MCevJQPJ6LkHFdSveXINO6vE= +github.com/hashicorp/go-azure-helpers v0.10.0/go.mod h1:YuAtHxm2v74s+IjQwUG88dHBJPd5jL+cXr5BGVzSKhE= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= @@ -378,6 +439,8 @@ github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+Db github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl/v2 v2.0.0 h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8= +github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= github.com/hashicorp/hcl2 v0.0.0-20181208003705-670926858200/go.mod h1:ShfpTh661oAaxo7VcNxg0zcZW6jvMa7Moy2oFx7e5dE= github.com/hashicorp/hcl2 v0.0.0-20190515223218-4b22149b7cef h1:xZRvbcwHY8zhaxDwgkmpAp2emwZkVn7p3gat0zhq2X0= github.com/hashicorp/hcl2 v0.0.0-20190515223218-4b22149b7cef/go.mod h1:4oI94iqF3GB10QScn46WqbG0kgTUpha97SAzzg2+2ec= @@ -400,10 +463,19 @@ github.com/hashicorp/terraform v0.12.6 h1:mWItQdLZQ7f3kBYBu2Kgdg+E5iZb1KtCq73V10 github.com/hashicorp/terraform v0.12.6/go.mod h1:udmq5rU8CO9pEIh/A/Xrs3zb3yYU/W9ce1pp8K1ysHA= github.com/hashicorp/terraform v0.12.7 h1:4pD+XguGRMGBnERUO3Wbtmv23R26ovWpGSQ2yqIL73Q= github.com/hashicorp/terraform v0.12.7/go.mod h1:dpIRVHTSvPpGZPDKBLEw3U7nNQaJCybZoZkeJSYxg/w= +github.com/hashicorp/terraform v0.12.8 h1:51Z5K8oj42KZi0IiTf99wMTujDpvsTd3eaF1k5z1URk= +github.com/hashicorp/terraform v0.12.8/go.mod h1:8rXMj8q+hRsR/28WWWyiHu1GEDSjWaHPoV14E66X5VU= github.com/hashicorp/terraform-config-inspect v0.0.0-20190327195015-8022a2663a70 h1:oZm5nE11yhzsTRz/YrUyDMSvixePqjoZihwn8ipuOYI= github.com/hashicorp/terraform-config-inspect v0.0.0-20190327195015-8022a2663a70/go.mod h1:ItvqtvbC3K23FFET62ZwnkwtpbKZm8t8eMcWjmVVjD8= github.com/hashicorp/terraform-config-inspect v0.0.0-20190821133035-82a99dc22ef4 h1:fTkL0YwjohGyN7AqsDhz6bwcGBpT+xBqi3Qhpw58Juw= github.com/hashicorp/terraform-config-inspect v0.0.0-20190821133035-82a99dc22ef4/go.mod h1:JDmizlhaP5P0rYTTZB0reDMefAiJyfWPEtugV4in1oI= +github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8 h1:+RyjwU+Gnd/aTJBPZVDNm903eXVjjqhbaR4Ypx3xYyY= +github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= +github.com/hashicorp/terraform-plugin-sdk v1.1.0/go.mod h1:NuwtLpEpPsFaKJPJNGtMcn9vlhe6Ofe+Y6NqXhJgV2M= +github.com/hashicorp/terraform-plugin-sdk v1.6.0 h1:Um5hsAL7kKsfTHtan8lybY/d03F2bHu4fjRB1H6Ag4U= +github.com/hashicorp/terraform-plugin-sdk v1.6.0/go.mod h1:H5QLx/uhwfxBZ59Bc5SqT19M4i+fYt7LZjHTpbLZiAg= +github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596 h1:hjyO2JsNZUKT1ym+FAdlBEkGPevazYsmVgIMw7dVELg= +github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= github.com/hashicorp/vault v0.10.4/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= github.com/hashicorp/vault v1.0.1/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= github.com/hashicorp/vault v1.0.3 h1:8qfP7xbldsLHnTktm1BoxOwlHWLjqr9t7QNbkE4Wbyw= @@ -600,6 +672,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/satori/uuid v0.0.0-20160927100844-b061729afc07 h1:81vvGlnI/AZ1/TxGDirw3ofUoS64TyjmPQt5C9XODTw= +github.com/satori/uuid v0.0.0-20160927100844-b061729afc07/go.mod h1:B8HLsPLik/YNn6KKWVMDJ8nzCL8RP5WyfsnmvnAEwIU= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/securego/gosec v0.0.0-20190912120752-140048b2a218 h1:O0yPHYL49quNL4Oj2wVq+zbGMu4dAM6iLoOQtm49TrQ= @@ -608,6 +682,7 @@ github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= @@ -681,6 +756,14 @@ github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BST github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/terraform-providers/terraform-provider-aws v1.60.1-0.20191003145700-f8707a46c6ec h1:AmIB/OnEENGJK7aPbItltjktVCo5b4HTCn+mX+YNFdk= github.com/terraform-providers/terraform-provider-aws v1.60.1-0.20191003145700-f8707a46c6ec/go.mod h1:WBtfTKZq7/v9xEBGo8wqQTVrBO8XmG0tLD+/q5rdCcw= +github.com/terraform-providers/terraform-provider-azuread v0.6.0/go.mod h1:O4kN9f8f6//T2EcSe4bcICeAex00XpYC50+fbBmuQ/g= +github.com/terraform-providers/terraform-provider-azuread v0.6.1-0.20191007035844-361c0a206ad4 h1:y/dkBZSHkz38ofRGgebSARSOdRzQsH6r0gQ0B46B+uU= +github.com/terraform-providers/terraform-provider-azuread v0.6.1-0.20191007035844-361c0a206ad4/go.mod h1:nIkEKBYPFXH/yU7mY7lK5Om6Krga/aMdD/B/OEJpWzc= +github.com/terraform-providers/terraform-provider-azurerm v1.34.0/go.mod h1:FZKwNcRGtgixGjkmMR25pKQlZ7iEFNKFjJb8XB8CXqE= +github.com/terraform-providers/terraform-provider-azurerm v1.35.0 h1:oWkjaw+ZaAngSPXwrP838fQ1tnVvW3dEwJAj5a5z4uI= +github.com/terraform-providers/terraform-provider-azurerm v1.35.0/go.mod h1:kKQDh7i9qOWCvhTJmPhYU7drDpxzGuQ/sff3MV12quc= +github.com/terraform-providers/terraform-provider-azurerm v1.44.0 h1:9zehlvIyibEx0dtsZJdaeOZr4MkBhp0Ibhd4JssK3I4= +github.com/terraform-providers/terraform-provider-azurerm v1.44.0/go.mod h1:GncKl1cgz6jPcb9gvVP8agaE5YI1IGd04bwmKW1+13Q= github.com/terraform-providers/terraform-provider-google v1.20.1-0.20190924213132-8cb5c9efd9d7 h1:wC7Rs+QRkZ6V8dg7+3Fbzif4ZQoTJerA1UpxIeuVnd4= github.com/terraform-providers/terraform-provider-google v1.20.1-0.20190924213132-8cb5c9efd9d7/go.mod h1:hADxMAJiBWVWChwpjM5ukqOxOYhqImU1+E30P7ZEXh4= github.com/terraform-providers/terraform-provider-openstack v1.15.0 h1:adpjqej+F8BAX9dHmuPF47sUIkgifeqBu6p7iCsyj0Y= @@ -693,6 +776,11 @@ github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec h1:AmoEvWAO3nDx1 github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tombuildsstuff/giovanni v0.5.0/go.mod h1:Xu/XU+DiRrKTDoCnJNGuh9ysD0eJyi/zU/naFh2aN9I= +github.com/tombuildsstuff/giovanni v0.6.0 h1:8RwaDJJqbp8mMN/HOKEbGUvhW/yaGMzxN2XbkQ3lHuA= +github.com/tombuildsstuff/giovanni v0.6.0/go.mod h1:Xu/XU+DiRrKTDoCnJNGuh9ysD0eJyi/zU/naFh2aN9I= +github.com/tombuildsstuff/giovanni v0.7.1 h1:QJG5TJNIjcRbMsaQGF1HtWEpZbu8xLAOmZuMIk7wf14= +github.com/tombuildsstuff/giovanni v0.7.1/go.mod h1:Xu/XU+DiRrKTDoCnJNGuh9ysD0eJyi/zU/naFh2aN9I= github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5 h1:cMjKdf4PxEBN9K5HaD9UMW8gkTbM0kMzkTa9SJe0WNQ= github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -733,6 +821,7 @@ github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgK go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.opencensus.io v0.18.1-0.20181204023538-aab39bd6a98b/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -757,14 +846,22 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA= +golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -783,10 +880,14 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac h1:8R1esu+8QioDxo4E4mX6bFzt golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -810,8 +911,14 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc= golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191009170851-d66e71096ffb h1:TR699M2v0qoKTOHxeLgp6zPqaQNs74f01a/ob9W0qko= +golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -829,6 +936,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -845,6 +953,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -854,8 +963,11 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190911201528-7ad0cfa0b7b5 h1:SW/0nsKCUaozCUtZTakri5laocGx/5bkDSSLrFUsa5s= golang.org/x/sys v0.0.0-20190911201528-7ad0cfa0b7b5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= @@ -897,10 +1009,16 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911230505-6bfd74cf029c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190912215617-3720d1ec3678 h1:rM1Udd0CgtYI3KUIhu9ROz0QCqjW+n/ODp/hH7c60Xc= golang.org/x/tools v0.0.0-20190912215617-3720d1ec3678/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191209225234-22774f7dae43 h1:NfPq5mgc5ArFgVLCpeS4z07IoxSAqVfV/gQ5vxdgaxI= golang.org/x/tools v0.0.0-20191209225234-22774f7dae43/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200312194400-c312e98713c2 h1:6TB4+MaZlkcSsJDu+BS5yxSEuZIYhjWz+jhbSLEZylI= +golang.org/x/tools v0.0.0-20200312194400-c312e98713c2/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI= @@ -946,6 +1064,7 @@ google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= diff --git a/state/writer_test.go b/state/writer_test.go index 3effc81b91..6cda4986c6 100644 --- a/state/writer_test.go +++ b/state/writer_test.go @@ -161,7 +161,7 @@ func TestSync(t *testing.T) { } ], "serial":0, - "terraform_version":"0.12.7", + "terraform_version":"0.12.8", "version":4 }` ) From 50881c87e586fc7e2c1dcfd31a1a25cd549fd8bf Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 13 Mar 2020 19:16:49 +0100 Subject: [PATCH 08/21] azurerm: add VirtualMachine resource --- azurerm/cmd/generate.go | 8 ++++++-- azurerm/resources.go | 19 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/azurerm/cmd/generate.go b/azurerm/cmd/generate.go index 4204d5f307..d0eb6849dc 100644 --- a/azurerm/cmd/generate.go +++ b/azurerm/cmd/generate.go @@ -9,9 +9,13 @@ import ( "github.com/pkg/errors" ) -var azureAPIs []AzureAPI +var azureAPIs = []AzureAPI{ + AzureAPI{API: "compute", APIVersion: "2019-07-01"}, +} -var functions []Function +var functions = []Function{ + Function{Resource: "VirtualMachine", API: "compute", ResourceGroup: true}, +} func main() { f, err := os.OpenFile("./reader_generated.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) diff --git a/azurerm/resources.go b/azurerm/resources.go index e731e3e5a9..01be0c7294 100644 --- a/azurerm/resources.go +++ b/azurerm/resources.go @@ -3,6 +3,8 @@ package azurerm import ( "context" + "github.com/pkg/errors" + "github.com/cycloidio/terracognita/provider" "github.com/cycloidio/terracognita/tag" ) @@ -13,17 +15,26 @@ type ResourceType int //go:generate enumer -type ResourceType -addprefix azurerm_ -transform snake -linecomment const ( - DummyResource ResourceType = iota + VirtualMachine ResourceType = iota ) type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) var ( resources = map[ResourceType]rtFn{ - DummyResource: dummyResource, + VirtualMachine: virtualMachines, } ) -func dummyResource(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { - return nil, nil +func virtualMachines(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + virtualMachines, err := a.azurer.ListVirtualMachines(ctx) + if err != nil { + return nil, errors.Wrap(err, "unable to list virtual machines from reader") + } + resources := make([]provider.Resource, 0, len(virtualMachines)) + for _, virtualMachine := range virtualMachines { + r := provider.NewResource(*virtualMachine.ID, resourceType, a) + resources = append(resources, r) + } + return resources, nil } From 406a803866e56f6709c5c7fd09103d9c6092d4e0 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Tue, 24 Mar 2020 12:09:18 +0100 Subject: [PATCH 09/21] azurerm: add VirtualNetwork resource --- azurerm/cmd/generate.go | 2 ++ azurerm/resources.go | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/azurerm/cmd/generate.go b/azurerm/cmd/generate.go index d0eb6849dc..758c5cce17 100644 --- a/azurerm/cmd/generate.go +++ b/azurerm/cmd/generate.go @@ -11,10 +11,12 @@ import ( var azureAPIs = []AzureAPI{ AzureAPI{API: "compute", APIVersion: "2019-07-01"}, + AzureAPI{API: "network", APIVersion: "2019-06-01"}, } var functions = []Function{ Function{Resource: "VirtualMachine", API: "compute", ResourceGroup: true}, + Function{Resource: "VirtualNetwork", API: "network", ResourceGroup: true}, } func main() { diff --git a/azurerm/resources.go b/azurerm/resources.go index 01be0c7294..2f802519c7 100644 --- a/azurerm/resources.go +++ b/azurerm/resources.go @@ -16,6 +16,7 @@ type ResourceType int //go:generate enumer -type ResourceType -addprefix azurerm_ -transform snake -linecomment const ( VirtualMachine ResourceType = iota + VirtualNetwork ) type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) @@ -23,6 +24,7 @@ type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag. var ( resources = map[ResourceType]rtFn{ VirtualMachine: virtualMachines, + VirtualNetwork: virtualNetworks, } ) @@ -38,3 +40,16 @@ func virtualMachines(ctx context.Context, a *azurerm, resourceType string, tags } return resources, nil } + +func virtualNetworks(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + virtualNetworks, err := a.azurer.ListVirtualNetworks(ctx) + if err != nil { + return nil, errors.Wrap(err, "unable to list virtual networks from reader") + } + resources := make([]provider.Resource, 0, len(virtualNetworks)) + for _, virtualNetwork := range virtualNetworks { + r := provider.NewResource(*virtualNetwork.ID, resourceType, a) + resources = append(resources, r) + } + return resources, nil +} From 8ad95c558b4b00a3280496f7fdeb84097d581e4b Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Tue, 24 Mar 2020 18:06:19 +0100 Subject: [PATCH 10/21] azurerm: add ResourceGroup resource --- azurerm/reader.go | 5 +++++ azurerm/resources.go | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/azurerm/reader.go b/azurerm/reader.go index ebd4c0cf95..261f779e6f 100644 --- a/azurerm/reader.go +++ b/azurerm/reader.go @@ -75,6 +75,11 @@ func NewAzureReader(ctx context.Context, clientID, clientSecret, environment, re }, nil } +// GetResourceGroup returns the current Resource Group resource +func (ar *AzureReader) GetResourceGroup() azureResourcesAPI.Group { + return ar.resourceGroup +} + // GetResourceGroupName returns the current Resource Group name func (ar *AzureReader) GetResourceGroupName() string { return *ar.resourceGroup.Name diff --git a/azurerm/resources.go b/azurerm/resources.go index 2f802519c7..dfc55ace5c 100644 --- a/azurerm/resources.go +++ b/azurerm/resources.go @@ -15,7 +15,8 @@ type ResourceType int //go:generate enumer -type ResourceType -addprefix azurerm_ -transform snake -linecomment const ( - VirtualMachine ResourceType = iota + ResourceGroup ResourceType = iota + VirtualMachine VirtualNetwork ) @@ -23,11 +24,19 @@ type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag. var ( resources = map[ResourceType]rtFn{ + ResourceGroup: resourceGroup, VirtualMachine: virtualMachines, VirtualNetwork: virtualNetworks, } ) +func resourceGroup(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + resourceGroup := a.azurer.GetResourceGroup() + r := provider.NewResource(*resourceGroup.ID, resourceType, a) + resources := []provider.Resource{r} + return resources, nil +} + func virtualMachines(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { virtualMachines, err := a.azurer.ListVirtualMachines(ctx) if err != nil { From 48a8bf9f8d6e736f88b5753d7528f424c18d0a44 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Thu, 26 Mar 2020 13:31:46 +0100 Subject: [PATCH 11/21] azurerm: add Subnet resource --- azurerm/cmd/generate.go | 1 + azurerm/resources.go | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/azurerm/cmd/generate.go b/azurerm/cmd/generate.go index 758c5cce17..71622b43c7 100644 --- a/azurerm/cmd/generate.go +++ b/azurerm/cmd/generate.go @@ -17,6 +17,7 @@ var azureAPIs = []AzureAPI{ var functions = []Function{ Function{Resource: "VirtualMachine", API: "compute", ResourceGroup: true}, Function{Resource: "VirtualNetwork", API: "network", ResourceGroup: true}, + Function{Resource: "Subnet", API: "network", ResourceGroup: true, ExtraArgs: []string{"virtualNetworkName"}}, } func main() { diff --git a/azurerm/resources.go b/azurerm/resources.go index dfc55ace5c..0c6a41fff0 100644 --- a/azurerm/resources.go +++ b/azurerm/resources.go @@ -18,6 +18,7 @@ const ( ResourceGroup ResourceType = iota VirtualMachine VirtualNetwork + Subnet ) type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) @@ -27,6 +28,7 @@ var ( ResourceGroup: resourceGroup, VirtualMachine: virtualMachines, VirtualNetwork: virtualNetworks, + Subnet: subnets, } ) @@ -62,3 +64,22 @@ func virtualNetworks(ctx context.Context, a *azurerm, resourceType string, tags } return resources, nil } + +func subnets(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + virtualNetworks, err := a.azurer.ListVirtualNetworks(ctx) + if err != nil { + return nil, errors.Wrap(err, "unable to list virtual networks from reader") + } + resources := make([]provider.Resource, 0) + for _, virtualNetwork := range virtualNetworks { + subnets, err := a.azurer.ListSubnets(ctx, *virtualNetwork.Name) + if err != nil { + return nil, errors.Wrap(err, "unable to list subnets from reader") + } + for _, subnet := range subnets { + r := provider.NewResource(*subnet.ID, resourceType, a) + resources = append(resources, r) + } + } + return resources, nil +} From db99288000afeef8c599a9b5ce10ba6703fce430 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Thu, 26 Mar 2020 13:56:30 +0100 Subject: [PATCH 12/21] azurerm: add NetworkInterface resource --- azurerm/cmd/generate.go | 1 + azurerm/resources.go | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/azurerm/cmd/generate.go b/azurerm/cmd/generate.go index 71622b43c7..ed4508bb5e 100644 --- a/azurerm/cmd/generate.go +++ b/azurerm/cmd/generate.go @@ -18,6 +18,7 @@ var functions = []Function{ Function{Resource: "VirtualMachine", API: "compute", ResourceGroup: true}, Function{Resource: "VirtualNetwork", API: "network", ResourceGroup: true}, Function{Resource: "Subnet", API: "network", ResourceGroup: true, ExtraArgs: []string{"virtualNetworkName"}}, + Function{Resource: "Interface", API: "network", ResourceGroup: true}, } func main() { diff --git a/azurerm/resources.go b/azurerm/resources.go index 0c6a41fff0..fa2633da8c 100644 --- a/azurerm/resources.go +++ b/azurerm/resources.go @@ -19,16 +19,18 @@ const ( VirtualMachine VirtualNetwork Subnet + NetworkInterface ) type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) var ( resources = map[ResourceType]rtFn{ - ResourceGroup: resourceGroup, - VirtualMachine: virtualMachines, - VirtualNetwork: virtualNetworks, - Subnet: subnets, + ResourceGroup: resourceGroup, + VirtualMachine: virtualMachines, + VirtualNetwork: virtualNetworks, + Subnet: subnets, + NetworkInterface: networkInterfaces, } ) @@ -83,3 +85,16 @@ func subnets(ctx context.Context, a *azurerm, resourceType string, tags []tag.Ta } return resources, nil } + +func networkInterfaces(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + networkInterfaces, err := a.azurer.ListInterfaces(ctx) + if err != nil { + return nil, errors.Wrap(err, "unable to list network interfaces from reader") + } + resources := make([]provider.Resource, 0, len(networkInterfaces)) + for _, networkInterface := range networkInterfaces { + r := provider.NewResource(*networkInterface.ID, resourceType, a) + resources = append(resources, r) + } + return resources, nil +} From 8a9edb59e970357a36636b598837a9197563e9f7 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Thu, 26 Mar 2020 15:25:28 +0100 Subject: [PATCH 13/21] azurerm: add NetworkSecurityGroup resource --- azurerm/cmd/generate.go | 1 + azurerm/resources.go | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/azurerm/cmd/generate.go b/azurerm/cmd/generate.go index ed4508bb5e..6cf03ad485 100644 --- a/azurerm/cmd/generate.go +++ b/azurerm/cmd/generate.go @@ -19,6 +19,7 @@ var functions = []Function{ Function{Resource: "VirtualNetwork", API: "network", ResourceGroup: true}, Function{Resource: "Subnet", API: "network", ResourceGroup: true, ExtraArgs: []string{"virtualNetworkName"}}, Function{Resource: "Interface", API: "network", ResourceGroup: true}, + Function{Resource: "SecurityGroup", API: "network", ResourceGroup: true}, } func main() { diff --git a/azurerm/resources.go b/azurerm/resources.go index fa2633da8c..c1e4db1b2f 100644 --- a/azurerm/resources.go +++ b/azurerm/resources.go @@ -20,17 +20,19 @@ const ( VirtualNetwork Subnet NetworkInterface + NetworkSecurityGroup ) type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) var ( resources = map[ResourceType]rtFn{ - ResourceGroup: resourceGroup, - VirtualMachine: virtualMachines, - VirtualNetwork: virtualNetworks, - Subnet: subnets, - NetworkInterface: networkInterfaces, + ResourceGroup: resourceGroup, + VirtualMachine: virtualMachines, + VirtualNetwork: virtualNetworks, + Subnet: subnets, + NetworkInterface: networkInterfaces, + NetworkSecurityGroup: networkSecurityGroups, } ) @@ -98,3 +100,16 @@ func networkInterfaces(ctx context.Context, a *azurerm, resourceType string, tag } return resources, nil } + +func networkSecurityGroups(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + securityGroups, err := a.azurer.ListSecurityGroups(ctx) + if err != nil { + return nil, errors.Wrap(err, "unable to list network security groups from reader") + } + resources := make([]provider.Resource, 0, len(securityGroups)) + for _, securityGroup := range securityGroups { + r := provider.NewResource(*securityGroup.ID, resourceType, a) + resources = append(resources, r) + } + return resources, nil +} From 6dfa9b900f3d4eb0e47a3df147073bf6544e653a Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 27 Mar 2020 17:53:03 +0100 Subject: [PATCH 14/21] azurerm: add VirtualMachineScaleSet resource --- azurerm/cmd/generate.go | 1 + azurerm/resources.go | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/azurerm/cmd/generate.go b/azurerm/cmd/generate.go index 6cf03ad485..a358ef970f 100644 --- a/azurerm/cmd/generate.go +++ b/azurerm/cmd/generate.go @@ -20,6 +20,7 @@ var functions = []Function{ Function{Resource: "Subnet", API: "network", ResourceGroup: true, ExtraArgs: []string{"virtualNetworkName"}}, Function{Resource: "Interface", API: "network", ResourceGroup: true}, Function{Resource: "SecurityGroup", API: "network", ResourceGroup: true}, + Function{Resource: "VirtualMachineScaleSet", API: "compute", ResourceGroup: true}, } func main() { diff --git a/azurerm/resources.go b/azurerm/resources.go index c1e4db1b2f..29afcd9c5c 100644 --- a/azurerm/resources.go +++ b/azurerm/resources.go @@ -21,18 +21,20 @@ const ( Subnet NetworkInterface NetworkSecurityGroup + VirtualMachineScaleSet ) type rtFn func(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) var ( resources = map[ResourceType]rtFn{ - ResourceGroup: resourceGroup, - VirtualMachine: virtualMachines, - VirtualNetwork: virtualNetworks, - Subnet: subnets, - NetworkInterface: networkInterfaces, - NetworkSecurityGroup: networkSecurityGroups, + ResourceGroup: resourceGroup, + VirtualMachine: virtualMachines, + VirtualNetwork: virtualNetworks, + Subnet: subnets, + NetworkInterface: networkInterfaces, + NetworkSecurityGroup: networkSecurityGroups, + VirtualMachineScaleSet: virtualMachineScaleSets, } ) @@ -113,3 +115,16 @@ func networkSecurityGroups(ctx context.Context, a *azurerm, resourceType string, } return resources, nil } + +func virtualMachineScaleSets(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + virtualMachineScaleSets, err := a.azurer.ListVirtualMachineScaleSets(ctx) + if err != nil { + return nil, errors.Wrap(err, "unable to list virtual machines scale sets from reader") + } + resources := make([]provider.Resource, 0, len(virtualMachineScaleSets)) + for _, virtualMachineScaleSet := range virtualMachineScaleSets { + r := provider.NewResource(*virtualMachineScaleSet.ID, resourceType, a) + resources = append(resources, r) + } + return resources, nil +} From 5e6d1614eb7db1f2061536f9badec382f54301d8 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 13 Mar 2020 19:02:16 +0100 Subject: [PATCH 15/21] makefile: add enumer target and generate prerequisites --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bff5f7a8ab..a4bbd6fde8 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ BIN_DIR := $(GOPATH)/bin GOLINT := $(BIN_DIR)/golinter GOIMPORTS := $(BIN_DIR)/goimports +ENUMER := $(BIN_DIR)/enumer MOCKGEN := $(BIN_DIR)/mockgen VERSION= $(shell git describe --tags --always) @@ -34,6 +35,9 @@ $(MOCKGEN): $(GOIMPORTS): @go get -u golang.org/x/tools/cmd/goimports +$(ENUMER): + @go get -u github.com/dmarkham/enumer + $(GOLINT): @go get -u golang.org/x/lint/golint @@ -42,7 +46,7 @@ lint: $(GOLINT) $(GOIMPORTS) ## Runs the linter @GO111MODULE=on golint -set_exit_status ./... && test -z "`go list -f {{.Dir}} ./... | xargs goimports -l | tee /dev/stderr`" .PHONY: generate -generate: $(MOCKGEN) ## Generates the needed code +generate: $(MOCKGEN) $(GOIMPORTS) $(ENUMER) ## Generates the needed code @GO111MODULE=on rm -rf ./mock/a && \ go generate ./... && \ goimports -w ./mock From 642b8347a6891628da97cebe3d063e94250ca48c Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Mon, 30 Mar 2020 12:34:48 +0200 Subject: [PATCH 16/21] azurerm: add cache to avoid calling the API multiple times for some resources In order to get some resources, you need to provide the name of another resource linked to it. For example, to get subnets you will need to give the virtual network name when using the SDK List method. --- azurerm/cache.go | 45 ++++++++++++++++++++++++++++++++++++++++++++ azurerm/provider.go | 4 ++++ azurerm/resources.go | 15 ++++++++++----- 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 azurerm/cache.go diff --git a/azurerm/cache.go b/azurerm/cache.go new file mode 100644 index 0000000000..6bdeb1c1c6 --- /dev/null +++ b/azurerm/cache.go @@ -0,0 +1,45 @@ +package azurerm + +import ( + "context" + + "github.com/cycloidio/terracognita/errcode" + "github.com/cycloidio/terracognita/provider" + "github.com/cycloidio/terracognita/tag" + "github.com/pkg/errors" +) + +func cacheVirtualNetworks(ctx context.Context, a *azurerm, rt string, tags []tag.Tag) ([]provider.Resource, error) { + rs, err := a.cache.Get(rt) + if err != nil { + if errors.Cause(err) != errcode.ErrCacheKeyNotFound { + return nil, errors.WithStack(err) + } + + rs, err = virtualNetworks(ctx, a, rt, tags) + if err != nil { + return nil, errors.Wrap(err, "unable to get virtual networks") + } + + err = a.cache.Set(rt, rs) + if err != nil { + return nil, err + } + } + + return rs, nil +} + +func getVirtualNetworkNames(ctx context.Context, a *azurerm, rt string, tags []tag.Tag) ([]string, error) { + rs, err := cacheVirtualNetworks(ctx, a, rt, tags) + if err != nil { + return nil, err + } + + names := make([]string, 0, len(rs)) + for _, i := range rs { + names = append(names, i.Data().Get("name").(string)) + } + + return names, nil +} diff --git a/azurerm/provider.go b/azurerm/provider.go index 0207c53a8b..fd28853515 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -10,6 +10,7 @@ import ( "github.com/pkg/errors" tfazurerm "github.com/terraform-providers/terraform-provider-azurerm/azurerm" + "github.com/cycloidio/terracognita/cache" "github.com/cycloidio/terracognita/filter" "github.com/cycloidio/terracognita/log" "github.com/cycloidio/terracognita/provider" @@ -19,6 +20,8 @@ type azurerm struct { tfAzureRMClient interface{} tfProvider *schema.Provider azurer *AzureReader + + cache cache.Cache } // NewProvider returns a AzureRM Provider @@ -52,6 +55,7 @@ func NewProvider(ctx context.Context, clientID, clientSecret, environment, resou tfAzureRMClient: tfp.Meta(), tfProvider: tfp, azurer: reader, + cache: cache.New(), }, nil } diff --git a/azurerm/resources.go b/azurerm/resources.go index 29afcd9c5c..325281e3c4 100644 --- a/azurerm/resources.go +++ b/azurerm/resources.go @@ -30,7 +30,7 @@ var ( resources = map[ResourceType]rtFn{ ResourceGroup: resourceGroup, VirtualMachine: virtualMachines, - VirtualNetwork: virtualNetworks, + VirtualNetwork: cacheVirtualNetworks, Subnet: subnets, NetworkInterface: networkInterfaces, NetworkSecurityGroup: networkSecurityGroups, @@ -66,19 +66,24 @@ func virtualNetworks(ctx context.Context, a *azurerm, resourceType string, tags resources := make([]provider.Resource, 0, len(virtualNetworks)) for _, virtualNetwork := range virtualNetworks { r := provider.NewResource(*virtualNetwork.ID, resourceType, a) + // we set the name prior of reading it from the state + // as it is required to able to List resources depending on this one + if err := r.Data().Set("name", *virtualNetwork.Name); err != nil { + return nil, errors.Wrapf(err, "unable to set name data on the provider.Resource for the virtual network '%s'", *virtualNetwork.Name) + } resources = append(resources, r) } return resources, nil } func subnets(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { - virtualNetworks, err := a.azurer.ListVirtualNetworks(ctx) + virtualNetworkNames, err := getVirtualNetworkNames(ctx, a, resourceType, tags) if err != nil { - return nil, errors.Wrap(err, "unable to list virtual networks from reader") + return nil, errors.Wrap(err, "unable to list virtual networks from cache") } resources := make([]provider.Resource, 0) - for _, virtualNetwork := range virtualNetworks { - subnets, err := a.azurer.ListSubnets(ctx, *virtualNetwork.Name) + for _, virtualNetworkName := range virtualNetworkNames { + subnets, err := a.azurer.ListSubnets(ctx, virtualNetworkName) if err != nil { return nil, errors.Wrap(err, "unable to list subnets from reader") } From ed8346d754a71b18b39231e16da7fa998c6ee127 Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Fri, 13 Mar 2020 19:22:10 +0100 Subject: [PATCH 17/21] azurerm: make generate --- azurerm/reader_generated.go | 149 +++++++++++++++++++++++++++++++++ azurerm/resourcetype_enumer.go | 43 ++++++++-- 2 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 azurerm/reader_generated.go diff --git a/azurerm/reader_generated.go b/azurerm/reader_generated.go new file mode 100644 index 0000000000..8709c6c703 --- /dev/null +++ b/azurerm/reader_generated.go @@ -0,0 +1,149 @@ +package azurerm + +// Code generated by 'go generate'; DO NOT EDIT +import ( + "context" + + "github.com/pkg/errors" + + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network" +) + +// ListVirtualMachines returns a list of VirtualMachines within a subscription and a resource group +func (ar *AzureReader) ListVirtualMachines(ctx context.Context) ([]compute.VirtualMachine, error) { + client := compute.NewVirtualMachinesClient(ar.config.SubscriptionID) + client.Authorizer = ar.authorizer + + output, err := client.List(ctx, ar.GetResourceGroupName()) + if err != nil { + return nil, errors.Wrap(err, "unable to list compute.VirtualMachine from Azure APIs") + } + resources := make([]compute.VirtualMachine, 0) + for output.NotDone() { + + for _, res := range output.Values() { + resources = append(resources, res) + } + + if err := output.NextWithContext(ctx); err != nil { + break + } + } + return resources, nil +} + +// ListVirtualNetworks returns a list of VirtualNetworks within a subscription and a resource group +func (ar *AzureReader) ListVirtualNetworks(ctx context.Context) ([]network.VirtualNetwork, error) { + client := network.NewVirtualNetworksClient(ar.config.SubscriptionID) + client.Authorizer = ar.authorizer + + output, err := client.List(ctx, ar.GetResourceGroupName()) + if err != nil { + return nil, errors.Wrap(err, "unable to list network.VirtualNetwork from Azure APIs") + } + resources := make([]network.VirtualNetwork, 0) + for output.NotDone() { + + for _, res := range output.Values() { + resources = append(resources, res) + } + + if err := output.NextWithContext(ctx); err != nil { + break + } + } + return resources, nil +} + +// ListSubnets returns a list of Subnets within a subscription and a resource group +func (ar *AzureReader) ListSubnets(ctx context.Context, virtualNetworkName string) ([]network.Subnet, error) { + client := network.NewSubnetsClient(ar.config.SubscriptionID) + client.Authorizer = ar.authorizer + + output, err := client.List(ctx, ar.GetResourceGroupName(), virtualNetworkName) + if err != nil { + return nil, errors.Wrap(err, "unable to list network.Subnet from Azure APIs") + } + resources := make([]network.Subnet, 0) + for output.NotDone() { + + for _, res := range output.Values() { + resources = append(resources, res) + } + + if err := output.NextWithContext(ctx); err != nil { + break + } + } + return resources, nil +} + +// ListInterfaces returns a list of Interfaces within a subscription and a resource group +func (ar *AzureReader) ListInterfaces(ctx context.Context) ([]network.Interface, error) { + client := network.NewInterfacesClient(ar.config.SubscriptionID) + client.Authorizer = ar.authorizer + + output, err := client.List(ctx, ar.GetResourceGroupName()) + if err != nil { + return nil, errors.Wrap(err, "unable to list network.Interface from Azure APIs") + } + resources := make([]network.Interface, 0) + for output.NotDone() { + + for _, res := range output.Values() { + resources = append(resources, res) + } + + if err := output.NextWithContext(ctx); err != nil { + break + } + } + return resources, nil +} + +// ListSecurityGroups returns a list of SecurityGroups within a subscription and a resource group +func (ar *AzureReader) ListSecurityGroups(ctx context.Context) ([]network.SecurityGroup, error) { + client := network.NewSecurityGroupsClient(ar.config.SubscriptionID) + client.Authorizer = ar.authorizer + + output, err := client.List(ctx, ar.GetResourceGroupName()) + if err != nil { + return nil, errors.Wrap(err, "unable to list network.SecurityGroup from Azure APIs") + } + resources := make([]network.SecurityGroup, 0) + for output.NotDone() { + + for _, res := range output.Values() { + resources = append(resources, res) + } + + if err := output.NextWithContext(ctx); err != nil { + break + } + } + return resources, nil +} + +// ListVirtualMachineScaleSets returns a list of VirtualMachineScaleSets within a subscription and a resource group +func (ar *AzureReader) ListVirtualMachineScaleSets(ctx context.Context) ([]compute.VirtualMachineScaleSet, error) { + client := compute.NewVirtualMachineScaleSetsClient(ar.config.SubscriptionID) + client.Authorizer = ar.authorizer + + output, err := client.List(ctx, ar.GetResourceGroupName()) + if err != nil { + return nil, errors.Wrap(err, "unable to list compute.VirtualMachineScaleSet from Azure APIs") + } + resources := make([]compute.VirtualMachineScaleSet, 0) + for output.NotDone() { + + for _, res := range output.Values() { + resources = append(resources, res) + } + + if err := output.NextWithContext(ctx); err != nil { + break + } + } + return resources, nil +} diff --git a/azurerm/resourcetype_enumer.go b/azurerm/resourcetype_enumer.go index 82c58ca0cb..2f7d09d7da 100644 --- a/azurerm/resourcetype_enumer.go +++ b/azurerm/resourcetype_enumer.go @@ -6,11 +6,11 @@ import ( "fmt" ) -const _ResourceTypeName = "azurerm_dummy_resource" +const _ResourceTypeName = "azurerm_resource_groupazurerm_virtual_machineazurerm_virtual_networkazurerm_subnetazurerm_network_interfaceazurerm_network_security_groupazurerm_virtual_machine_scale_set" -var _ResourceTypeIndex = [...]uint8{0, 22} +var _ResourceTypeIndex = [...]uint8{0, 22, 45, 68, 82, 107, 137, 170} -const _ResourceTypeLowerName = "azurerm_dummy_resource" +const _ResourceTypeLowerName = "azurerm_resource_groupazurerm_virtual_machineazurerm_virtual_networkazurerm_subnetazurerm_network_interfaceazurerm_network_security_groupazurerm_virtual_machine_scale_set" func (i ResourceType) String() string { if i < 0 || i >= ResourceType(len(_ResourceTypeIndex)-1) { @@ -19,15 +19,46 @@ func (i ResourceType) String() string { return _ResourceTypeName[_ResourceTypeIndex[i]:_ResourceTypeIndex[i+1]] } -var _ResourceTypeValues = []ResourceType{0} +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _ResourceTypeNoOp() { + var x [1]struct{} + _ = x[ResourceGroup-(0)] + _ = x[VirtualMachine-(1)] + _ = x[VirtualNetwork-(2)] + _ = x[Subnet-(3)] + _ = x[NetworkInterface-(4)] + _ = x[NetworkSecurityGroup-(5)] + _ = x[VirtualMachineScaleSet-(6)] +} + +var _ResourceTypeValues = []ResourceType{ResourceGroup, VirtualMachine, VirtualNetwork, Subnet, NetworkInterface, NetworkSecurityGroup, VirtualMachineScaleSet} var _ResourceTypeNameToValueMap = map[string]ResourceType{ - _ResourceTypeName[0:22]: 0, - _ResourceTypeLowerName[0:22]: 0, + _ResourceTypeName[0:22]: ResourceGroup, + _ResourceTypeLowerName[0:22]: ResourceGroup, + _ResourceTypeName[22:45]: VirtualMachine, + _ResourceTypeLowerName[22:45]: VirtualMachine, + _ResourceTypeName[45:68]: VirtualNetwork, + _ResourceTypeLowerName[45:68]: VirtualNetwork, + _ResourceTypeName[68:82]: Subnet, + _ResourceTypeLowerName[68:82]: Subnet, + _ResourceTypeName[82:107]: NetworkInterface, + _ResourceTypeLowerName[82:107]: NetworkInterface, + _ResourceTypeName[107:137]: NetworkSecurityGroup, + _ResourceTypeLowerName[107:137]: NetworkSecurityGroup, + _ResourceTypeName[137:170]: VirtualMachineScaleSet, + _ResourceTypeLowerName[137:170]: VirtualMachineScaleSet, } var _ResourceTypeNames = []string{ _ResourceTypeName[0:22], + _ResourceTypeName[22:45], + _ResourceTypeName[45:68], + _ResourceTypeName[68:82], + _ResourceTypeName[82:107], + _ResourceTypeName[107:137], + _ResourceTypeName[137:170], } // ResourceTypeString retrieves an enum value from the enum constants string name. From d688f3b7f9890fe184b166a035bef262ee8ed50c Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Thu, 26 Mar 2020 13:32:47 +0100 Subject: [PATCH 18/21] hcl: fix typo --- hcl/writer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hcl/writer.go b/hcl/writer.go index 65531a9858..c6a358efa1 100644 --- a/hcl/writer.go +++ b/hcl/writer.go @@ -151,7 +151,7 @@ func (w *Writer) Interpolate(i map[string]string) { } // walk through a resource block. it's easier since we do not know how the block is made -// `dest` will be the new "block" with the values inteprolated from `interpolate` +// `dest` will be the new "block" with the values interpolated from `interpolate` func walk(dest, src reflect.Value, interpolate map[string]string, name string, resourceType string) { switch src.Kind() { // it's an interface, so we basically need From 21f3387820bae5577c277acb634ebde5607c23ec Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Mon, 30 Mar 2020 13:03:24 +0200 Subject: [PATCH 19/21] README: mention the AzureRM provider --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 50bf6e489d..5360ccc60d 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,12 @@ We decided to opensource this tool as we believe that it will help people to ado ## Cloud providers -Terracognita currently imports AWS and GCP cloud provider as terraform (0.12.7) resource/state. +Terracognita currently imports AWS, GCP and AzureRM cloud provider as terraform (0.12.8) resource/state. Please see the following versions as follow: Providers: * AWS: 2.31.0 + * AzureRM: 1.35.0 * GCP: 2.16.0 ## Installation From a183edef1ae5740fa3708a42e4c0bdc42d773edf Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Mon, 30 Mar 2020 13:23:21 +0200 Subject: [PATCH 20/21] CONTRIBUTING: add AzureRM how-to --- CONTRIBUTING.md | 179 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 144 insertions(+), 35 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2d0578d8d5..a03a558fa6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ There are 6 types of labels, they can be used for issues or PRs: - `bug`: These track bugs with the code - `docs`: These track problems with the documentation (i.e. missing or incomplete) - `maintenance`: These tracks problems, update and migration for dependencies / third-party tools -- `refactoring`: These tracks internal improvment with no direct impact on the product +- `refactoring`: These tracks internal improvement with no direct impact on the product - `need review`: this status must be set when you feel confident with your submission - `in progress`: some important change has been requested on your submission, so you can toggle from `need review` to `in progress` - `under discussion`: it's time to take a break, think about this submission and try to figure out how we can implement this or this @@ -33,7 +33,7 @@ $ git clone https://github.com//terracognita.git $ cd terracognita ``` -In order to stay updated with the upstream, it's highly recommended to add cycloidio/terracognita as a remote upstream. +In order to stay updated with the upstream, it's highly recommended to add `cycloidio/terracognita` as a remote upstream. ```shell $ git remote add upstream https://github.com/cycloidio/terracognita.git @@ -50,7 +50,7 @@ $ git rebase upstream/master #### Build from sources -Since Terracognita is a Go project, Go must be installed and configured on your machine (really ?). We currently support Go1.12 and Go.13 and go `modules` as dependency manager. You can simply pull all necessaries dependencies by running an initial +Since Terracognita is a Go project, Go must be installed and configured on your machine (really ?). We currently support Go1.12 and Go.13 and go `modules` as dependency manager. You can simply pull all necessaries dependencies by running an initial. ```shell $ make build @@ -59,16 +59,21 @@ $ make build This basically builds `terracognita` with the current sources. You also need to install other code dependencies not mandatory in the runtime environment: - * [enumer](https://github.com/dmarkham/enumer) is used to play around AWS or GCP provider, it is used to generate some code - * [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) is used to format / organize code and imports. CI will perform a check on this, we highly recommend to run `$ goimports -w ` + * [enumer](https://github.com/dmarkham/enumer) is used to generate some code. + * [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) is used to format / organize code and imports. CI will perform a check on this, we highly recommend to run `$ goimports -w `. #### Add a component to an existing provider (AWS or GCP) -We currently support two providers: Amazon Web Services (AWS) and Google Cloud Platform (GCP). If you want to play around with one of this provider, you can follow the following guidelines. +We currently support three providers: Amazon Web Services (AWS), Google Cloud Platform (GCP) and Azure Resource Manager (AzureRM). If you want to play around with one of this provider, you can follow the following guidelines. For both providers, you need to add your component to this places or equivalent: -* As a `const` value [here](https://github.com/cycloidio/terracognita/blob/000789d3bd61b81cf10695d414f4f45346ccc25f/google/resources.go#L17) for Google and [here](https://github.com/cycloidio/terracognita/blob/000789d3bd61b81cf10695d414f4f45346ccc25f/aws/resources.go#L22) for AWS. :warning: your component name must exactly maps the name as in Terraform documentation. Example: `ComputeInstance` will be later used as `google_compute_instance` :warning:. +* As a `const` value: + * [here](https://github.com/cycloidio/terracognita/blob/21f3387820bae5577c277acb634ebde5607c23ec/aws/resources.go#L23) for AWS. + * [here](https://github.com/cycloidio/terracognita/blob/21f3387820bae5577c277acb634ebde5607c23ec/azurerm/resources.go#L17) for AzureRM. + * [here](https://github.com/cycloidio/terracognita/blob/21f3387820bae5577c277acb634ebde5607c23ec/google/resources.go#L19) for Google. + +:warning: your component name must exactly map the name as in Terraform documentation. Example: `ComputeInstance` will be later used as `google_compute_instance` :warning:. ```go //go:generate enumer -type ResourceType -addprefix google_ -transform snake -linecomment @@ -76,15 +81,23 @@ For both providers, you need to add your component to this places or equivalent: This means you will need to generate some code. -* As a `key/value`, in this [array](https://github.com/cycloidio/terracognita/blob/000789d3bd61b81cf10695d414f4f45346ccc25f/google/resources.go#L25)([here](https://github.com/cycloidio/terracognita/blob/000789d3bd61b81cf10695d414f4f45346ccc25f/aws/resources.go#L96) for AWS). This is where you map your component with a middleware function. +* As a `key/value`, in this: + * [array](https://github.com/cycloidio/terracognita/blob/21f3387820bae5577c277acb634ebde5607c23ec/aws/resources.go#L111) for AWS. + * [array](https://github.com/cycloidio/terracognita/blob/21f3387820bae5577c277acb634ebde5607c23ec/azurerm/resources.go#L30) for AzureRM. + * [array](https://github.com/cycloidio/terracognita/blob/21f3387820bae5577c277acb634ebde5607c23ec/google/resources.go#L46) for Google. + +This is where you map your component with a middleware function. ```go -... -ComputeInstance: computeInstance, -... +var ( + resources = map[ResourceType]rtFn{ + ... + ComputeInstance: computeInstances, + } +) ``` -Now, you can write your `computeInstance` function. Check-out the other functions, you basically fetch resources from a middleware layer and you add them as Terraform resources. +Now, you can write your `computeInstances` function. Check-out the other functions, you basically fetch resources from a middleware layer and you add them as Terraform resources. ##### AWS Middleware layer @@ -96,14 +109,16 @@ We have an `aws/cmd` that generates the `aws/reader` interface, which is then us Functions are based on `https://github.com/aws/aws-sdk-go/tree/master/service`. For example with `aws_db_parameter_group` you should be able to find the Entity, Prefix, Service in https://github.com/aws/aws-sdk-go/blob/master/service/rds/rdsiface/interface.go#L313 -In our case we want to read data, the dedicated function is `DescribeDBParameterGroups` +In our case we want to read data, the dedicated function is `DescribeDBParameterGroups`. * Entity: use the function name without prefix "DBParameterGroups" - * Prefix: use the function prefix (generaly Describe, List or Get) + * Prefix: use the function prefix (generally Describe, List or Get) * Service: SubDirectory from aws-sdk-go service `service/rds` +```shell +$ vim aws/cmd/functions.go ``` -vim aws/cmd/functions.go +```go Function{ Entity: "DBParameterGroups", @@ -119,35 +134,35 @@ vim aws/cmd/functions.go Functions are used to generate Get methods in `aws/reader/reader.go`. After a `make generate` execution, we should find a `GetDBParameterGroups` method at the end of the file corresponding to our previous example. - 2. Add your resource type The naming is based on terraform resources like `aws_db_parameter_group` but without the `aws` prefix and Snake case like `bla_foo` needs to be replaced by Camel case `blaFoo`. The function should start with a `lowercase` and end with a `s`. The end result would be `dbParameterGroups`. - +```shell +$ vim aws/resources.go ``` -vim aws/resources.go - - +```go const ( - - DBParameterGroup + ... + DBParameterGroup +) ... -resources = map[ResourceType]rtFn{ - DBParameterGroup: dbParameterGroups, - +var ( + resources = map[ResourceType]rtFn{ + DBParameterGroup: dbParameterGroups, + ... + } +) ``` -const is used to generate resourcetype_enumer.go - +The const is used to generate `aws/resourcetype_enumer.go`. 3. Add the associated function to generate terraform codes. - -``` +```go func dbParameterGroups(ctx context.Context, a *aws, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { dbParameterGroups, err := a.awsr.GetDBParameterGroups(ctx, nil) @@ -174,21 +189,115 @@ func dbParameterGroups(ctx context.Context, a *aws, resourceType string, tags [] Last step is to re-generate the following files with enumer and build/install. - * aws/reader/reader.go - * aws/resourcetype_enumer.go + * `aws/reader/reader.go` + * `aws/resourcetype_enumer.go` -``` -make generate -make test +```shell +$ make generate +$ make test ``` 5. Update CHANGELOG Don't forget to update the `CHANGELOG.md` +##### AzureRM Middleware layer + +We have an `azurerm/cmd` that generates the `azurerm/reader_generated.go` methods used to get the resources from the Azure SDK. To add a new call you have to add a new Function to the list in `aws/cmd/generate.go` (and the corresponding AzureAPI if necessary) and run `make generate`, you'll have the code fully generated for that function. + +###### Example with azurerm_virtual_machine + +1. Add your function + +Functions are based on `https://github.com/Azure/azure-sdk-for-go/tree/master/services`. +For example with `azurerm_virtual_machine` you should be able to find the required information in https://github.com/Azure/azure-sdk-for-go/blob/master/services/compute/mgmt/2019-12-01/compute/virtualmachines.go +The API to use is the `compute` service with the version `2019-12-01`. +In our case we want to list data from the ResourceGroup used when executing `terracognita`, the corresponding function is `List`, sometimes another List function is needed as it's depends if it based on a ResourceGroup, a Location or will only list all resources without those delimiters. + + * API: SubDirectory azure-sdk-for-go services `compute` + * APIVersion: SubDirectory azure-sdk-for-go mgmt `2019-12-01` + * Resource: resource name in singular PascalCase `VirtualMachine` + * ResourceGroup: `true` as the List function require the resource group name as a parameter + +```shell +$ vim aws/cmd/generate.go +``` +```go +var azureAPIs = []AzureAPI{ + ... + AzureAPI{API: "compute", APIVersion: "2019-07-01"}, +} + +var functions = []Function{ + ... + Function{Resource: "VirtualMachine", API: "compute", ResourceGroup: true}, +} +``` + +Functions are used to generate List methods in `azurerm/reader_generated.go`. After a `make generate` execution, we should find a `ListVirtualMachines` method at the end of the file corresponding to our previous example. + +2. Add your resource type + +The naming is based on terraform resources like `azurerm_virtual_machine` but without the `azurerm` prefix and Snake case like `bla_foo` needs to be replaced by Camel case `blaFoo`. The function should start with a `lowercase` and end with a `s`. +The end result would be `virtualMachines`. + +```shell +$ vim azurerm/resources.go +``` +```go +const ( + ... + VirtualMachine ResourceType = iota +) + +... + +var ( + resources = map[ResourceType]rtFn{ + ... + VirtualMachine: virtualMachines, + } +) +``` + +The const is used to generate `azurerm/resourcetype_enumer.go`. + +3. Add the associated function to generate terraform codes. + +```go +func virtualMachines(ctx context.Context, a *azurerm, resourceType string, tags []tag.Tag) ([]provider.Resource, error) { + virtualMachines, err := a.azurer.ListVirtualMachines(ctx) + if err != nil { + return nil, errors.Wrap(err, "unable to list virtual machines from reader") + } + resources := make([]provider.Resource, 0) + for _, virtualMachine := range virtualMachines { + r := provider.NewResource(*virtualMachine.ID, resourceType, a) + resources = append(resources, r) + } + return resources, nil +} +``` + +4. Make generate + +Last step is to re-generate the following files with enumer and build/install. + + * `azurerm/reader_generated.go` + * `azurerm/resourcetype_enumer.go` + +``` +$ make generate +$ make test +``` + +5. Update CHANGELOG + +Don't forget to update the `CHANGELOG.md`. + ##### GCP Middleware layer -In `reader.go`, you can add your middleware function `ListInstances`. You will need to be equiped with this [documentation](https://godoc.org/google.golang.org/api/compute/v1). Google SDK is pretty standard, APIs are most of the time used in a similar way. +In `reader.go`, you can add your middleware function `ListInstances`. You will need to be equipped with this [documentation](https://godoc.org/google.golang.org/api/compute/v1). Google SDK is pretty standard, APIs are most of the time used in a similar way. You only need to find out if your component belongs to a `project` or a `project` and a `zone`. It's highly recommended to base your code on the other functions (a method to generate this function will be provided soon). #### Build and test your component From 1b8fb60f98bf82dcf2e33627a382187a6e50feec Mon Sep 17 00:00:00 2001 From: Steve Durrheimer Date: Tue, 24 Mar 2020 18:25:29 +0100 Subject: [PATCH 21/21] CHANGELOG: new AzureRM provider --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17a48230d0..e0ac65b37a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ ([PR #78](https://github.com/cycloidio/terracognita/pull/78)) - New flag `--target` to allow specific resource+id import ([Issue #40](https://github.com/cycloidio/terracognita/issues/40)) +- New AzureRM provider + ([PR #88](https://github.com/cycloidio/terracognita/pull/88)) ## [0.3.0] _2020-01-02_