Exemplo n.º 1
0
func (c *BuildCommand) Execute(args []string) error {
	sysConfig := BuiltinConfig
	sysConfig.Discover()

	config, err := padstone.LoadConfig(c.Args.ConfigDir)
	if err != nil {
		return err
	}

	storage := &tfmodcfg.FolderStorage{
		StorageDir: ".padstone",
	}

	// The state file must not already exist, since we don't to
	// accidentally clobber the record of resources created in an
	// earlier build.
	_, err = os.Lstat(c.Args.StateFile)
	if err == nil {
		return fmt.Errorf("state file %s already exists; specify a different name or destroy it with 'padstone destroy' before generating a new set of resources", c.Args.StateFile)
	}

	state := terraform.NewState()

	uiHook := &UIHook{
		ui:      c.ui,
		verbose: c.Verbose,
	}
	stateHook := &StateHook{
		OutputFilename: c.Args.StateFile,
	}

	variables, err := decodeKVSpecs(c.Args.VarSpecs)
	if err != nil {
		return err
	}

	ctx := &padstone.Context{
		Config:        config,
		State:         state,
		Providers:     sysConfig.ProviderFactories(),
		Provisioners:  sysConfig.ProvisionerFactories(),
		Variables:     variables,
		Hooks:         []terraform.Hook{stateHook, uiHook},
		UIInput:       c.ui,
		ModuleStorage: storage,
	}

	warns, errs := ctx.Validate()
	for _, warning := range warns {
		c.ui.Warn(warning)
	}
	if len(errs) > 0 {
		for _, err := range errs {
			c.ui.Error(err.Error())
		}
		return fmt.Errorf("aborted due to configuration errors.")
	}

	err = ctx.Build()
	if err != nil {
		return err
	}

	c.ui.Info("--- Build succeeded! Now destroying temporary resources... ---")

	err = ctx.CleanUp()
	if err != nil {
		return err
	}

	_, err = stateHook.PostStateUpdate(ctx.ResultState)
	if err != nil {
		return err
	}

	outputs := ctx.ResultState.Modules[0].Outputs
	if len(outputs) > 0 {
		c.ui.Output("\nOutputs:")
		for k, v := range outputs {
			c.ui.Output(fmt.Sprintf("- %v = %v", k, v))
		}
		c.ui.Output("")
	}

	return nil
}
Exemplo n.º 2
0
func (c *DestroyCommand) Execute(args []string) error {
	sysConfig := BuiltinConfig
	sysConfig.Discover()

	config, err := padstone.LoadConfig(c.Args.ConfigDir)
	if err != nil {
		return err
	}

	storage := &tfmodcfg.FolderStorage{
		StorageDir: ".padstone",
	}

	stateFile, err := os.Open(c.Args.StateFile)
	if err != nil {
		return fmt.Errorf("error opening state file %s: %s", c.Args.StateFile, err)
	}

	state, err := terraform.ReadState(stateFile)
	if err != nil {
		return fmt.Errorf("error reading state file %s: %s", c.Args.StateFile, err)
	}

	uiHook := &UIHook{
		ui:      c.ui,
		verbose: c.Verbose,
	}
	stateHook := &StateHook{
		OutputFilename: c.Args.StateFile,
	}

	variables, err := decodeKVSpecs(c.Args.VarSpecs)
	if err != nil {
		return err
	}

	ctx := &padstone.Context{
		Config:        config,
		State:         state,
		Providers:     sysConfig.ProviderFactories(),
		Provisioners:  sysConfig.ProvisionerFactories(),
		Variables:     variables,
		Hooks:         []terraform.Hook{stateHook, uiHook},
		UIInput:       c.ui,
		ModuleStorage: storage,
	}

	warns, errs := ctx.Validate()
	for _, warning := range warns {
		c.ui.Warn(warning)
	}
	if len(errs) > 0 {
		for _, err := range errs {
			c.ui.Error(err.Error())
		}
		return fmt.Errorf("aborted due to configuration errors.")
	}

	err = ctx.Destroy()
	if err != nil {
		return err
	}

	rootState := ctx.State.RootModule()
	moduleCount := len(ctx.State.Modules)

	if moduleCount == 1 && len(rootState.Resources) == 0 {
		c.ui.Info("All resources destroyed")
		err := os.Remove(c.Args.StateFile)
		if err != nil {
			return fmt.Errorf("Failed to remove state file %s: %s", c.Args.StateFile, err)
		}
	} else {
		c.ui.Warn(fmt.Sprintf("Not all resources were destroyed. State file %s updated to reflect remaining resources.", c.Args.StateFile))
		_, err = stateHook.PostStateUpdate(ctx.State)
		if err != nil {
			return err
		}
	}

	return nil
}