Skip to content

Commit

Permalink
Merge pull request #21 from bilalcaliskan/devel
Browse files Browse the repository at this point in the history
Devel
  • Loading branch information
bilalcaliskan authored Mar 10, 2024
2 parents e6a190e + a53500a commit a40d13d
Show file tree
Hide file tree
Showing 16 changed files with 256 additions and 49 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ run-daemon: build-daemon
chmod +x ./.bin/split-the-tunnel
sudo ./.bin/split-the-tunnel $(DEFAULT_GO_RUN_ARGS)

.PHONY: run-cli
run-cli: build-cli
$(info running cli...)
chmod +x ./.bin/stt-cli
sudo ./.bin/stt-cli $(DEFAULT_GO_RUN_ARGS)

.PHONY: prepare-initial-project
GITHUB_USERNAME ?= $(shell read -p "Your Github username(ex: bilalcaliskan): " github_username; echo $$github_username)
PROJECT_NAME ?= $(shell read -p "'Kebab-cased' Project Name(ex: golang-cli-template): " project_name; echo $$project_name)
Expand Down
3 changes: 2 additions & 1 deletion cmd/cli/add/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ to quickly create a Cobra application.`,
},
RunE: func(cmd *cobra.Command, args []string) error {
logger := cmd.Context().Value(constants.LoggerKey{}).(zerolog.Logger)
socketPath := cmd.Context().Value(constants.SocketPathKey{}).(string)

logger.Info().
Str("operation", cmd.Name()).
Expand All @@ -38,7 +39,7 @@ to quickly create a Cobra application.`,

