Skip to content

Commit

Permalink
Initial commit. Core functions, ability to set token and save config,…
Browse files Browse the repository at this point in the history
… calling methods with params
  • Loading branch information
bssth committed Apr 1, 2024
0 parents commit aeadfcc
Show file tree
Hide file tree
Showing 18 changed files with 1,242 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bin
config.yaml
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/kt-cli.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# ktCloud CLI Client

This is a command-line interface (CLI) client for the ktCloud service. It is written in Go and provides peer-to-peer encryption and zero-trust security. The client allows you to interact with the ktCloud service, enabling you to download, upload, and use the API for ktCloud.

## Features

- **P2P Encryption**: All data transferred between the client and ktCloud service is encrypted using peer-to-peer encryption, ensuring the security of your data.
- **Zero-Trust Security**: The client implements a zero-trust security model, meaning it does not inherently trust any entities. This reduces the potential attack surface.
- **Download and Upload**: The client allows you to download and upload files to and from the ktCloud service.
- **API Interaction**: The client provides a way to interact with the ktCloud API, allowing you to perform various operations on the ktCloud service.

## Installation

To get the ktCloud CLI client, you need to have Go installed on your machine. Once Go is installed, you can download and install the ktCloud CLI client using the `go get` command:

```bash
go get github.com/kt-soft-dev/kt-cli
```

For ready binaries see releases page.

## Making API request

To make an API request, you can use -act.method flag to specify the method of the request. For example:

```bash
ktcloud -act.method=test.test
```

Output will be like this:

```bash
2024/04/01 06:37:17 {"ok":true}
```

Parameters can be passed using **-params** flag.
Value should be a string with space-separated key-value pairs.

For example:

```bash
ktcloud -act.method=test.test -params="param1=value1 param2=value2"'
```
In this example params are just stubs and will be ignored. To get known about parameters for specific method, please read the API documentation.
## Output modes
Output can be displayed in different modes. By default, output is displayed in usual **log.Println** format like this:
```bash
2024/04/01 06:37:17 {"ok":true}
```
**-output** flag can be used to specify output mode. Currently supported modes are:
- **0** - log with timestamp
- **1** - plain log (simple output, no timestamp)
- **2** - just like plain log but without new line at the end
## Contributing
Contributions are welcome. Please feel free to submit a pull request or open an issue on the GitHub repository.
## License
See the `LICENSE` file.
19 changes: 19 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: '3'

tasks:
debug:
cmds:
- go run main.go -debug

test:
cmds:
- go test ./...

build-all:
cmds:
- mkdir -p bin
- GOOS=linux GOARCH=amd64 go build -o bin/ktcloud_linux_amd64
- GOOS=linux GOARCH=386 go build -o bin/ktcloud_linux_386
- GOOS=darwin GOARCH=amd64 go build -o bin/ktcloud_darwin_amd64
- GOOS=windows GOARCH=amd64 go build -o bin/ktcloud_windows_amd64.exe
- GOOS=windows GOARCH=386 go build -o bin/ktcloud_windows_386.exe
16 changes: 16 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module github.com/kt-soft-dev/kt-cli

go 1.20

require (
github.com/schollz/progressbar/v3 v3.13.1
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/rivo/uniseg v0.4.4 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/term v0.11.0 // indirect
)
31 changes: 31 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/schollz/progressbar/v3 v3.13.1 h1:o8rySDYiQ59Mwzy2FELeHY5ZARXZTVJC7iHD6PEFUiE=
github.com/schollz/progressbar/v3 v3.13.1/go.mod h1:xvrbki8kfT1fzWzBT/UZd9L6GA+jdL7HAgq2RFnO6fQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
49 changes: 49 additions & 0 deletions internal/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package internal

import (
"gopkg.in/yaml.v2"
"io/ioutil"
)

// Config represents the structure of global configuration
type Config struct {
UserID string `yaml:"user_id"`
Token string `yaml:"token"`
}

func CreateDefaultConfig() *Config {
return &Config{}
}

