Skip to content

Commit

Permalink
feat(cdsctl): export template instances in yaml (#5382)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlt authored Aug 20, 2020
1 parent a5b0200 commit bcf8355
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 55 deletions.
58 changes: 3 additions & 55 deletions cli/cdsctl/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/spf13/cobra"

Expand All @@ -30,7 +29,9 @@ func template() *cobra.Command {
cli.NewCommand(templatePullCmd, templatePullRun, nil, withAllCommandModifiers()...),
cli.NewCommand(templatePushCmd, templatePushRun, nil, withAllCommandModifiers()...),
cli.NewDeleteCommand(templateDeleteCmd, templateDeleteRun, nil, withAllCommandModifiers()...),
cli.NewListCommand(templateInstancesCmd, templateInstancesRun, nil, withAllCommandModifiers()...),
cli.NewListCommand(templateInstancesCmd, templateInstancesRun, []*cobra.Command{
cli.NewCommand(templateInstancesExportCmd, templateInstancesExportRun, nil, withAllCommandModifiers()...),
}),
cli.NewCommand(templateDetachCmd, templateDetachRun, nil, withAllCommandModifiers()...),
})
}
Expand Down Expand Up @@ -239,59 +240,6 @@ func templateDeleteRun(v cli.Values) error {
return nil
}

var templateInstancesCmd = cli.Command{
Name: "instances",
Short: "Get instances for a CDS workflow template",
Example: "cdsctl template instances group-name/template-slug",
OptionalArgs: []cli.Arg{
{Name: "template-path"},
},
}

func templateInstancesRun(v cli.Values) (cli.ListResult, error) {
wt, err := getTemplateFromCLI(v)
if err != nil {
return nil, err
}
if wt == nil {
wt, err = suggestTemplate()
if err != nil {
return nil, err
}
}

wtis, err := client.TemplateGetInstances(wt.Group.Name, wt.Slug)
if err != nil {
return nil, err
}

type TemplateInstanceDisplay struct {
ID int64 `cli:"id,key"`
Created string `cli:"created"`
Project string `cli:"project"`
Workflow string `cli:"workflow"`
Params string `cli:"params"`
}

tids := make([]TemplateInstanceDisplay, len(wtis))
for i := range wtis {
tids[i].ID = wtis[i].ID
tids[i].Created = fmt.Sprintf("On %s by %s", wtis[i].FirstAudit.Created.Format(time.RFC3339),
wtis[i].FirstAudit.AuditCommon.TriggeredBy)
tids[i].Project = wtis[i].Project.Name
if wtis[i].Workflow != nil {
tids[i].Workflow = wtis[i].Workflow.Name
} else {
tids[i].Workflow = fmt.Sprintf("%s (not imported)", wtis[i].WorkflowName)
}
for k, v := range wtis[i].Request.Parameters {
tids[i].Params = fmt.Sprintf("%s%s:%s\n", tids[i].Params, k, v)
}
}

return cli.AsListResult(tids), nil
}

var templateDetachCmd = cli.Command{
Name: "detach",
Short: "Detach a workflow from template",
Expand Down
143 changes: 143 additions & 0 deletions cli/cdsctl/template_instances.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package main

import (
"fmt"
"strings"
"time"

"github.com/ovh/cds/cli"

"gopkg.in/yaml.v2"
)

var templateInstancesCmd = cli.Command{
Name: "instances",
Short: "Get instances for a CDS workflow template",
Example: "cdsctl template instances group-name/template-slug",
OptionalArgs: []cli.Arg{
{Name: "template-path"},
},
}

func templateInstancesRun(v cli.Values) (cli.ListResult, error) {
wt, err := getTemplateFromCLI(v)
if err != nil {
return nil, err
}
if wt == nil {
wt, err = suggestTemplate()
if err != nil {
return nil, err
}
}

wtis, err := client.TemplateGetInstances(wt.Group.Name, wt.Slug)
if err != nil {
return nil, err
}

type TemplateInstanceDisplay struct {
ID int64 `cli:"id,key"`
Created string `cli:"created"`
Project string `cli:"project"`
Workflow string `cli:"workflow"`
Params string `cli:"params"`
}

tids := make([]TemplateInstanceDisplay, len(wtis))
for i := range wtis {
tids[i].ID = wtis[i].ID
tids[i].Created = fmt.Sprintf("On %s by %s", wtis[i].FirstAudit.Created.Format(time.RFC3339),
wtis[i].FirstAudit.AuditCommon.TriggeredBy)
tids[i].Project = wtis[i].Project.Name
if wtis[i].Workflow != nil {
tids[i].Workflow = wtis[i].Workflow.Name
} else {
tids[i].Workflow = fmt.Sprintf("%s (not imported)", wtis[i].WorkflowName)
}
for k, v := range wtis[i].Request.Parameters {
tids[i].Params = fmt.Sprintf("%s%s:%s\n", tids[i].Params, k, v)
}
}

return cli.AsListResult(tids), nil
}

var templateInstancesExportCmd = cli.Command{
Name: "export",
Short: "Get instances for a CDS workflow template as yaml file",
Example: "cdsctl template instances group-name/template-slug",
OptionalArgs: []cli.Arg{
{Name: "template-path"},
},
Flags: []cli.Flag{
{
Type: cli.FlagArray,
Name: "filter-params",
Usage: "Specify filter on params for template like --filter-params paramKey=paramValue, wil return only instances that have params that match.",
Default: "",
},
},
}

func templateInstancesExportRun(v cli.Values) error {
wt, err := getTemplateFromCLI(v)
if err != nil {
return err
}
if wt == nil {
wt, err = suggestTemplate()
if err != nil {
return err
}
}

wtis, err := client.TemplateGetInstances(wt.Group.Name, wt.Slug)
if err != nil {
return err
}

filterParams := make(map[string]string)
filterParamPairs := v.GetStringArray("filter-params")
for _, p := range filterParamPairs {
ps := strings.Split(p, "=")
if len(ps) < 2 {
return fmt.Errorf("Invalid given param %s", ps[0])
}
filterParams[ps[0]] = strings.Join(ps[1:], "=")
}

var f templateBulkFile
f.TemplatePath = wt.Path()

for _, wti := range wtis {
filterMatch := true
for k, v := range filterParams {
if value, ok := wti.Request.Parameters[k]; !ok || value != v {
filterMatch = false
break
}
}
if !filterMatch {
continue
}

params := []string{}
for k, v := range wti.Request.Parameters {
params = append(params, k+"="+v)
}
f.Instances = append(f.Instances, templateBulkFileInstance{
WorkflowPath: wti.Project.Key + "/" + wti.Request.WorkflowName,
Parameters: params,
})
}

b, err := yaml.Marshal(f)
if err != nil {
return fmt.Errorf("unable to marshal: %v", err)
}

fmt.Println(string(b))

return nil
}

0 comments on commit bcf8355

Please sign in to comment.