From a78442f526ad8d2ec711f7c5223af77044558a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Jutteau?= Date: Wed, 15 Jun 2022 10:35:05 +0200 Subject: [PATCH] fs: "fs" is a new provider with one first "file" resource. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new provider will allow frieza to cleanup local resources like files and folders. This should also ease core testing. close #34 ref #35 Signed-off-by: Jérôme Jutteau --- cmd/frieza/providers.go | 7 ++- docs/providers.md | 22 ------- internal/providers/fs/fs.go | 122 ++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 23 deletions(-) create mode 100644 internal/providers/fs/fs.go 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..005eb1e 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -1,23 +1 @@ # Providers and supported objects - -## s3 -- object -- bucket - -## outscale_oapi -- vm -- load_balancer -- nat_service -- security_group -- public_ip -- volume -- keypair -- route_table -- internet_service -- subnet -- net -- image -- snapshot -- vpn_connection -- virtual_gateway -- nic diff --git a/internal/providers/fs/fs.go b/internal/providers/fs/fs.go new file mode 100644 index 0000000..6d907ae --- /dev/null +++ b/internal/providers/fs/fs.go @@ -0,0 +1,122 @@ +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" + +type FileProvider 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) (*FileProvider, error) { + if err := checkConfig(config); err != nil { + return nil, err + } + return &FileProvider{ + Path: config["path"], + }, nil +} + +func Types() []ObjectType { + object_types := []ObjectType{typeFile} + 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 *FileProvider) Name() string { + return Name +} + +func (provider *FileProvider) Types() []ObjectType { + return Types() +} + +func (provider *FileProvider) 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 *FileProvider) ReadObjects(typeName string) []Object { + switch typeName { + case typeFile: + return provider.readFiles() + } + return []Object{} +} + +func (provider *FileProvider) DeleteObjects(typeName string, objects []Object) { + switch typeName { + case typeFile: + provider.deleteFiles(objects) + } +} + +func (provider *FileProvider) StringObject(object string, typeName string) string { + return object +} + +func (provider *FileProvider) 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 *FileProvider) 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") + } +}