github.com/spirius/terraform@v0.10.0-beta2.0.20170714185654-87b2c0cf8fea/command/internal_plugin.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/terraform/plugin"
     9  	"github.com/kardianos/osext"
    10  )
    11  
    12  // InternalPluginCommand is a Command implementation that allows plugins to be
    13  // compiled into the main Terraform binary and executed via a subcommand.
    14  type InternalPluginCommand struct {
    15  	Meta
    16  }
    17  
    18  const TFSPACE = "-TFSPACE-"
    19  
    20  // BuildPluginCommandString builds a special string for executing internal
    21  // plugins. It has the following format:
    22  //
    23  // 	/path/to/terraform-TFSPACE-internal-plugin-TFSPACE-terraform-provider-aws
    24  //
    25  // We split the string on -TFSPACE- to build the command executor. The reason we
    26  // use -TFSPACE- is so we can support spaces in the /path/to/terraform part.
    27  func BuildPluginCommandString(pluginType, pluginName string) (string, error) {
    28  	terraformPath, err := osext.Executable()
    29  	if err != nil {
    30  		return "", err
    31  	}
    32  	parts := []string{terraformPath, "internal-plugin", pluginType, pluginName}
    33  	return strings.Join(parts, TFSPACE), nil
    34  }
    35  
    36  func (c *InternalPluginCommand) Run(args []string) int {
    37  	if len(args) != 2 {
    38  		log.Printf("Wrong number of args; expected: terraform internal-plugin pluginType pluginName")
    39  		return 1
    40  	}
    41  
    42  	pluginType := args[0]
    43  	pluginName := args[1]
    44  
    45  	log.SetPrefix(fmt.Sprintf("%s-%s (internal) ", pluginName, pluginType))
    46  
    47  	switch pluginType {
    48  	case "provider":
    49  		pluginFunc, found := InternalProviders[pluginName]
    50  		if !found {
    51  			log.Printf("[ERROR] Could not load provider: %s", pluginName)
    52  			return 1
    53  		}
    54  		log.Printf("[INFO] Starting provider plugin %s", pluginName)
    55  		plugin.Serve(&plugin.ServeOpts{
    56  			ProviderFunc: pluginFunc,
    57  		})
    58  	case "provisioner":
    59  		pluginFunc, found := InternalProvisioners[pluginName]
    60  		if !found {
    61  			log.Printf("[ERROR] Could not load provisioner: %s", pluginName)
    62  			return 1
    63  		}
    64  		log.Printf("[INFO] Starting provisioner plugin %s", pluginName)
    65  		plugin.Serve(&plugin.ServeOpts{
    66  			ProvisionerFunc: pluginFunc,
    67  		})
    68  	default:
    69  		log.Printf("[ERROR] Invalid plugin type %s", pluginType)
    70  		return 1
    71  	}
    72  
    73  	return 0
    74  }
    75  
    76  func (c *InternalPluginCommand) Help() string {
    77  	helpText := `
    78  Usage: terraform internal-plugin pluginType pluginName
    79  
    80    Runs an internally-compiled version of a plugin from the terraform binary.
    81  
    82    NOTE: this is an internal command and you should not call it yourself.
    83  `
    84  
    85  	return strings.TrimSpace(helpText)
    86  }
    87  
    88  func (c *InternalPluginCommand) Synopsis() string {
    89  	return "internal plugin command"
    90  }