diff --git a/internal/provider/data_source_remotefile.go b/internal/provider/data_source_remotefile.go index f9167cc..6abdff1 100644 --- a/internal/provider/data_source_remotefile.go +++ b/internal/provider/data_source_remotefile.go @@ -23,6 +23,7 @@ func dataSourceRemotefile() *schema.Resource { "host": { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "The target host.", }, "port": { @@ -65,6 +66,7 @@ func dataSourceRemotefile() *schema.Resource { "path": { Description: "Path to file on remote host.", Type: schema.TypeString, + ForceNew: true, Required: true, }, }, diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 7a15622..127b481 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -133,7 +133,7 @@ func (c *apiClient) writeFileSudo(d *schema.ResourceData) error { stdin.Close() }() - cmd := fmt.Sprint("cat /dev/stdin | sudo tee ", d.Get("path").(string)) + cmd := fmt.Sprintf("cat /dev/stdin | sudo tee %s", d.Get("path").(string)) return session.Run(cmd) } @@ -177,6 +177,38 @@ func (c *apiClient) readFile(d *schema.ResourceData) error { return nil } +func (c *apiClient) fileExistsSudo(d *schema.ResourceData) (bool, error) { + sshClient, err := c.getSSHClient() + if err != nil { + return false, err + } + + session, err := sshClient.NewSession() + if err != nil { + return false, err + } + defer session.Close() + + path := d.Get("path").(string) + cmd := fmt.Sprintf("test -f %s", path) + err = session.Run(cmd) + + if err != nil { + session2, err := sshClient.NewSession() + if err != nil { + return false, err + } + defer session2.Close() + + cmd := fmt.Sprintf("test ! -f %s", path) + err = session2.Run(cmd) + + return err == nil, err + } + + return true, nil +} + func (c *apiClient) readFileSudo(d *schema.ResourceData) error { sshClient, err := c.getSSHClient() if err != nil { @@ -189,7 +221,7 @@ func (c *apiClient) readFileSudo(d *schema.ResourceData) error { } defer session.Close() - cmd := fmt.Sprint("sudo cat ", d.Get("path").(string)) + cmd := fmt.Sprintf("sudo cat %s", d.Get("path").(string)) content, err := session.Output(cmd) if err != nil { return err @@ -221,7 +253,7 @@ func (c *apiClient) deleteFileSudo(d *schema.ResourceData) error { } defer session.Close() - cmd := fmt.Sprint("sudo cat ", d.Get("path").(string)) + cmd := fmt.Sprintf("sudo cat %s", d.Get("path").(string)) return session.Run(cmd) } diff --git a/internal/provider/resource_remotefile.go b/internal/provider/resource_remotefile.go index 09e6555..07d7dd7 100644 --- a/internal/provider/resource_remotefile.go +++ b/internal/provider/resource_remotefile.go @@ -27,6 +27,7 @@ func resourceRemotefile() *schema.Resource { "host": { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "The target host.", }, "port": { @@ -69,16 +70,19 @@ func resourceRemotefile() *schema.Resource { "path": { Description: "Path to file on remote host.", Type: schema.TypeString, + ForceNew: true, Required: true, }, "content": { Description: "Content of file.", Type: schema.TypeString, + ForceNew: true, Required: true, }, "permissions": { Description: "Permissions of file.", Type: schema.TypeString, + ForceNew: true, Default: "0644", Optional: true, }, @@ -124,14 +128,22 @@ func resourceRemotefileRead(ctx context.Context, d *schema.ResourceData, meta in sudo, ok := d.GetOk("conn.0.sudo") if ok && sudo.(bool) { - err := client.readFileSudo(d) + exists, err := client.fileExistsSudo(d) if err != nil { - return diag.Errorf("error while removing remote file with sudo: %s", err.Error()) + return diag.Errorf("error while checking if remote file exists with sudo: %s", err.Error()) + } + if exists { + err := client.readFileSudo(d) + if err != nil { + return diag.Errorf("error while reading remote file with sudo: %s", err.Error()) + } + } else { + return diag.Errorf("cannot read file, it does not exist.") } } else { err := client.readFile(d) if err != nil { - return diag.Errorf("error while removing remote file: %s", err.Error()) + return diag.Errorf("error while reading remote file: %s", err.Error()) } } @@ -150,9 +162,17 @@ func resourceRemotefileDelete(ctx context.Context, d *schema.ResourceData, meta sudo, ok := d.GetOk("conn.0.sudo") if ok && sudo.(bool) { - err := client.deleteFileSudo(d) + exists, err := client.fileExistsSudo(d) if err != nil { - return diag.Errorf("error while removing remote file with sudo: %s", err.Error()) + return diag.Errorf("error while checking if remote file exists with sudo: %s", err.Error()) + } + if exists { + err := client.deleteFileSudo(d) + if err != nil { + return diag.Errorf("error while removing remote file with sudo: %s", err.Error()) + } + } else { + return diag.Errorf("cannot delete file, it does not exist.") } } else { err := client.deleteFile(d)