terraform-provider-file/internal/provider/file_client/file_os_client.go

166 lines
3.9 KiB
Go

package file_client
import (
"compress/gzip"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"os"
"path/filepath"
"strconv"
)
// The default FileClient, using the os package.
type OsFileClient struct{}
var _ FileClient = &OsFileClient{} // make sure the OsFileClient implements the FileClient
func (c *OsFileClient) Create(directory string, name string, data string, permissions string) error {
path := filepath.Join(directory, name)
modeInt, err := strconv.ParseUint(permissions, 8, 32)
if err != nil {
return err
}
return os.WriteFile(path, []byte(data), os.FileMode(modeInt))
}
func (c *OsFileClient) Read(directory string, name string) (string, string, error) {
path := filepath.Join(directory, name)
info, err := os.Stat(path)
if err != nil && os.IsNotExist(err) {
return "", "", fmt.Errorf("file not found")
}
if err != nil {
return "", "", err
}
mode := fmt.Sprintf("%#o", info.Mode().Perm())
contents, err := os.ReadFile(path)
if err != nil {
return "", "", err
}
return mode, string(contents), nil
}
func (c *OsFileClient) Update(currentDirectory string, currentName string, newDirectory string, newName string, data string, permissions string) error {
currentPath := filepath.Join(currentDirectory, currentName)
newPath := filepath.Join(newDirectory, newName)
if currentPath != newPath {
err := os.Rename(currentPath, newPath)
if err != nil {
return err
}
}
modeInt, err := strconv.ParseUint(permissions, 8, 32)
if err != nil {
return err
}
if err = os.WriteFile(newPath, []byte(data), os.FileMode(modeInt)); err != nil {
return err
}
return nil
}
func (c *OsFileClient) Delete(directory string, name string) error {
path := filepath.Join(directory, name)
return os.RemoveAll(path)
}
func (c *OsFileClient) Compress(directory string, name string, outputName string) error {
inFilePath := filepath.Join(directory, name)
inFile, err := os.Open(inFilePath)
if err != nil {
return err
}
defer inFile.Close()
// Create a tmp file to hold compressed data during conversion
outFilePath := filepath.Join(directory, outputName)
outFile, err := os.Create(outFilePath)
if err != nil {
return err
}
defer outFile.Close()
// copy inFile to gzip writer, which writes to outFile
// use the best compression ratio possible
gzipWriter, err := gzip.NewWriterLevel(outFile, gzip.BestCompression)
if err != nil {
return err
}
_, err = io.Copy(gzipWriter, inFile)
if err != nil {
return err
}
return gzipWriter.Close()
}
// base64 encodes a file.
func (c *OsFileClient) Encode(directory string, name string, outputName string) error {
inFilePath := filepath.Join(directory, name)
inFile, err := os.Open(inFilePath)
if err != nil {
return err
}
defer inFile.Close()
// Create a tmp file to hold encoded data during conversion
outFilePath := filepath.Join(directory, outputName)
outFile, err := os.Create(outFilePath)
if err != nil {
return err
}
defer outFile.Close()
// Copy writes to the base64Encoder, which writes to the outFile
base64Encoder := base64.NewEncoder(base64.StdEncoding, outFile)
_, err = io.Copy(base64Encoder, inFile)
if err != nil {
return err
}
return base64Encoder.Close()
}
// get the sha256 hash of the file, formatted as hex.
func (c *OsFileClient) Hash(directory string, name string) (string, error) {
filePath := filepath.Join(directory, name)
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
hasher := sha256.New()
_, err = io.Copy(hasher, file)
if err != nil {
return "", err
}
contentsHash := hasher.Sum(nil)
hexContents := hex.EncodeToString(contentsHash)
return hexContents, nil
}
func (c *OsFileClient) Copy(currentPath string, newPath string) error {
srcFile, err := os.Open(currentPath)
if err != nil {
return err
}
defer srcFile.Close()
destFile, err := os.Create(newPath)
if err != nil {
return err
}
defer destFile.Close()
_, err = io.Copy(destFile, srcFile)
if err != nil {
return err
}
return nil
}