github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/commands.go (about)

     1  package main
     2  
     3  import (
     4  	"os"
     5  	"os/signal"
     6  
     7  	"github.com/mitchellh/cli"
     8  
     9  	"github.com/hashicorp/go-plugin"
    10  	svchost "github.com/hashicorp/terraform-svchost"
    11  	"github.com/hashicorp/terraform-svchost/auth"
    12  	"github.com/hashicorp/terraform-svchost/disco"
    13  	"github.com/muratcelep/terraform/not-internal/addrs"
    14  	"github.com/muratcelep/terraform/not-internal/command"
    15  	"github.com/muratcelep/terraform/not-internal/command/cliconfig"
    16  	"github.com/muratcelep/terraform/not-internal/command/views"
    17  	"github.com/muratcelep/terraform/not-internal/command/webbrowser"
    18  	"github.com/muratcelep/terraform/not-internal/getproviders"
    19  	pluginDiscovery "github.com/muratcelep/terraform/not-internal/plugin/discovery"
    20  	"github.com/muratcelep/terraform/not-internal/terminal"
    21  )
    22  
    23  // runningInAutomationEnvName gives the name of an environment variable that
    24  // can be set to any non-empty value in order to suppress certain messages
    25  // that assume that Terraform is being run from a command prompt.
    26  const runningInAutomationEnvName = "TF_IN_AUTOMATION"
    27  
    28  // Commands is the mapping of all the available Terraform commands.
    29  var Commands map[string]cli.CommandFactory
    30  
    31  // PrimaryCommands is an ordered sequence of the top-level commands (not
    32  // subcommands) that we emphasize at the top of our help output. This is
    33  // ordered so that we can show them in the typical workflow order, rather
    34  // than in alphabetical order. Anything not in this sequence or in the
    35  // HiddenCommands set appears under "all other commands".
    36  var PrimaryCommands []string
    37  
    38  // HiddenCommands is a set of top-level commands (not subcommands) that are
    39  // not advertised in the top-level help at all. This is typically because
    40  // they are either just stubs that return an error message about something
    41  // no longer being supported or backward-compatibility aliases for other
    42  // commands.
    43  //
    44  // No commands in the PrimaryCommands sequence should also appear in the
    45  // HiddenCommands set, because that would be rather silly.
    46  var HiddenCommands map[string]struct{}
    47  
    48  // Ui is the cli.Ui used for communicating to the outside world.
    49  var Ui cli.Ui
    50  
    51  func initCommands(
    52  	originalWorkingDir string,
    53  	streams *terminal.Streams,
    54  	config *cliconfig.Config,
    55  	services *disco.Disco,
    56  	providerSrc getproviders.Source,
    57  	providerDevOverrides map[addrs.Provider]getproviders.PackageLocalDir,
    58  	unmanagedProviders map[addrs.Provider]*plugin.ReattachConfig,
    59  ) {
    60  	var inAutomation bool
    61  	if v := os.Getenv(runningInAutomationEnvName); v != "" {
    62  		inAutomation = true
    63  	}
    64  
    65  	for userHost, hostConfig := range config.Hosts {
    66  		host, err := svchost.ForComparison(userHost)
    67  		if err != nil {
    68  			// We expect the config was already validated by the time we get
    69  			// here, so we'll just ignore invalid hostnames.
    70  			continue
    71  		}
    72  		services.ForceHostServices(host, hostConfig.Services)
    73  	}
    74  
    75  	configDir, err := cliconfig.ConfigDir()
    76  	if err != nil {
    77  		configDir = "" // No config dir available (e.g. looking up a home directory failed)
    78  	}
    79  
    80  	wd := WorkingDir(originalWorkingDir, os.Getenv("TF_DATA_DIR"))
    81  
    82  	meta := command.Meta{
    83  		WorkingDir: wd,
    84  		Streams:    streams,
    85  		View:       views.NewView(streams).SetRunningInAutomation(inAutomation),
    86  
    87  		Color:            true,
    88  		GlobalPluginDirs: globalPluginDirs(),
    89  		Ui:               Ui,
    90  
    91  		Services:        services,
    92  		BrowserLauncher: webbrowser.NewNativeLauncher(),
    93  
    94  		RunningInAutomation: inAutomation,
    95  		CLIConfigDir:        configDir,
    96  		PluginCacheDir:      config.PluginCacheDir,
    97  
    98  		ShutdownCh: makeShutdownCh(),
    99  
   100  		ProviderSource:       providerSrc,
   101  		ProviderDevOverrides: providerDevOverrides,
   102  		UnmanagedProviders:   unmanagedProviders,
   103  	}
   104  
   105  	// The command list is included in the terraform -help
   106  	// output, which is in turn included in the docs at
   107  	// website/docs/cli/commands/index.html.markdown; if you
   108  	// add, remove or reclassify commands then consider updating
   109  	// that to match.
   110  
   111  	Commands = map[string]cli.CommandFactory{
   112  		"apply": func() (cli.Command, error) {
   113  			return &command.ApplyCommand{
   114  				Meta: meta,
   115  			}, nil
   116  		},
   117  
   118  		"console": func() (cli.Command, error) {
   119  			return &command.ConsoleCommand{
   120  				Meta: meta,
   121  			}, nil
   122  		},
   123  
   124  		"destroy": func() (cli.Command, error) {
   125  			return &command.ApplyCommand{
   126  				Meta:    meta,
   127  				Destroy: true,
   128  			}, nil
   129  		},
   130  
   131  		"env": func() (cli.Command, error) {
   132  			return &command.WorkspaceCommand{
   133  				Meta:       meta,
   134  				LegacyName: true,
   135  			}, nil
   136  		},
   137  
   138  		"env list": func() (cli.Command, error) {
   139  			return &command.WorkspaceListCommand{
   140  				Meta:       meta,
   141  				LegacyName: true,
   142  			}, nil
   143  		},
   144  
   145  		"env select": func() (cli.Command, error) {
   146  			return &command.WorkspaceSelectCommand{
   147  				Meta:       meta,
   148  				LegacyName: true,
   149  			}, nil
   150  		},
   151  
   152  		"env new": func() (cli.Command, error) {
   153  			return &command.WorkspaceNewCommand{
   154  				Meta:       meta,
   155  				LegacyName: true,
   156  			}, nil
   157  		},
   158  
   159  		"env delete": func() (cli.Command, error) {
   160  			return &command.WorkspaceDeleteCommand{
   161  				Meta:       meta,
   162  				LegacyName: true,
   163  			}, nil
   164  		},
   165  
   166  		"fmt": func() (cli.Command, error) {
   167  			return &command.FmtCommand{
   168  				Meta: meta,
   169  			}, nil
   170  		},
   171  
   172  		"get": func() (cli.Command, error) {
   173  			return &command.GetCommand{
   174  				Meta: meta,
   175  			}, nil
   176  		},
   177  
   178  		"graph": func() (cli.Command, error) {
   179  			return &command.GraphCommand{
   180  				Meta: meta,
   181  			}, nil
   182  		},
   183  
   184  		"import": func() (cli.Command, error) {
   185  			return &command.ImportCommand{
   186  				Meta: meta,
   187  			}, nil
   188  		},
   189  
   190  		"init": func() (cli.Command, error) {
   191  			return &command.InitCommand{
   192  				Meta: meta,
   193  			}, nil
   194  		},
   195  
   196  		"login": func() (cli.Command, error) {
   197  			return &command.LoginCommand{
   198  				Meta: meta,
   199  			}, nil
   200  		},
   201  
   202  		"logout": func() (cli.Command, error) {
   203  			return &command.LogoutCommand{
   204  				Meta: meta,
   205  			}, nil
   206  		},
   207  
   208  		"output": func() (cli.Command, error) {
   209  			return &command.OutputCommand{
   210  				Meta: meta,
   211  			}, nil
   212  		},
   213  
   214  		"plan": func() (cli.Command, error) {
   215  			return &command.PlanCommand{
   216  				Meta: meta,
   217  			}, nil
   218  		},
   219  
   220  		"providers": func() (cli.Command, error) {
   221  			return &command.ProvidersCommand{
   222  				Meta: meta,
   223  			}, nil
   224  		},
   225  
   226  		"providers lock": func() (cli.Command, error) {
   227  			return &command.ProvidersLockCommand{
   228  				Meta: meta,
   229  			}, nil
   230  		},
   231  
   232  		"providers mirror": func() (cli.Command, error) {
   233  			return &command.ProvidersMirrorCommand{
   234  				Meta: meta,
   235  			}, nil
   236  		},
   237  
   238  		"providers schema": func() (cli.Command, error) {
   239  			return &command.ProvidersSchemaCommand{
   240  				Meta: meta,
   241  			}, nil
   242  		},
   243  
   244  		"push": func() (cli.Command, error) {
   245  			return &command.PushCommand{
   246  				Meta: meta,
   247  			}, nil
   248  		},
   249  
   250  		"refresh": func() (cli.Command, error) {
   251  			return &command.RefreshCommand{
   252  				Meta: meta,
   253  			}, nil
   254  		},
   255  
   256  		"show": func() (cli.Command, error) {
   257  			return &command.ShowCommand{
   258  				Meta: meta,
   259  			}, nil
   260  		},
   261  
   262  		"taint": func() (cli.Command, error) {
   263  			return &command.TaintCommand{
   264  				Meta: meta,
   265  			}, nil
   266  		},
   267  
   268  		"test": func() (cli.Command, error) {
   269  			return &command.TestCommand{
   270  				Meta: meta,
   271  			}, nil
   272  		},
   273  
   274  		"validate": func() (cli.Command, error) {
   275  			return &command.ValidateCommand{
   276  				Meta: meta,
   277  			}, nil
   278  		},
   279  
   280  		"version": func() (cli.Command, error) {
   281  			return &command.VersionCommand{
   282  				Meta:              meta,
   283  				Version:           Version,
   284  				VersionPrerelease: VersionPrerelease,
   285  				Platform:          getproviders.CurrentPlatform,
   286  				CheckFunc:         commandVersionCheck,
   287  			}, nil
   288  		},
   289  
   290  		"untaint": func() (cli.Command, error) {
   291  			return &command.UntaintCommand{
   292  				Meta: meta,
   293  			}, nil
   294  		},
   295  
   296  		"workspace": func() (cli.Command, error) {
   297  			return &command.WorkspaceCommand{
   298  				Meta: meta,
   299  			}, nil
   300  		},
   301  
   302  		"workspace list": func() (cli.Command, error) {
   303  			return &command.WorkspaceListCommand{
   304  				Meta: meta,
   305  			}, nil
   306  		},
   307  
   308  		"workspace select": func() (cli.Command, error) {
   309  			return &command.WorkspaceSelectCommand{
   310  				Meta: meta,
   311  			}, nil
   312  		},
   313  
   314  		"workspace show": func() (cli.Command, error) {
   315  			return &command.WorkspaceShowCommand{
   316  				Meta: meta,
   317  			}, nil
   318  		},
   319  
   320  		"workspace new": func() (cli.Command, error) {
   321  			return &command.WorkspaceNewCommand{
   322  				Meta: meta,
   323  			}, nil
   324  		},
   325  
   326  		"workspace delete": func() (cli.Command, error) {
   327  			return &command.WorkspaceDeleteCommand{
   328  				Meta: meta,
   329  			}, nil
   330  		},
   331  
   332  		//-----------------------------------------------------------
   333  		// Plumbing
   334  		//-----------------------------------------------------------
   335  
   336  		"force-unlock": func() (cli.Command, error) {
   337  			return &command.UnlockCommand{
   338  				Meta: meta,
   339  			}, nil
   340  		},
   341  
   342  		"state": func() (cli.Command, error) {
   343  			return &command.StateCommand{}, nil
   344  		},
   345  
   346  		"state list": func() (cli.Command, error) {
   347  			return &command.StateListCommand{
   348  				Meta: meta,
   349  			}, nil
   350  		},
   351  
   352  		"state rm": func() (cli.Command, error) {
   353  			return &command.StateRmCommand{
   354  				StateMeta: command.StateMeta{
   355  					Meta: meta,
   356  				},
   357  			}, nil
   358  		},
   359  
   360  		"state mv": func() (cli.Command, error) {
   361  			return &command.StateMvCommand{
   362  				StateMeta: command.StateMeta{
   363  					Meta: meta,
   364  				},
   365  			}, nil
   366  		},
   367  
   368  		"state pull": func() (cli.Command, error) {
   369  			return &command.StatePullCommand{
   370  				Meta: meta,
   371  			}, nil
   372  		},
   373  
   374  		"state push": func() (cli.Command, error) {
   375  			return &command.StatePushCommand{
   376  				Meta: meta,
   377  			}, nil
   378  		},
   379  
   380  		"state show": func() (cli.Command, error) {
   381  			return &command.StateShowCommand{
   382  				Meta: meta,
   383  			}, nil
   384  		},
   385  
   386  		"state replace-provider": func() (cli.Command, error) {
   387  			return &command.StateReplaceProviderCommand{
   388  				StateMeta: command.StateMeta{
   389  					Meta: meta,
   390  				},
   391  			}, nil
   392  		},
   393  	}
   394  
   395  	PrimaryCommands = []string{
   396  		"init",
   397  		"validate",
   398  		"plan",
   399  		"apply",
   400  		"destroy",
   401  	}
   402  
   403  	HiddenCommands = map[string]struct{}{
   404  		"env":             struct{}{},
   405  		"not-internal-plugin": struct{}{},
   406  		"push":            struct{}{},
   407  	}
   408  
   409  }
   410  
   411  // makeShutdownCh creates an interrupt listener and returns a channel.
   412  // A message will be sent on the channel for every interrupt received.
   413  func makeShutdownCh() <-chan struct{} {
   414  	resultCh := make(chan struct{})
   415  
   416  	signalCh := make(chan os.Signal, 4)
   417  	signal.Notify(signalCh, ignoreSignals...)
   418  	signal.Notify(signalCh, forwardSignals...)
   419  	go func() {
   420  		for {
   421  			<-signalCh
   422  			resultCh <- struct{}{}
   423  		}
   424  	}()
   425  
   426  	return resultCh
   427  }
   428  
   429  func credentialsSource(config *cliconfig.Config) (auth.CredentialsSource, error) {
   430  	helperPlugins := pluginDiscovery.FindPlugins("credentials", globalPluginDirs())
   431  	return config.CredentialsSource(helperPlugins)
   432  }