diff --git a/internal/provider/program.go b/internal/provider/program.go index e3e07647..ff57ef72 100644 --- a/internal/provider/program.go +++ b/internal/provider/program.go @@ -28,6 +28,7 @@ type program struct { keepTmpDirOnError bool name string perms map[string]os.FileMode + providerData *schema.ResourceData removeDir bool } @@ -41,11 +42,12 @@ func init() { TempDirBase = fmt.Sprintf("%s/terraform-provider-external", dir) } -func Program(ctx context.Context, data *schema.ResourceData) *program { +func Program(ctx context.Context, data *schema.ResourceData, providerData *schema.ResourceData) *program { oldStateV, newStateV := data.GetChange("state") p := &program{ - context: ctx, - data: data, + context: ctx, + data: data, + providerData: providerData, } p.inputTmpDir = data.Get("program_tmpdir").(string) p.keepTmpDir = data.Get("program_tmpdir_keep").(bool) @@ -53,6 +55,7 @@ func Program(ctx context.Context, data *schema.ResourceData) *program { p.combinedOutput = data.Get("program_output_combined").(bool) p.files = map[string]string{ + "provider_input": p.providerData.Get("input").(string), "input": p.data.Get("input").(string), "input_sensitive": p.data.Get("input_sensitive").(string), "output": p.data.Get("output").(string), @@ -161,7 +164,7 @@ func (p *program) prepareEnv() (env []string, diags diag.Diagnostics) { } var files []string - for name, _ := range p.files { + for name := range p.files { files = append(files, name) } env = append(env, fmt.Sprintf("%s=%s", "TF_EXTERNAL_MANAGED_FILES", strings.Join(files, ":"))) @@ -226,12 +229,11 @@ func (p *program) executeCommand(key string) (diags diag.Diagnostics) { cmd.Stdout = stdout cmd.Stderr = stderr } - err := cmd.Start() if err != nil { diags = append(diags, diag.Diagnostic{ Severity: diag.Error, - Summary: fmt.Sprintf("Error when starting program %s", p.name), + Summary: fmt.Sprintf("Error when starting program %s in %s", p.name, p.currentTmpDir), Detail: fmt.Sprintf("ERROR=%v\nCOMMAND:\n%s", err.Error(), cmdRepr), }) return @@ -277,12 +279,12 @@ func (p *program) executeCommand(key string) (diags diag.Diagnostics) { diags = append(diags, diag.Diagnostic{ Severity: diag.Warning, Summary: fmt.Sprintf("Combined output (%d bytes) of %s:\n%s", outputLength, p.name, cmdRepr), - Detail: outputRepr, + Detail: outputRepr, // }) if err != nil { diags = append(diags, diag.Diagnostic{ Severity: diag.Error, - Summary: fmt.Sprintf("Error when running %s: %v", p.name, err.Error()), + Summary: fmt.Sprintf("Error when running %s in %s: %v", p.name, p.currentTmpDir, err.Error()), Detail: fmt.Sprintf("%s\nOUTPUT (%d bytes):\n%s", cmdRepr, outputLength, outputRepr), }) } @@ -347,33 +349,6 @@ func (p *program) closeDir(hadError bool) (diags diag.Diagnostics) { return } -func runProgram(ctx context.Context, data *schema.ResourceData, name string, commandKey string) (diags diag.Diagnostics) { - p := Program(ctx, data) - p.name = name - diags = append(diags, p.openDir()...) - if diags.HasError() { - return - } - defer func() { diags = append(diags, p.closeDir(diags.HasError())...) }() - - diags = append(diags, p.executeCommand(commandKey)...) - if diags.HasError() { - return - } - - diags = append(diags, p.storeId()...) - if diags.HasError() { - return - } - - diags = append(diags, p.storeAttributes("state", "output", "output_sensitive")...) - if diags.HasError() { - return - } - - return -} - func (p *program) readFile(name string) (text string, diags diag.Diagnostics) { fullPath := path.Join(p.currentTmpDir, name) info, err := os.Stat(fullPath) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5187b901..a2a79feb 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1,11 +1,26 @@ package provider import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func New() *schema.Provider { return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "input": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + Default: "", + Description: "Pass this attribute as additional input to resources (eg. as short-term credentials).", + }, + }, + ConfigureContextFunc: func(ctx context.Context, data *schema.ResourceData) (meta interface{}, diags diag.Diagnostics) { + meta = data + return + }, DataSourcesMap: map[string]*schema.Resource{ "external": dataSource(), }, diff --git a/internal/provider/resource.go b/internal/provider/resource.go index 76b694d1..cdcceb44 100644 --- a/internal/provider/resource.go +++ b/internal/provider/resource.go @@ -99,7 +99,7 @@ func resourceExternal() *schema.Resource { } func resourceExternalCreate(ctx context.Context, data *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) { - p := Program(ctx, data) + p := Program(ctx, data, meta.(*schema.ResourceData)) p.name = "create" diags = append(diags, p.openDir()...) defer func() { diags = append(diags, p.closeDir(diags.HasError())...) }() @@ -131,7 +131,7 @@ func resourceExternalCreate(ctx context.Context, data *schema.ResourceData, meta } func resourceExternalRead(ctx context.Context, data *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) { - p := Program(ctx, data) + p := Program(ctx, data, meta.(*schema.ResourceData)) p.name = "read" diags = append(diags, p.openDir()...) defer func() { diags = append(diags, p.closeDir(diags.HasError())...) }() @@ -157,9 +157,8 @@ func resourceExternalRead(ctx context.Context, data *schema.ResourceData, meta i } func resourceExternalUpdate(ctx context.Context, data *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) { - p := Program(ctx, data) - name := "update" - p.name = name + p := Program(ctx, data, meta.(*schema.ResourceData)) + p.name = "update" diags = append(diags, p.openDir()...) defer func() { diags = append(diags, p.closeDir(diags.HasError())...) }() if diags.HasError() { @@ -184,7 +183,29 @@ func resourceExternalUpdate(ctx context.Context, data *schema.ResourceData, meta } func resourceExternalDelete(ctx context.Context, data *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) { - diags = append(diags, runProgram(ctx, data, "delete", "program_delete")...) + providerData := meta.(*schema.ResourceData) + p := Program(ctx, data, providerData) + p.name = "delete" + diags = append(diags, p.openDir()...) + if diags.HasError() { + return + } + defer func() { diags = append(diags, p.closeDir(diags.HasError())...) }() + + diags = append(diags, p.executeCommand("program_delete")...) + if diags.HasError() { + return + } + + diags = append(diags, p.storeId()...) + if diags.HasError() { + return + } + + diags = append(diags, p.storeAttributes("state", "output", "output_sensitive")...) + if diags.HasError() { + return + } data.SetId("") return