for _, arg := range args {
req := fmt.Sprintf("%s %s", cmd.Name(), arg)
res, err := utils.SendCommandToDaemon(utils.SocketPath, req)
res, err := utils.SendCommandToDaemon(socketPath, req)
if err != nil {
logger.Error().Str("command", req).Err(err).Msg(constants.FailedToProcessCommand)
continue
Expand Down
21 changes: 17 additions & 4 deletions cmd/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package main

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

"github.com/bilalcaliskan/split-the-tunnel/cmd/cli/purge"

"github.com/bilalcaliskan/split-the-tunnel/internal/constants"
"github.com/bilalcaliskan/split-the-tunnel/internal/logging"
"github.com/pkg/errors"

"github.com/bilalcaliskan/split-the-tunnel/cmd/cli/add"
"github.com/bilalcaliskan/split-the-tunnel/cmd/cli/list"
Expand All @@ -20,9 +21,11 @@ import (
)

var (
verbose bool
ver = version.Get()
cliCmd = &cobra.Command{
verbose bool
socketFile string
workspace string
ver = version.Get()
cliCmd = &cobra.Command{
Use: "stt-cli",
Short: "",
Long: ``,
Expand All @@ -38,6 +41,9 @@ var (
logger.Debug().Str("foo", "bar").Msg("this is a dummy log")
}

socketPath := filepath.Join(workspace, socketFile)

cmd.SetContext(context.WithValue(cmd.Context(), constants.SocketPathKey{}, socketPath))
cmd.SetContext(context.WithValue(cmd.Context(), constants.LoggerKey{}, logger))
},
}
Expand All @@ -54,6 +60,13 @@ func main() {
}

func init() {
homeDir, err := os.UserHomeDir()
if err != nil {
panic(errors.Wrap(err, "failed to get user home directory"))
}

cliCmd.PersistentFlags().StringVarP(&workspace, "workspace", "w", filepath.Join(homeDir, ".split-the-tunnel"), "workspace directory path")
cliCmd.PersistentFlags().StringVarP(&socketFile, "socket-file", "s", "ipc.sock", "unix domain socket file in workspace")
cliCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "enable verbose mode")

cliCmd.AddCommand(add.AddCmd)
Expand Down
3 changes: 2 additions & 1 deletion cmd/cli/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ to quickly create a Cobra application.`,
},
RunE: func(cmd *cobra.Command, args []string) error {
logger := cmd.Context().Value(constants.LoggerKey{}).(zerolog.Logger)
socketPath := cmd.Context().Value(constants.SocketPathKey{}).(string)

logger.Info().
Str("operation", cmd.Name()).
Msg(constants.ProcessCommand)

res, err := utils.SendCommandToDaemon(utils.SocketPath, cmd.Name())
res, err := utils.SendCommandToDaemon(socketPath, cmd.Name())
if err != nil {
logger.Error().Str("command", cmd.Name()).Err(err).Msg(constants.FailedToProcessCommand)

Expand Down
3 changes: 2 additions & 1 deletion cmd/cli/purge/purge.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ to quickly create a Cobra application.`,
},
RunE: func(cmd *cobra.Command, args []string) error {
logger := cmd.Context().Value(constants.LoggerKey{}).(zerolog.Logger)
socketPath := cmd.Context().Value(constants.SocketPathKey{}).(string)

logger.Info().
Str("operation", cmd.Name()).
Msg(constants.ProcessCommand)

res, err := utils.SendCommandToDaemon(utils.SocketPath, cmd.Name())
res, err := utils.SendCommandToDaemon(socketPath, cmd.Name())
if err != nil {
logger.Error().Str("command", cmd.Name()).Err(err).Msg(constants.FailedToProcessCommand)

Expand Down
3 changes: 2 additions & 1 deletion cmd/cli/remove/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ to quickly create a Cobra application.`,
},
RunE: func(cmd *cobra.Command, args []string) error {
logger := cmd.Context().Value(constants.LoggerKey{}).(zerolog.Logger)
socketPath := cmd.Context().Value(constants.SocketPathKey{}).(string)

logger.Info().
Str("operation", cmd.Name()).
Expand All @@ -38,7 +39,7 @@ to quickly create a Cobra application.`,

for _, arg := range args {
req := fmt.Sprintf("%s %s", cmd.Name(), arg)
res, err := utils.SendCommandToDaemon(utils.SocketPath, req)
res, err := utils.SendCommandToDaemon(socketPath, req)
if err != nil {
logger.Error().
Str("command", req).
Expand Down
2 changes: 0 additions & 2 deletions cmd/cli/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"github.com/pkg/errors"
)

const SocketPath = "/tmp/mydaemon.sock"

var (
ErrNoArgs = errors.New("no arguments provided")
ErrTooManyArgs = errors.New("too many arguments provided")
Expand Down
27 changes: 20 additions & 7 deletions cmd/daemon/daemon.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package main

import (
"fmt"
"os"
"os/signal"
"syscall"
"time"

"github.com/pkg/errors"

"github.com/bilalcaliskan/split-the-tunnel/internal/state"

"github.com/bilalcaliskan/split-the-tunnel/internal/constants"
Expand All @@ -17,16 +20,16 @@ import (
"github.com/spf13/cobra"
)

const socketPath = "/tmp/mydaemon.sock"

var (
opts *options.RootOptions
ver = version.Get()
)

func init() {
opts = options.GetRootOptions()
opts.InitFlags(daemonCmd)
if err := opts.InitFlags(daemonCmd); err != nil {
panic(errors.Wrap(err, "failed to initialize flags"))
}
}

// daemonCmd represents the base command when called without any subcommands
Expand All @@ -36,6 +39,16 @@ var daemonCmd = &cobra.Command{
Long: ``,
Version: ver.GitVersion,
RunE: func(cmd *cobra.Command, args []string) error {
if err := opts.ReadConfig(); err != nil {
return errors.Wrap(err, "failed to read config")
}

fmt.Println(opts)

if err := os.MkdirAll(opts.Workspace, 0755); err != nil {
return errors.Wrap(err, "failed to create workspace directory")
}

logger := logging.GetLogger().With().Str("job", "main").Logger()
logger.Info().Str("appVersion", ver.GitVersion).Str("goVersion", ver.GoVersion).Str("goOS", ver.GoOs).
Str("goArch", ver.GoArch).Str("gitCommit", ver.GitCommit).Str("buildDate", ver.BuildDate).
Expand All @@ -48,20 +61,20 @@ var daemonCmd = &cobra.Command{
st := state.NewState(logger)

// Initialize IPC mechanism
if err := ipc.InitIPC(st, socketPath, logger); err != nil {
if err := ipc.InitIPC(st, opts.SocketPath, logger); err != nil {
logger.Error().Err(err).Msg(constants.FailedToInitializeIPC)
return err
}

logger.Info().Str("socket", socketPath).Msg(constants.IPCInitialized)
logger.Info().Str("socket", opts.SocketPath).Msg(constants.IPCInitialized)

defer func() {
if err := ipc.Cleanup(socketPath); err != nil {
if err := ipc.Cleanup(opts.SocketPath); err != nil {
logger.Error().Err(err).Msg(constants.FailedToCleanupIPC)
}
}()

logger.Info().Str("socket", socketPath).Msg(constants.DaemonRunning)
logger.Info().Str("socket", opts.SocketPath).Msg(constants.DaemonRunning)

go func() {
// Create a ticker that fires every 5 minutes
Expand Down
82 changes: 77 additions & 5 deletions cmd/daemon/options/options.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,95 @@
package options

import "github.com/spf13/cobra"
import (
"log"
"os"
"path/filepath"

"github.com/spf13/viper"

"github.com/pkg/errors"
"github.com/spf13/cobra"
)

var rootOptions = &RootOptions{}

// RootOptions contains frequent command line and application options.
type RootOptions struct {
DnsServers string
CheckIntervalMin int
Verbose bool
Workspace string // This field will be managed by the command line argument
ConfigFile string // This field will be managed by the command line argument
DnsServers string `toml:"dns-servers"` // This field will be managed by the config file
CheckIntervalMin int `toml:"check-interval-min"` // This field will be managed by the config file
SocketPath string `toml:"socket-path"` // This field will be managed by the config file
Verbose bool `toml:"verbose"` // This field will be managed by the config file
}

// GetRootOptions returns the pointer of RootOptions
func GetRootOptions() *RootOptions {
return rootOptions
}

func (opts *RootOptions) InitFlags(cmd *cobra.Command) {
func (opts *RootOptions) InitFlags(cmd *cobra.Command) error {
if err := opts.setFlags(cmd); err != nil {
return errors.Wrap(err, "failed to set flags")
}

if err := viper.BindPFlags(cmd.Flags()); err != nil {
return errors.Wrap(err, "failed to bind flags")
}

return nil
}

//func (opts *RootOptions) setDefaultWorkspace() error {
// homeDir, err := os.UserHomeDir()
// if err != nil {
// return errors.Wrap(err, "failed to get user home directory")
// }
//
// ws := filepath.Join(homeDir, ".split-the-tunnel")
// opts.Workspace = ws
// opts.ConfigFile = filepath.Join(ws, "config.toml")
//
// return nil
//}

func (opts *RootOptions) setFlags(cmd *cobra.Command) error {
homeDir, err := os.UserHomeDir()
if err != nil {
return errors.Wrap(err, "failed to get user home directory")
}

cmd.Flags().StringVarP(&opts.Workspace, "workspace", "w", filepath.Join(homeDir, ".split-the-tunnel"), "workspace directory path")
cmd.Flags().StringVarP(&opts.ConfigFile, "config-file", "c", "config.toml", "config file path, will search in workspace")
cmd.Flags().StringVarP(&opts.SocketPath, "socket-path", "", "ipc.sock", "unix domain socket path in workspace")
cmd.Flags().BoolVarP(&opts.Verbose, "verbose", "", false, "verbose logging output")
cmd.Flags().StringVarP(&opts.DnsServers, "dns-servers", "", "", "comma separated dns servers to be used for DNS resolving")
cmd.Flags().IntVarP(&opts.CheckIntervalMin, "check-interval-min", "", 5, "routing table check interval with collected state, in minutes")

return nil
}

func (opts *RootOptions) ReadConfig() error {
viper.SetConfigFile(opts.ConfigFile)
viper.SetConfigType("toml")

opts.SocketPath = filepath.Join(opts.Workspace, opts.SocketPath)
opts.ConfigFile = filepath.Join(opts.Workspace, opts.ConfigFile)

if _, err := os.Stat(opts.ConfigFile); os.IsNotExist(err) {
log.Printf("config file not found in %s, will use default values\n", opts.ConfigFile)
return nil
} else if err != nil {
return errors.Wrap(err, "failed to access config file")
}

if err := viper.ReadInConfig(); err != nil {
return errors.Wrap(err, "failed to read config file")
}

if err := viper.Unmarshal(opts); err != nil {
return errors.Wrap(err, "failed to unmarshal config file")
}

return nil
}
2 changes: 1 addition & 1 deletion cmd/daemon/options/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ func TestGetRootOptions(t *testing.T) {
func TestRootOptions_InitFlags(t *testing.T) {
cmd := cobra.Command{}
opts := GetRootOptions()
opts.InitFlags(&cmd)
assert.NoError(t, opts.InitFlags(&cmd))
}
25 changes: 19 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,34 @@ require (
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.32.0
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.9.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.17.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit a40d13d

Please sign in to comment.