// LoadConfig loads the configuration from a YAML file or creates the empty one
func LoadConfig(filename string) (*Config, error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
defaultConf := CreateDefaultConfig()
_ = SaveConfig(defaultConf, filename)
return defaultConf, nil
}

var config Config
err = yaml.Unmarshal(data, &config)
if err != nil {
return nil, err
}

return &config, nil
}

// SaveConfig saves the configuration to a YAML file
func SaveConfig(config *Config, filename string) error {
data, err := yaml.Marshal(config)
if err != nil {
return err
}

err = ioutil.WriteFile(filename, data, 0644)
if err != nil {
return err
}

return nil
}
31 changes: 31 additions & 0 deletions internal/output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package internal

import (
"fmt"
"log"
)

const (
ModeLog = iota
ModePlain
ModeNoNewline
)

var printMode = ModeLog

func SetPrintMode(mode int) {
printMode = mode
}

func Print(content string, params ...interface{}) {
text := fmt.Sprintf(content, params...)

switch printMode {
case ModePlain:
fmt.Println(text)
case ModeNoNewline:
fmt.Print(text)
default:
log.Println(text)
}
}
9 changes: 9 additions & 0 deletions internal/progressbar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package internal

import "github.com/schollz/progressbar/v3"

// NewProgressBar @todo
func NewProgressBar(max int64) *progressbar.ProgressBar {
bar := progressbar.Default(max)
return bar
}
90 changes: 90 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package main

import (
"flag"
"github.com/kt-soft-dev/kt-cli/internal"
"github.com/kt-soft-dev/kt-cli/pkg"
"os"
)

func main() {
// Do not catch panics and prettify them, show debug info
debug := flag.Bool("debug", false, "Enable debug mode")

// Global flags
configFilename := flag.String("config", "config.yaml", "Set config file path")
printMode := flag.Int("output", internal.ModeLog, "Output mode (0 - log with timestamp, 1 - plain log, 2 - no newline)")
noConfigSave := flag.Bool("no-save", false, "Do not save the config file on exit (including token)")
auth := flag.String("token", "", "Set auth token for future requests (will be saved in config file)")
pretty := flag.Bool("pretty", false, "Pretty-print JSON responses")

// Actions to perform
method := flag.String("act.method", "", "Call API method")
params := flag.String("params", "", "Set API method key=value parameters separated by space (format: k=v k=v k=v...)")
flag.Parse()

internal.SetPrintMode(*printMode)

// When not in debug mode, catch panics and print them in more user-friendly way like error messages
if !*debug {
defer func() {
if err := recover(); err != nil {
internal.Print("%v", err)
os.Exit(1)
}
}()
}

// globalContext, cancel := context.WithCancel(context.Background())
config, err := internal.LoadConfig(*configFilename)
if err != nil {
internal.Print("Failed to load config file and/or create a new one. Exiting...")
os.Exit(1)
}

if !*noConfigSave {
// Save the config file on exit. It could change during the program execution in some cases
defer func() {
err = internal.SaveConfig(config, *configFilename)
if err != nil {
internal.Print("Failed to save config file")
}
}()
}

if *auth != "" {
config.Token = *auth
}

switch {
case *method != "":
paramsMap := pkg.ParseKeyValues(*params)
resp, err := pkg.ApiRequest(config.Token, *method, paramsMap)
err = pkg.GetActualError(resp, err)
if err != nil {
internal.Print(err.Error())
return
}

internal.Print(pkg.JsonToString(resp.Result, *pretty))

default:
// Usually in case of empty method and non-empty token we should take this as a request to validate and store the token
if *auth != "" {
id, err := pkg.CheckToken(*auth)
if err != nil {
internal.Print("Failed to check token")
return
}

internal.Print("Logged in as user id %s", id)
config.Token = *auth
config.UserID = id
// Config will be saved because of the defer above (if no -no-save flag is set)
return
}

flag.PrintDefaults()
os.Exit(0)
}
}
Loading

0 comments on commit aeadfcc

Please sign in to comment.