Skip to content

Commit

Permalink
refactor tfrobot cmds
Browse files Browse the repository at this point in the history
  • Loading branch information
Eslam-Nawara committed Nov 4, 2024
1 parent a711837 commit 12af137
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 126 deletions.
34 changes: 7 additions & 27 deletions tfrobot/cmd/cancel.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package cmd

import (
"fmt"
"os"
"path/filepath"

"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/threefoldtech/tfgrid-sdk-go/tfrobot/internal/parser"
"github.com/threefoldtech/tfgrid-sdk-go/tfrobot/pkg/deployer"
)

Expand All @@ -19,36 +17,18 @@ var cancelCmd = &cobra.Command{
if len(cmd.Flags().Args()) != 0 {
return fmt.Errorf("'cancel' and %v cannot be used together, please use one command at a time", cmd.Flags().Args())
}

debug, err := cmd.Flags().GetBool("debug")
if err != nil {
return fmt.Errorf("invalid log debug mode input '%v' with error: %w", debug, err)
}

configPath, err := cmd.Flags().GetString("config")
if err != nil {
return fmt.Errorf("error in configuration file: %w", err)
}

if configPath == "" {
return fmt.Errorf("required configuration file path is empty")
return errors.Wrap(err, "error in configuration file")
}

configFile, err := os.Open(configPath)
debug, err := cmd.Flags().GetBool("debug")
if err != nil {
return fmt.Errorf("failed to open configuration file '%s' with error: %w", configPath, err)
return errors.Wrapf(err, "invalid log debug mode input '%v'", debug)
}
defer configFile.Close()

jsonFmt := filepath.Ext(configPath) == jsonExt
ymlFmt := filepath.Ext(configPath) == yamlExt || filepath.Ext(configPath) == ymlExt
if !jsonFmt && !ymlFmt {
return fmt.Errorf("unsupported configuration file format '%s', should be [yaml, yml, json]", configPath)
}

cfg, err := parser.ParseConfig(configFile, jsonFmt)
cfg, err := readConfig(configPath)
if err != nil {
return fmt.Errorf("failed to parse configuration file '%s' with error: %w", configPath, err)
return err
}

tfPluginClient, err := setup(cfg, debug)
Expand All @@ -58,7 +38,7 @@ var cancelCmd = &cobra.Command{

err = deployer.RunCanceler(cfg, tfPluginClient, debug)
if err != nil {
return fmt.Errorf("failed to cancel configured deployments with error: %w", err)
return errors.Wrap(err, "failed to cancel configured deployments")
}

return nil
Expand Down
68 changes: 14 additions & 54 deletions tfrobot/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,12 @@ package cmd

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"

"github.com/rs/zerolog/log"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/threefoldtech/tfgrid-sdk-go/tfrobot/internal/parser"
"github.com/threefoldtech/tfgrid-sdk-go/tfrobot/pkg/deployer"
"golang.org/x/sys/unix"
)

const (
ymlExt = ".yml"
yamlExt = ".yaml"
jsonExt = ".json"
)

var deployCmd = &cobra.Command{
Expand All @@ -29,53 +19,26 @@ var deployCmd = &cobra.Command{
if len(cmd.Flags().Args()) != 0 {
return fmt.Errorf("'deploy' and %v cannot be used together, please use one command at a time", cmd.Flags().Args())
}

debug, err := cmd.Flags().GetBool("debug")
if err != nil {
return fmt.Errorf("invalid log debug mode input '%v' with error: %w", debug, err)
}

outputPath, err := cmd.Flags().GetString("output")
if err != nil {
return fmt.Errorf("error in output file: %w", err)
}

outJsonFmt := filepath.Ext(outputPath) == jsonExt
outYmlFmt := filepath.Ext(outputPath) == yamlExt || filepath.Ext(outputPath) == ymlExt
if !outJsonFmt && !outYmlFmt {
return fmt.Errorf("unsupported output file format '%s', should be [yaml, yml, json]", outputPath)
}

_, err = os.Stat(outputPath)
// check if output file is writable
if !errors.Is(err, os.ErrNotExist) && unix.Access(outputPath, unix.W_OK) != nil {
return fmt.Errorf("output path '%s' is not writable", outputPath)
}

configPath, err := cmd.Flags().GetString("config")
if err != nil {
return fmt.Errorf("error in configuration file: %w", err)
return errors.Wrap(err, "error in configuration file")
}

if configPath == "" {
return fmt.Errorf("required configuration file path is empty")
debug, err := cmd.Flags().GetBool("debug")
if err != nil {
return errors.Wrapf(err, "invalid log debug mode input '%v'", debug)
}

configFile, err := os.Open(configPath)
outputPath, err := cmd.Flags().GetString("output")
if err != nil {
return fmt.Errorf("failed to open configuration file '%s' with error: %w", configPath, err)
return errors.Wrap(err, "error in output file")
}
defer configFile.Close()

jsonFmt := filepath.Ext(configPath) == jsonExt
ymlFmt := filepath.Ext(configPath) == yamlExt || filepath.Ext(configPath) == ymlExt
if !jsonFmt && !ymlFmt {
return fmt.Errorf("unsupported configuration file format '%s', should be [yaml, yml, json]", configPath)
if err = checkOutputFile(outputPath); err != nil {
return err
}

cfg, err := parser.ParseConfig(configFile, jsonFmt)
cfg, err := readConfig(configPath)
if err != nil {
return fmt.Errorf("failed to parse configuration file '%s' with error: %w", configPath, err)
return err
}

tfPluginClient, err := setup(cfg, debug)
Expand All @@ -84,14 +47,11 @@ var deployCmd = &cobra.Command{
}

if err = parser.ValidateConfig(cfg, tfPluginClient); err != nil {
return fmt.Errorf("failed to validate configuration file '%s' with error: %w", configPath, err)
return errors.Wrapf(err, "failed to validate configuration file '%s' with error", configPath)
}

ctx := context.Background()
if errs := deployer.RunDeployer(ctx, cfg, tfPluginClient, outputPath, debug); errs != nil {
log.Error().Msg("deployments failed with errors: ")
fmt.Println(errs)
os.Exit(1)
if errs := deployer.RunDeployer(context.Background(), cfg, tfPluginClient, outputPath, debug); errs != nil {
return errors.Wrap(err, "failed to run deployer")
}

return nil
Expand Down
58 changes: 13 additions & 45 deletions tfrobot/cmd/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@ package cmd

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"

"github.com/rs/zerolog/log"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/threefoldtech/tfgrid-sdk-go/tfrobot/internal/parser"
"github.com/threefoldtech/tfgrid-sdk-go/tfrobot/pkg/deployer"
"golang.org/x/sys/unix"
)

var loadCmd = &cobra.Command{
Expand All @@ -24,62 +19,35 @@ var loadCmd = &cobra.Command{
return fmt.Errorf("'load' and %v cannot be used together, please use one command at a time", cmd.Flags().Args())
}

debug, err := cmd.Flags().GetBool("debug")
if err != nil {
return fmt.Errorf("invalid log debug mode input '%v' with error: %w", debug, err)
}

outputPath, err := cmd.Flags().GetString("output")
if err != nil {
return fmt.Errorf("error in output file: %w", err)
}
outJsonFmt := filepath.Ext(outputPath) == jsonExt
outYmlFmt := filepath.Ext(outputPath) == yamlExt || filepath.Ext(outputPath) == ymlExt
if !outJsonFmt && !outYmlFmt {
return fmt.Errorf("unsupported output file format '%s', should be [yaml, yml, json]", outputPath)
}

_, err = os.Stat(outputPath)
// check if output file is writable
if !errors.Is(err, os.ErrNotExist) && unix.Access(outputPath, unix.W_OK) != nil {
return fmt.Errorf("output path '%s' is not writable", outputPath)
}

configPath, err := cmd.Flags().GetString("config")
if err != nil {
return fmt.Errorf("error in configuration file: %w", err)
return errors.Wrap(err, "error in configuration file")
}
if configPath == "" {
return fmt.Errorf("required configuration file path is empty")
debug, err := cmd.Flags().GetBool("debug")
if err != nil {
return errors.Wrapf(err, "invalid log debug mode input '%v'", debug)
}

configFile, err := os.Open(configPath)
outputPath, err := cmd.Flags().GetString("output")
if err != nil {
return fmt.Errorf("failed to open configuration file '%s' with error: %w", configPath, err)
return errors.Wrap(err, "error in output file")
}
defer configFile.Close()

jsonFmt := filepath.Ext(configPath) == jsonExt
ymlFmt := filepath.Ext(configPath) == yamlExt || filepath.Ext(configPath) == ymlExt
if !jsonFmt && !ymlFmt {
return fmt.Errorf("unsupported configuration file format '%s', should be [yaml, yml, json]", configPath)
if err = checkOutputFile(outputPath); err != nil {
return err
}

cfg, err := parser.ParseConfig(configFile, jsonFmt)
cfg, err := readConfig(configPath)
if err != nil {
return fmt.Errorf("failed to parse configuration file '%s' with error: %w", configPath, err)
return err
}

ctx := context.Background()
tfPluginClient, err := setup(cfg, debug)
if err != nil {
return err
}

if err := deployer.RunLoader(ctx, cfg, tfPluginClient, debug, outputPath); err != nil {
log.Error().Msg("failed to load configured deployments")
fmt.Println(err)
os.Exit(1)
if err := deployer.RunLoader(context.Background(), cfg, tfPluginClient, debug, outputPath); err != nil {
return errors.Wrap(err, "failed to load configured deployments")
}

return nil
Expand Down
47 changes: 47 additions & 0 deletions tfrobot/cmd/setup.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
package cmd

import (
"fmt"
"os"
"path/filepath"
"slices"

"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer"
"github.com/threefoldtech/tfgrid-sdk-go/tfrobot/internal/parser"
tfrobot "github.com/threefoldtech/tfgrid-sdk-go/tfrobot/pkg/deployer"
"golang.org/x/sys/unix"
)

const jsonExt = ".json"

var allowedExt = []string{".yml", ".yaml", jsonExt}

func setup(conf tfrobot.Config, debug bool) (deployer.TFPluginClient, error) {
network := conf.Network
log.Debug().Str("network", network).Send()
Expand All @@ -24,3 +36,38 @@ func setup(conf tfrobot.Config, debug bool) (deployer.TFPluginClient, error) {

return deployer.NewTFPluginClient(mnemonic, opts...)
}

func readConfig(configPath string) (tfrobot.Config, error) {
if configPath == "" {
return tfrobot.Config{}, errors.New("required configuration file path is empty")
}

configFile, err := os.Open(configPath)
if err != nil {
return tfrobot.Config{}, errors.Wrapf(err, "failed to open configuration file '%s'", configPath)
}
defer configFile.Close()

if !slices.Contains(allowedExt, filepath.Ext(configPath)) {
return tfrobot.Config{}, fmt.Errorf("unsupported configuration file format '%s', should be [yaml, yml, json]", configPath)
}

cfg, err := parser.ParseConfig(configFile, filepath.Ext(configPath) == jsonExt)
if err != nil {
return tfrobot.Config{}, errors.Wrapf(err, "failed to parse configuration file '%s' with error", configPath)
}
return cfg, nil
}

func checkOutputFile(outputPath string) error {
if !slices.Contains(allowedExt, filepath.Ext(outputPath)) {
return fmt.Errorf("unsupported output file format '%s', should be [yaml, yml, json]", outputPath)
}

_, err := os.Stat(outputPath)
// check if output file is writable
if !errors.Is(err, os.ErrNotExist) && unix.Access(outputPath, unix.W_OK) != nil {
return fmt.Errorf("output path '%s' is not writable", outputPath)
}
return nil
}

0 comments on commit 12af137

Please sign in to comment.