From bef1bc27bfd66af339ccf25a9b0fefbefa00d8e9 Mon Sep 17 00:00:00 2001 From: Martin Petkov Date: Fri, 5 Feb 2021 14:08:54 -0500 Subject: [PATCH] Importer: Add resource_types flag (#779) * Support interactive correctly * Add --resources flag to tfimport * Switch to specific resource types * Remove leftover from branch * Fix custom type repr --- cmd/tfimport/main.go | 31 ++++++++++++++++++++++++++----- internal/tfimport/tfimport.go | 12 ++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/cmd/tfimport/main.go b/cmd/tfimport/main.go index e68271a81..692738d13 100644 --- a/cmd/tfimport/main.go +++ b/cmd/tfimport/main.go @@ -16,10 +16,11 @@ // Requires Terraform to be installed and for authentication to be configured for each provider in the Terraform configs provider blocks. // // Usage: -// $ go run . [--input_dir=/path/to/config] +// $ go run . [--input_dir=/path/to/config] [--resource_types 'google_storage_bucket.bucket' --resources 'google_resource_manager_lien.lien'] package main import ( + "encoding/json" "flag" "fmt" "log" @@ -29,6 +30,23 @@ import ( "github.com/GoogleCloudPlatform/healthcare-data-protection-suite/internal/tfimport" ) +// From https://stackoverflow.com/a/28323276 +type mapFlag map[string]bool + +func (i *mapFlag) String() string { + if b, err := json.Marshal(*i); err == nil { + return string(b) + } + return "" +} + +func (i *mapFlag) Set(value string) error { + (*i)[value] = true + return nil +} + +var resourcesFlag = make(mapFlag) + var ( inputDir = flag.String("input_dir", ".", "Path to the directory containing Terraform configs.") terraformPath = flag.String("terraform_path", "terraform", "Name or path to the terraform binary to use.") @@ -38,6 +56,8 @@ var ( ) func main() { + flag.Var(&resourcesFlag, "resource_types", "Specific resource types to import, specified as terraform resource names (e.g. 'google_storage_bucket', 'google_resource_manager_lien'). Leave empty to import all.") + if err := run(); err != nil { log.Fatal(err) } @@ -66,10 +86,11 @@ func run() error { } args := &tfimport.RunArgs{ - InputDir: *inputDir, - TerraformPath: *terraformPath, - DryRun: *dryRun, - Interactive: *interactive, + InputDir: *inputDir, + TerraformPath: *terraformPath, + DryRun: *dryRun, + Interactive: *interactive, + SpecificResourceTypes: resourcesFlag, } if err := tfimport.Run(rn, importRn, args); err != nil { diff --git a/internal/tfimport/tfimport.go b/internal/tfimport/tfimport.go index 4a54de916..7c380fb9f 100644 --- a/internal/tfimport/tfimport.go +++ b/internal/tfimport/tfimport.go @@ -522,6 +522,10 @@ type RunArgs struct { TerraformPath string DryRun bool Interactive bool + + // This is a "set" of resource types to import. + // If not nil and not empty, will import only resources which match it. + SpecificResourceTypes map[string]bool } // Run executes the main tfimport logic. @@ -614,6 +618,14 @@ func planAndImport(rn, importRn runner.Runner, runArgs *RunArgs) (retry bool, er log.Printf("Found importable resource: %q\n", ir.Change.Address) + // Check against specific resources list, if present. + if len(runArgs.SpecificResourceTypes) > 0 { + if _, ok := runArgs.SpecificResourceTypes[ir.Change.Kind]; !ok { + log.Printf("Skipping %v, not in list of specific resource types to import", ir.Change.Address) + continue + } + } + // Attempt the import. output, err := Import(importRn, ir, runArgs.InputDir, runArgs.TerraformPath, runArgs.Interactive)