Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Create CRDs based on scripts directory #634

Merged
merged 1 commit into from
Dec 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/kubectl-testkube/commands/scripts.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func NewScriptsCmd() *cobra.Command {
cmd.AddCommand(scripts.NewWatchExecutionCmd())
cmd.AddCommand(scripts.NewListExecutionsCmd())
cmd.AddCommand(scripts.NewCreateScriptsCmd())
cmd.AddCommand(scripts.NewCRDScriptsCmd())
cmd.AddCommand(scripts.NewUpdateScriptsCmd())
cmd.AddCommand(scripts.NewDeleteScriptsCmd())
return cmd
Expand Down
124 changes: 124 additions & 0 deletions cmd/kubectl-testkube/commands/scripts/crd_script.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package scripts

import (
"bytes"
"fmt"
"io/fs"
"io/ioutil"
"path/filepath"
"strings"
"text/template"

"github.com/kubeshop/testkube/pkg/api/v1/client"
"github.com/kubeshop/testkube/pkg/test/script/detector"
"github.com/kubeshop/testkube/pkg/ui"
"github.com/spf13/cobra"
)

func NewCRDScriptsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "crd",
Short: "Generate scripts CRD file based on directory",
Long: `Generate scripts manifest based on directory (e.g. for ArgoCD sync based on scripts files)`,
Run: func(cmd *cobra.Command, args []string) {
ui.Logo()

var err error

if len(args) == 0 {
ui.Failf("Please pass directory")
}

dir := args[0]
firstEntry := true

err = filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
if !firstEntry {
fmt.Printf("\n\n---\n\n")
}
firstEntry = false

if err != nil {
return nil
}
if !strings.HasSuffix(path, ".json") {
return nil
}

ns, _ := cmd.Flags().GetString("namespace")
yaml, err := GenerateCRD(ns, path)
if err != nil {
return err
}

fmt.Print(yaml)

return nil
})

ui.ExitOnError("getting directory content", err)

},
}

return cmd
}

var ErrTypeNotDetected = fmt.Errorf("type not detected")

type Script struct {
Name string
Namespace string
Content string
Type string
}

// TODO find a way to use internal objects as YAML
// GenerateCRD generates CRDs based on directory of test files
func GenerateCRD(namespace, path string) (string, error) {
var scriptType string

tpl := `apiVersion: tests.testkube.io/v1
kind: Script
metadata:
name: {{ .Name }}
namespace: {{ .Namespace }}
spec:
content: "{{ .Content }}"
type: {{ .Type }}
`

content, err := ioutil.ReadFile(path)
if err != nil {
return "", err
}

// try to detect type if none passed
d := detector.NewDefaultDetector()
if detectedType, ok := d.Detect(client.UpsertScriptOptions{Content: string(content)}); ok {
ui.Debug("Detected test script type", detectedType)
scriptType = detectedType
} else {
return "", ErrTypeNotDetected
}

t := template.Must(template.New("sccript").Parse(tpl))
b := bytes.NewBuffer([]byte{})
err = t.Execute(b, Script{
Name: SanitizePath(path),
Namespace: namespace,
Content: fmt.Sprintf("%q", string(content)),
Type: scriptType,
})

return b.String(), err
}

func SanitizePath(path string) string {
name := strings.Replace(path, "/", "-", -1)
name = strings.Replace(name, "_", "-", -1)
name = strings.Replace(name, ".", "-", -1)
name = strings.TrimSuffix(name, ".json")

return name
}
11 changes: 11 additions & 0 deletions pkg/ui/printers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ func LogLine(message string) {
fmt.Printf("%s\n", DarkGray(message))
}

func Debug(message string, subMessages ...string) {
if !Verbose {
return
}
fmt.Printf("%s", DarkGray(message))
for _, sub := range subMessages {
fmt.Printf(" %s", LightGray(sub))
}
fmt.Println()
}

func Info(message string, subMessages ...string) {
fmt.Printf("%s", DarkGray(message))
for _, sub := range subMessages {
Expand Down