Skip to content

Commit

Permalink
Merge pull request #109 from trickest/feat/private-scripts
Browse files Browse the repository at this point in the history
Feat/private scripts
  • Loading branch information
mhmdiaa committed Feb 6, 2024
2 parents d024161 + 6a6a7e5 commit ec7112a
Show file tree
Hide file tree
Showing 11 changed files with 408 additions and 14 deletions.
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,56 @@ trickest tools delete --name "my-tool"
| --id | string | / | ID of the tool to delete |
| --name | string | / | Name of the tool to delete |


## Scripts command
Manage private scripts

#### Example script definition
```yaml
name: hello-world
description: Write "Hello, world!" to the output
script_type: bash
script: echo "Hello, world!" | tee out/output.txt
```
#### Create a new private script
```
trickest scripts create --file script.yaml
```

| Flag | Type | Default | Description |
|----------------------|--------|----------|---------------------------------------------------------------------|
| --file | string | / | YAML file for script definition |

#### Update a private script
```
trickest scripts update --file script.yaml
```

| Flag | Type | Default | Description |
|----------------------|--------|----------|---------------------------------------------------------------------|
| --file | string | / | YAML file for script definition |

#### List private scripts
```
trickest scripts list
```

| Flag | Type | Default | Description |
|----------------------|---------|-------------|---------------------------------------------------------------------|
| --json | boolean | false | Display output in JSON format |

#### Delete a private script
```
trickest scripts delete --name "my-script"
```

| Flag | Type | Default | Description |
|----------------------|--------|----------|---------------------------------------------------------------------|
| --id | string | / | ID of the script to delete |
| --name | string | / | Name of the script to delete |


## Report Bugs / Feedback
We look forward to any feedback you want to share with us or if you're stuck with a problem you can contact us at [[email protected]](mailto:[email protected]).

Expand Down
23 changes: 23 additions & 0 deletions cmd/library/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,26 @@ func PrintTools(tools []types.Tool, jsonOutput bool) {

fmt.Println(output)
}

func PrintScripts(scripts []types.Script, jsonOutput bool) {
var output string
if jsonOutput {
data, err := json.Marshal(scripts)
if err != nil {
fmt.Println("Error marshalling project data")
return
}
output = string(data)
} else {
tree := treeprint.New()
tree.SetValue("Scripts")
for _, script := range scripts {
branch := tree.AddBranch(script.Name)
branch.AddNode(script.Script.Source)
}

output = tree.String()
}

fmt.Println(output)
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/trickest/trickest-cli/cmd/library"
"github.com/trickest/trickest-cli/cmd/list"
"github.com/trickest/trickest-cli/cmd/output"
"github.com/trickest/trickest-cli/cmd/scripts"
"github.com/trickest/trickest-cli/cmd/tools"
"github.com/trickest/trickest-cli/util"

Expand Down Expand Up @@ -54,6 +55,7 @@ func init() {
RootCmd.AddCommand(get.GetCmd)
RootCmd.AddCommand(files.FilesCmd)
RootCmd.AddCommand(tools.ToolsCmd)
RootCmd.AddCommand(scripts.ScriptsCmd)
// RootCmd.AddCommand(export.ExportCmd)
}

Expand Down
131 changes: 131 additions & 0 deletions cmd/scripts/scripts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package scripts

import (
"encoding/json"
"fmt"
"net/http"
"os"

"github.com/go-yaml/yaml"
"github.com/google/uuid"
"github.com/spf13/cobra"
"github.com/trickest/trickest-cli/client/request"
"github.com/trickest/trickest-cli/types"
"github.com/trickest/trickest-cli/util"
)

var ScriptsCmd = &cobra.Command{
Use: "scripts",
Short: "Manage private scripts",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}

func init() {
ScriptsCmd.SetHelpFunc(func(command *cobra.Command, strings []string) {
_ = ScriptsCmd.Flags().MarkHidden("workflow")
_ = ScriptsCmd.Flags().MarkHidden("project")
_ = ScriptsCmd.Flags().MarkHidden("space")
_ = ScriptsCmd.Flags().MarkHidden("url")

command.Root().HelpFunc()(command, strings)
})
}

func ListPrivateScripts(name string) ([]types.Script, error) {
endpoint := fmt.Sprintf("script/?vault=%s", util.GetVault())
if name != "" {
endpoint += "&search=" + name
} else {
endpoint += "&page_size=100"
}

resp := request.Trickest.Get().Do(endpoint)
if resp == nil || resp.Status() != http.StatusOK {
request.ProcessUnexpectedResponse(resp)
}

var scripts types.Scripts
err := json.Unmarshal(resp.Body(), &scripts)
if err != nil {
return nil, fmt.Errorf("couldn't parse API response: %s", err)
}

return scripts.Results, nil
}

func getScriptIDByName(name string) (uuid.UUID, error) {
scripts, err := ListPrivateScripts(name)
if err != nil {
return uuid.Nil, fmt.Errorf("couldn't search for %s: %w", name, err)
}

for _, script := range scripts {
if script.Name == name {
return script.ID, nil
}
}

return uuid.Nil, fmt.Errorf("couldn't find script '%s'", name)
}

func createScriptImportRequestFromYAML(fileName string) (types.ScriptImportRequest, error) {
data, err := os.ReadFile(fileName)
if err != nil {
err = fmt.Errorf("couldn't read %s: %w", fileName, err)
return types.ScriptImportRequest{}, err
}

var scriptImportRequest types.ScriptImportRequest
err = yaml.Unmarshal(data, &scriptImportRequest)
if err != nil {
err = fmt.Errorf("couldn't parse %s: %w", fileName, err)
return types.ScriptImportRequest{}, err
}

scriptImportRequest.VaultInfo = util.GetVault()

return scriptImportRequest, nil
}

func importScript(fileName string, isUpdate bool) (string, uuid.UUID, error) {
scriptImportRequest, err := createScriptImportRequestFromYAML(fileName)
if err != nil {
return "", uuid.Nil, err
}

scriptJSON, err := json.Marshal(scriptImportRequest)
if err != nil {
return "", uuid.Nil, fmt.Errorf("couldn't encode %s: %w", fileName, err)
}

var resp *request.Response
if isUpdate {
scriptName := scriptImportRequest.Name
scriptID, err := getScriptIDByName(scriptName)
if err != nil {
return "", uuid.Nil, fmt.Errorf("couldn't import '%s': %w", scriptName, err)
}
resp = request.Trickest.Patch().Body(scriptJSON).DoF("script/%s/", scriptID.String())
} else {
resp = request.Trickest.Post().Body(scriptJSON).Do("script/")
}

if resp == nil {
return "", uuid.Nil, fmt.Errorf("couldn't import %s", fileName)
}

if resp.Status() != http.StatusCreated && resp.Status() != http.StatusOK {
request.ProcessUnexpectedResponse(resp)
}

var importedScript types.ScriptImportRequest
err = json.Unmarshal(resp.Body(), &importedScript)
if err != nil {
return "", uuid.Nil, fmt.Errorf("couldn't import %s: %w", fileName, err)
}

return importedScript.Name, *importedScript.ID, nil
}
37 changes: 37 additions & 0 deletions cmd/scripts/scriptsCreate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package scripts

import (
"fmt"
"os"

"github.com/google/uuid"
"github.com/spf13/cobra"
)

var file string

var scriptsCreateCmd = &cobra.Command{
Use: "create",
Short: "Create a new private script",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
name, id, err := createScript(file)
if err != nil {
fmt.Printf("Error: %s\n", err)
os.Exit(1)
}

fmt.Printf("Succesfuly imported %s (%s)\n", name, id)
},
}

