2015-02-06 22:31:59 +01:00
package main
import (
2017-06-09 21:25:34 +02:00
"bytes"
2015-02-06 22:31:59 +01:00
"flag"
"fmt"
"os"
2017-06-09 21:25:34 +02:00
"os/exec"
2015-02-06 22:31:59 +01:00
"path/filepath"
2017-10-20 17:32:34 +02:00
"github.com/adammck/venv"
"github.com/blang/vfs"
2015-02-06 22:31:59 +01:00
)
2015-02-09 22:14:55 +01:00
var version = flag . Bool ( "version" , false , "print version information and exit" )
2015-02-06 22:31:59 +01:00
var list = flag . Bool ( "list" , false , "list mode" )
var host = flag . String ( "host" , "" , "host mode" )
2016-02-24 13:03:36 +01:00
var inventory = flag . Bool ( "inventory" , false , "inventory mode" )
2015-02-06 22:31:59 +01:00
func main ( ) {
flag . Parse ( )
file := flag . Arg ( 0 )
2015-02-09 22:14:55 +01:00
if * version == true {
2015-06-05 04:43:56 +02:00
fmt . Printf ( "%s version %s\n" , os . Args [ 0 ] , versionInfo ( ) )
2015-02-09 22:14:55 +01:00
return
}
2017-06-09 21:25:34 +02:00
fs := vfs . OS ( )
2015-06-05 06:17:23 +02:00
if file == "" {
2017-06-09 21:25:34 +02:00
2016-08-19 04:15:55 +02:00
env := venv . OS ( )
file = GetInputPath ( fs , env )
2015-06-05 06:22:08 +02:00
}
2016-02-24 13:03:36 +01:00
if ! * list && * host == "" && ! * inventory {
2015-06-05 06:17:23 +02:00
fmt . Fprint ( os . Stderr , "Either --host or --list must be specified" )
2015-02-06 22:31:59 +01:00
os . Exit ( 1 )
}
path , err := filepath . Abs ( file )
if err != nil {
2015-06-05 06:17:23 +02:00
fmt . Fprintf ( os . Stderr , "Invalid file: %s\n" , err )
2015-02-06 22:31:59 +01:00
os . Exit ( 1 )
}
2017-06-09 21:25:34 +02:00
f , err := fs . Stat ( path )
2015-02-06 22:31:59 +01:00
if err != nil {
2017-06-09 21:25:34 +02:00
fmt . Fprintf ( os . Stderr , "Invalid file: %s\n" , err )
2015-02-06 22:31:59 +01:00
os . Exit ( 1 )
}
2019-08-01 17:21:54 +02:00
var s stateAnyTerraformVersion
2017-06-09 21:25:34 +02:00
if ! f . IsDir ( ) {
stateFile , err := os . Open ( path )
defer stateFile . Close ( )
if err != nil {
fmt . Fprintf ( os . Stderr , "Error opening tfstate file: %s\n" , err )
os . Exit ( 1 )
}
err = s . read ( stateFile )
if err != nil {
fmt . Fprintf ( os . Stderr , "Error reading tfstate file: %s\n" , err )
os . Exit ( 1 )
}
}
if f . IsDir ( ) {
2019-08-01 17:21:54 +02:00
cmd := exec . Command ( "terraform" , "show" , "-json" )
2017-06-09 21:25:34 +02:00
cmd . Dir = path
var out bytes . Buffer
cmd . Stdout = & out
err = cmd . Run ( )
if err != nil {
2019-08-01 17:21:54 +02:00
fmt . Fprintf ( os . Stderr , "Error running `terraform show -json` in directory %s, %s, falling back to trying Terraform pre-0.12 command\n" , path , err )
cmd = exec . Command ( "terraform" , "state" , "pull" )
cmd . Dir = path
out . Reset ( )
cmd . Stdout = & out
err = cmd . Run ( )
if err != nil {
fmt . Fprintf ( os . Stderr , "Error running `terraform state pull` in directory %s, %s\n" , path , err )
os . Exit ( 1 )
}
2017-06-09 21:25:34 +02:00
}
err = s . read ( & out )
if err != nil {
2019-08-01 17:21:54 +02:00
fmt . Fprintf ( os . Stderr , "Error reading Terraform state: %s\n" , err )
2017-06-09 21:25:34 +02:00
os . Exit ( 1 )
}
2019-08-01 17:21:54 +02:00
}
2017-06-09 21:25:34 +02:00
2019-08-01 17:21:54 +02:00
if s . TerraformVersion == TerraformVersionUnknown {
fmt . Fprintf ( os . Stderr , "Unknown state format\n\nUsage: %s [options] path\npath: this is either a path to a state file or a folder from which `terraform commands` are valid\n" , os . Args [ 0 ] )
os . Exit ( 1 )
2017-06-09 21:25:34 +02:00
}
2019-08-01 17:21:54 +02:00
if ( s . TerraformVersion == TerraformVersionPre0dot12 && s . StatePre0dot12 . Modules == nil ) ||
( s . TerraformVersion == TerraformVersion0dot12 && s . State0dot12 . Values . RootModule == nil ) {
fmt . Fprintf ( os . Stderr , "No modules found in state\n\nUsage: %s [options] path\npath: this is either a path to a state file or a folder from which `terraform commands` are valid\n" , os . Args [ 0 ] )
2015-02-06 22:31:59 +01:00
os . Exit ( 1 )
}
if * list {
os . Exit ( cmdList ( os . Stdout , os . Stderr , & s ) )
2016-02-24 13:03:36 +01:00
} else if * inventory {
os . Exit ( cmdInventory ( os . Stdout , os . Stderr , & s ) )
2015-02-06 22:31:59 +01:00
} else if * host != "" {
os . Exit ( cmdHost ( os . Stdout , os . Stderr , & s , * host ) )
}
}