github.com/GoogleCloudPlatform/terraformer@v0.8.18/cmd/plan.go (about) 1 // Copyright 2018 The Terraformer Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package cmd 15 16 import ( 17 "encoding/json" 18 "fmt" 19 "log" 20 "os" 21 "path/filepath" 22 23 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 24 "github.com/spf13/cobra" 25 ) 26 27 type ImportPlan struct { 28 Version string 29 Provider string 30 Options ImportOptions 31 Args []string 32 ImportedResource map[string][]terraformutils.Resource 33 } 34 35 func newPlanCmd() *cobra.Command { 36 options := ImportOptions{ 37 Plan: true, 38 } 39 cmd := &cobra.Command{ 40 Use: "plan", 41 Short: "Plan to import current state to Terraform configuration", 42 Long: "Plan to import current state to Terraform configuration", 43 SilenceUsage: true, 44 SilenceErrors: false, 45 //Version: version.String(), 46 } 47 48 for _, subcommand := range providerImporterSubcommands() { 49 cmd.AddCommand(subcommand(options)) 50 } 51 return cmd 52 } 53 54 func newCmdPlanImporter(options ImportOptions) *cobra.Command { 55 cmd := &cobra.Command{ 56 Use: "plan", 57 Short: "Import planned state to Terraform configuration", 58 Long: "Import planned state to Terraform configuration", 59 Args: cobra.ExactArgs(1), 60 RunE: func(cmd *cobra.Command, args []string) error { 61 plan, err := LoadPlanfile(args[0]) 62 if err != nil { 63 return err 64 } 65 66 var provider terraformutils.ProviderGenerator 67 if providerGen, ok := providerGenerators()[plan.Provider]; ok { 68 provider = providerGen() 69 } else { 70 return fmt.Errorf("unsupported provider: %s", plan.Provider) 71 } 72 73 if err = provider.Init(plan.Args); err != nil { 74 return err 75 } 76 77 for _, service := range plan.Options.Resources { 78 if err = provider.InitService(service, options.Verbose); err != nil { 79 return err 80 } 81 } 82 83 return ImportFromPlan(provider, plan) 84 }, 85 } 86 return cmd 87 } 88 89 func LoadPlanfile(path string) (*ImportPlan, error) { 90 f, err := os.Open(path) 91 if err != nil { 92 return nil, err 93 } 94 defer f.Close() 95 96 plan := &ImportPlan{} 97 dec := json.NewDecoder(f) 98 dec.DisallowUnknownFields() 99 if err := dec.Decode(plan); err != nil { 100 return nil, err 101 } 102 103 if plan.Version != version { 104 return nil, fmt.Errorf("planfile version did not match. expected: %s, actual: %s", version, plan.Version) 105 } 106 107 return plan, nil 108 } 109 110 func ExportPlanFile(plan *ImportPlan, path, filename string) error { 111 plan.Version = version 112 113 planfilePath := filepath.Join(path, filename) 114 log.Println("Saving planfile to", planfilePath) 115 116 if err := os.MkdirAll(path, os.ModePerm); err != nil { 117 return err 118 } 119 120 f, err := os.OpenFile(planfilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm) 121 if err != nil { 122 return err 123 } 124 defer f.Close() 125 126 enc := json.NewEncoder(f) 127 enc.SetIndent("", "\t") 128 return enc.Encode(plan) 129 }