func init() {
ScriptsCmd.AddCommand(scriptsCreateCmd)

scriptsCreateCmd.Flags().StringVar(&file, "file", "", "YAML file for script definition")
scriptsCreateCmd.MarkFlagRequired("file")
}

func createScript(fileName string) (string, uuid.UUID, error) {
return importScript(fileName, false)
}
64 changes: 64 additions & 0 deletions cmd/scripts/scriptsDelete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package scripts

import (
"fmt"
"net/http"
"os"

"github.com/spf13/cobra"
"github.com/trickest/trickest-cli/client/request"
)

var (
scriptID string
scriptName string
)

var scriptsDeleteCmd = &cobra.Command{
Use: "delete",
Short: "Delete a private script",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
if scriptName == "" && scriptID == "" {
cmd.Help()
return
}

if scriptName != "" {
id, err := getScriptIDByName(scriptName)
if err != nil {
fmt.Printf("Error: %s\n", err)
os.Exit(1)
}
scriptID = id.String()
}

err := deleteScript(scriptID)
if err != nil {
fmt.Printf("Error: %s\n", err)
os.Exit(1)
}

fmt.Printf("Succesfuly deleted %s\n", scriptID)
},
}

func init() {
ScriptsCmd.AddCommand(scriptsDeleteCmd)

scriptsDeleteCmd.Flags().StringVar(&scriptID, "id", "", "ID of the script to delete")
scriptsDeleteCmd.Flags().StringVar(&scriptName, "name", "", "Name of the script to delete")
}

func deleteScript(scriptID string) error {
resp := request.Trickest.Delete().DoF("script/%s/", scriptID)
if resp == nil {
return fmt.Errorf("couldn't delete %s: invalid response", scriptID)
}

if resp.Status() == http.StatusNoContent {
return nil
} else {
return fmt.Errorf("couldn't delete %s: unexpected status code (%d)", scriptID, resp.Status())
}
}
44 changes: 44 additions & 0 deletions cmd/scripts/scriptsList.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package scripts

import (
"fmt"
"os"

"github.com/spf13/cobra"
"github.com/trickest/trickest-cli/cmd/library"
)

var jsonOutput bool

var scriptsListCmd = &cobra.Command{
Use: "list",
Short: "List private scripts",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
err := listScripts(jsonOutput)
if err != nil {
fmt.Printf("Error: %s\n", err)
os.Exit(1)
}
},
}

func init() {
ScriptsCmd.AddCommand(scriptsListCmd)

scriptsListCmd.Flags().BoolVar(&jsonOutput, "json", false, "Display output in JSON format")
}

func listScripts(jsonOutput bool) error {
scripts, err := ListPrivateScripts("")
if err != nil {
return fmt.Errorf("couldn't list private scripts: %w", err)
}

if len(scripts) == 0 {
return fmt.Errorf("couldn't find any private scripts. Did you mean `library list scripts`?")
}

library.PrintScripts(scripts, jsonOutput)
return nil
}
Loading

0 comments on commit ec7112a

Please sign in to comment.