diff --git a/.reuse/dep5 b/.reuse/dep5 index 9cb366c..3562251 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -7,6 +7,6 @@ Files: *.md docs/* Copyright: 2019 Outscale SAS License: CC-BY-4.0 -Files: cmd/* *.mod *.sum Makefile internal/common/*.go internal/providers/outscale_oapi/* docs/providers.sh internal/providers/provider_example/* internal/providers/s3/* .github/* .goreleaser.yml version .gitignore +Files: cmd/* *.mod *.sum Makefile internal/common/*.go internal/providers/outscale_oapi/* docs/providers.sh internal/providers/provider_example/* internal/providers/s3/* internal/providers/fs/* .github/* .goreleaser.yml version .gitignore Copyright: 2021 Outscale SAS License: BSD-3-Clause diff --git a/cmd/frieza/cli_provider.go b/cmd/frieza/cli_provider.go index a07e43b..ef18d33 100644 --- a/cmd/frieza/cli_provider.go +++ b/cmd/frieza/cli_provider.go @@ -1,7 +1,7 @@ package main import ( - "log" + "fmt" "github.com/teris-io/cli" ) @@ -17,7 +17,7 @@ func cliProviderLs() cli.Command { WithShortcut("ls"). WithAction(func(args []string, options map[string]string) int { for providerName := range providersTypes { - log.Printf("%s\n", providerName) + fmt.Println(providerName) } return 0 }) @@ -30,7 +30,7 @@ func cliProviderDescribe() cli.Command { WithAction(func(args []string, options map[string]string) int { providerName := args[0] for _, providerType := range providersTypes[providerName] { - log.Printf("%s\n", providerType) + fmt.Println(providerType) } return 0 }) diff --git a/cmd/frieza/providers.go b/cmd/frieza/providers.go index 2c8fd19..fec6d68 100644 --- a/cmd/frieza/providers.go +++ b/cmd/frieza/providers.go @@ -4,6 +4,7 @@ import ( "fmt" . "github.com/outscale-dev/frieza/internal/common" + "github.com/outscale-dev/frieza/internal/providers/fs" "github.com/outscale-dev/frieza/internal/providers/outscale_oapi" "github.com/outscale-dev/frieza/internal/providers/s3" "github.com/teris-io/cli" @@ -17,18 +18,22 @@ func ProviderNew(profile Profile) (Provider, error) { // return provider_example.New(profile.Config, Debug) case s3.Name: return s3.New(profile.Config, GlobalCliOptions.debug) + case fs.Name: + return fs.New(profile.Config, GlobalCliOptions.debug) } - return nil, fmt.Errorf("Provider %s not found", profile.Provider) + return nil, fmt.Errorf("provider %s not found", profile.Provider) } var providersCli = []func() (string, cli.Command){ outscale_oapi.Cli, //provider_example.Cli, s3.Cli, + fs.Cli, } var providersTypes = map[string][]ObjectType{ outscale_oapi.Name: outscale_oapi.Types(), //provider_example.Name: provider_example.Types(), s3.Name: s3.Types(), + fs.Name: fs.Types(), } diff --git a/docs/providers.md b/docs/providers.md index caf857c..d2aa705 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -1,9 +1,5 @@ # Providers and supported objects -## s3 -- object -- bucket - ## outscale_oapi - vm - load_balancer @@ -21,3 +17,12 @@ - vpn_connection - virtual_gateway - nic +- access_key + +## s3 +- object +- bucket + +## fs +- file +- folder diff --git a/internal/providers/fs/fs.go b/internal/providers/fs/fs.go new file mode 100644 index 0000000..8e055ea --- /dev/null +++ b/internal/providers/fs/fs.go @@ -0,0 +1,168 @@ +package fs + +import ( + "errors" + "fmt" + "log" + "os" + "path" + + . "github.com/outscale-dev/frieza/internal/common" + "github.com/teris-io/cli" +) + +const Name = "fs" + +const typeFile = "file" +const typeFolder = "folder" + +type FileSystem struct { + Path string +} + +func checkConfig(config ProviderConfig) error { + if len(config["path"]) == 0 { + return errors.New("path is needed") + } + return nil +} + +func New(config ProviderConfig, debug bool) (*FileSystem, error) { + if err := checkConfig(config); err != nil { + return nil, err + } + return &FileSystem{ + Path: config["path"], + }, nil +} + +func Types() []ObjectType { + object_types := []ObjectType{typeFile, typeFolder} + return object_types +} + +func Cli() (string, cli.Command) { + return Name, cli.NewCommand(Name, "create new file system profile"). + WithOption(cli.NewOption("path", "folder path")) +} + +func (provider *FileSystem) Name() string { + return Name +} + +func (provider *FileSystem) Types() []ObjectType { + return Types() +} + +func (provider *FileSystem) AuthTest() error { + // Will test if we can access the folder + if _, err := os.ReadDir(provider.Path); err != nil { + return fmt.Errorf("cannot move to directory: %s", err.Error()) + } + return nil +} + +func (provider *FileSystem) ReadObjects(typeName string) []Object { + switch typeName { + case typeFile: + return provider.readFiles() + case typeFolder: + return provider.readFolders() + } + return []Object{} +} + +func (provider *FileSystem) DeleteObjects(typeName string, objects []Object) { + switch typeName { + case typeFile: + provider.deleteFiles(objects) + case typeFolder: + provider.deleteFolders(objects) + } +} + +func (provider *FileSystem) StringObject(object string, typeName string) string { + return object +} + +func (provider *FileSystem) readFiles() []Object { + files := make([]Object, 0) + + if err := os.Chdir(provider.Path); err != nil { + log.Printf("cannot move to directory: %s", err.Error()) + return files + } + + folderStack := []string{"."} + for len(folderStack) > 0 { + dirPath := folderStack[len(folderStack)-1] + folderStack = folderStack[:len(folderStack)-1] + dir, err := os.ReadDir(dirPath) + if err != nil { + log.Printf("cannot read directory: %s", err.Error()) + continue + } + for _, node := range dir { + nodePath := path.Join(dirPath, node.Name()) + if node.IsDir() { + folderStack = append(folderStack, nodePath) + } + if node.Type().IsRegular() { + files = append(files, nodePath) + } + } + } + return files +} + +func (provider *FileSystem) deleteFiles(files []Object) { + for _, relativeFilePath := range files { + filePath := path.Join(provider.Path, relativeFilePath) + log.Printf("Deleting file %s ... ", filePath) + if err := os.Remove(filePath); err != nil { + log.Printf("cannot remove file %s\n", err.Error()) + continue + } + log.Println("OK") + } +} + +func (provider *FileSystem) readFolders() []Object { + folders := make([]Object, 0) + + if err := os.Chdir(provider.Path); err != nil { + log.Printf("cannot move to directory: %s", err.Error()) + return folders + } + + folderStack := []string{"."} + for len(folderStack) > 0 { + dirPath := folderStack[len(folderStack)-1] + folderStack = folderStack[:len(folderStack)-1] + dir, err := os.ReadDir(dirPath) + if err != nil { + log.Printf("cannot read directory: %s", err.Error()) + continue + } + for _, node := range dir { + nodePath := path.Join(dirPath, node.Name()) + if node.IsDir() { + folderStack = append(folderStack, nodePath) + folders = append(folders, nodePath) + } + } + } + return folders +} + +func (provider *FileSystem) deleteFolders(folders []Object) { + for _, relativeFolderPath := range folders { + folderPath := path.Join(provider.Path, relativeFolderPath) + log.Printf("Deleting folder %s ... ", folderPath) + if err := os.Remove(folderPath); err != nil { + log.Printf("cannot remove folder %s\n", err.Error()) + continue + } + log.Println("OK") + } +}