Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrContinue parser error continue input ErrContinue = errors.New("<continue input>") // ErrQuit parser error quit session ErrQuit = errors.New("<quit session>") )
var AlertCmd = &cobra.Command{ Use: "alert", Short: "Manage alerts", Long: "Manage alerts", SilenceUsage: false, }
AlertCmd skydive alert root command
var AlertCreate = &cobra.Command{ Use: "create", Short: "Create alert", Long: "Create alert", Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } alert := types.NewAlert() alert.Name = alertName alert.Description = alertDescription alert.Expression = alertExpression alert.Trigger = alertTrigger alert.Action = alertAction if err := validator.Validate(alert); err != nil { exitOnError(err) } if err := client.Create("alert", &alert, nil); err != nil { exitOnError(err) } printJSON(&alert) }, }
AlertCreate skydive alert creates command
var AlertDelete = &cobra.Command{ Use: "delete [alert]", Short: "Delete alert", Long: "Delete alert", PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } for _, id := range args { if err := client.Delete("alert", id); err != nil { logging.GetLogger().Error(err) } } }, }
AlertDelete skydive alert delete command
var AlertGet = &cobra.Command{ Use: "get [alert]", Short: "Display alert", Long: "Display alert", PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { var alert types.Alert client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.Get("alert", args[0], &alert); err != nil { exitOnError(err) } printJSON(&alert) }, }
AlertGet skydive alert get command
var AlertList = &cobra.Command{ Use: "list", Short: "List alerts", Long: "List alerts", Run: func(cmd *cobra.Command, args []string) { var alerts map[string]types.Alert client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.List("alert", &alerts); err != nil { exitOnError(err) } printJSON(alerts) }, }
AlertList skydive alert list command
var (
AuthenticationOpts shttp.AuthenticationOpts
)
AuthenticationOpts Authentication options
var CaptureCmd = &cobra.Command{ Use: "capture", Short: "Manage captures", Long: "Manage captures", SilenceUsage: false, }
CaptureCmd skydive capture root command
var CaptureCreate = &cobra.Command{ Use: "create", Short: "Create capture", Long: "Create capture", PreRun: func(cmd *cobra.Command, args []string) { if nodeTID != "" { if gremlinQuery != "" { exitOnError(errors.New("Options --node and --gremlin are exclusive")) } gremlinQuery = fmt.Sprintf("g.V().Has('TID', '%s')", nodeTID) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } var layers flow.ExtraLayers if err := layers.Parse(extraLayers...); err != nil { exitOnError(err) } capture := api.NewCapture(gremlinQuery, bpfFilter) capture.Name = captureName capture.Description = captureDescription capture.Type = captureType capture.Port = port capture.SamplingRate = samplingRate capture.PollingInterval = pollingInterval capture.HeaderSize = headerSize capture.ExtraTCPMetric = extraTCPMetric capture.IPDefrag = ipDefrag capture.ReassembleTCP = reassembleTCP capture.LayerKeyMode = layerKeyMode capture.RawPacketLimit = rawPacketLimit capture.ExtraLayers = layers capture.Target = target capture.TargetType = targetType if err := validator.Validate(capture); err != nil { exitOnError(err) } var createOpts *http.CreateOptions if captureTTL != 0 { createOpts = &http.CreateOptions{ TTL: time.Duration(captureTTL) * time.Millisecond, } } if err := client.Create("capture", &capture, createOpts); err != nil { exitOnError(err) } printJSON(&capture) }, }
CaptureCreate skydive capture creates command
var CaptureDelete = &cobra.Command{ Use: "delete [capture]", Short: "Delete capture", Long: "Delete capture", PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } for _, id := range args { if err := client.Delete("capture", id); err != nil { logging.GetLogger().Error(err) } } }, }
CaptureDelete skydive capture delete command
var CaptureGet = &cobra.Command{ Use: "get [capture]", Short: "Display capture", Long: "Display capture", PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { var capture api.Capture client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.Get("capture", args[0], &capture); err != nil { exitOnError(err) } printJSON(&capture) }, }
CaptureGet skydive capture get command
var CaptureList = &cobra.Command{ Use: "list", Short: "List captures", Long: "List captures", Run: func(cmd *cobra.Command, args []string) { var captures map[string]api.Capture client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.List("capture", &captures); err != nil { exitOnError(err) } printJSON(captures) }, }
CaptureList skydive capture list command
var ClientCmd = &cobra.Command{ Use: "client", Short: "Skydive client", Long: "Skydive client", SilenceUsage: true, PersistentPreRun: func(cmd *cobra.Command, args []string) { cmd.Root().PersistentPreRun(cmd.Root(), args) if analyzerAddr != "" { config.Set("analyzers", analyzerAddr) } else { config.SetDefault("analyzers", []string{"localhost:8082"}) } }, }
ClientCmd describe the skydive client root command
var EdgeRuleCmd = &cobra.Command{ Use: "edge-rule", Short: "edge-rule", Long: "edge-rule", SilenceUsage: false, }
EdgeRuleCmd skydive edge rule root command
var EdgeRuleCreate = &cobra.Command{ Use: "create", Short: "create", Long: "create", SilenceUsage: false, PreRun: func(cmd *cobra.Command, args []string) { if relationType == "" { logging.GetLogger().Error("--relationtype is a required parameter") os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } m, err := usertopology.DefToMetadata(metadata, graph.Metadata{}) if err != nil { exitOnError(err) } m["RelationType"] = relationType edge := &api.EdgeRule{ Name: name, Description: description, Src: src, Dst: dst, Metadata: m, } if err = validator.Validate(edge); err != nil { exitOnError(fmt.Errorf("Error while validating edge rule: %s", err)) } if err = client.Create("edgerule", &edge, nil); err != nil { exitOnError(err) } printJSON(edge) }, }
EdgeRuleCreate skydive edge create command
var EdgeRuleDelete = &cobra.Command{ Use: "delete", Short: "delete", Long: "delete", SilenceUsage: false, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } for _, id := range args { if err := client.Delete("edgerule", id); err != nil { logging.GetLogger().Error(err.Error()) } } }, }
EdgeRuleDelete skydive edge delete command
var EdgeRuleGet = &cobra.Command{ Use: "get", Short: "get", Long: "get", SilenceUsage: false, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { var edge api.EdgeRule client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.Get("edgerule", args[0], &edge); err != nil { exitOnError(err) } printJSON(&edge) }, }
EdgeRuleGet skydive edge get command
var EdgeRuleList = &cobra.Command{ Use: "list", Short: "list", Long: "list", SilenceUsage: false, Run: func(cmd *cobra.Command, args []string) { var edges map[string]api.EdgeRule client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.List("edgerule", &edges); err != nil { exitOnError(err) } printJSON(edges) }, }
EdgeRuleList skydive edge list command
var NodeRuleCmd = &cobra.Command{ Use: "node-rule", Short: "node-rule", Long: "node-rule", SilenceUsage: false, }
NodeRuleCmd skydive node rule root command
var NodeRuleCreate = &cobra.Command{ Use: "create", Short: "create", Long: "create", SilenceUsage: false, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } m, err := usertopology.DefToMetadata(metadata, graph.Metadata{}) if err != nil { exitOnError(err) } if action == "create" { if nodeName == "" || nodeType == "" { exitOnError(errors.New("Both --node-name and --node-type are required for 'create' node rules")) } m["Name"] = nodeName m["Type"] = nodeType } node := &api.NodeRule{ Name: name, Description: description, Metadata: m, Query: query, Action: action, } if err = validator.Validate(node); err != nil { exitOnError(fmt.Errorf("Error while validating node rule: %s", err)) } if err = client.Create("noderule", &node, nil); err != nil { exitOnError(err) } printJSON(node) }, }
NodeRuleCreate skydive node create command
var NodeRuleDelete = &cobra.Command{ Use: "delete", Short: "delete", Long: "delete", SilenceUsage: false, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { logging.GetLogger().Error(err.Error()) os.Exit(1) } for _, id := range args { if err := client.Delete("noderule", id); err != nil { logging.GetLogger().Error(err.Error()) } } }, }
NodeRuleDelete skydive node delete command
var NodeRuleGet = &cobra.Command{ Use: "get", Short: "get", Long: "get", SilenceUsage: false, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { var node api.NodeRule client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { logging.GetLogger().Error(err.Error()) os.Exit(1) } if err := client.Get("noderule", args[0], &node); err != nil { logging.GetLogger().Error(err.Error()) os.Exit(1) } printJSON(&node) }, }
NodeRuleGet skydive node get command
var NodeRuleList = &cobra.Command{ Use: "list", Short: "list", Long: "list", SilenceUsage: false, Run: func(cmd *cobra.Command, args []string) { var nodes map[string]api.NodeRule client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { logging.GetLogger().Error(err.Error()) os.Exit(1) } if err := client.List("noderule", &nodes); err != nil { logging.GetLogger().Error(err.Error()) os.Exit(1) } printJSON(nodes) }, }
NodeRuleList skydive node list command
var PacketInjectionCreate = &cobra.Command{ Use: "create", Short: "create packet injection", Long: "create packet injection", SilenceUsage: false, Run: func(cmd *cobra.Command, args []string) { crudClient, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } request, err := injector.GetPacketInjectRequest() if err != nil { exitOnError(err) } packet := &api.PacketInjection{ Src: srcNode, Dst: dstNode, SrcPort: request.SrcPort, DstPort: request.DstPort, Type: request.Type, Payload: request.Payload, Pcap: request.Pcap, ICMPID: request.ICMPID, Count: request.Count, Interval: request.Interval, Increment: request.Increment, IncrementPayload: request.IncrementPayload, TTL: request.TTL, } if request.SrcIP != nil { packet.SrcIP = request.SrcIP.String() } if request.DstIP != nil { packet.DstIP = request.DstIP.String() } if request.SrcMAC != nil { packet.SrcMAC = request.SrcMAC.String() } if request.DstMAC != nil { packet.DstMAC = request.DstMAC.String() } if err = validator.Validate(packet); err != nil { exitOnError(err) } ttl := 5 * time.Second if packet.Interval != 0 { ttl = time.Duration(packet.Interval*packet.Count)*time.Millisecond + 5*time.Second } createOpts := &http.CreateOptions{TTL: ttl} if err := crudClient.Create("injectpacket", &packet, createOpts); err != nil { exitOnError(err) } printJSON(packet) }, }
PacketInjectionCreate describes the command to create a packet injection
var PacketInjectionDelete = &cobra.Command{ Use: "delete [injection]", Short: "Delete injection", Long: "Delete packet injection", PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } for _, id := range args { if err := client.Delete("injectpacket", id); err != nil { logging.GetLogger().Error(err) } } }, }
PacketInjectionDelete describes the command to delete a packet injection
var PacketInjectionGet = &cobra.Command{ Use: "get", Short: "get packet injection", Long: "get packet injection", PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { var injection api.PacketInjection client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.Get("injectpacket", args[0], &injection); err != nil { exitOnError(err) } printJSON(&injection) }, }
PacketInjectionGet describes the command to retrieve a packet injection
var PacketInjectionList = &cobra.Command{ Use: "list", Short: "list packet injections", Long: "list packet injections", Run: func(cmd *cobra.Command, args []string) { var injections map[string]api.PacketInjection client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.List("injectpacket", &injections); err != nil { exitOnError(err) } printJSON(injections) }, }
PacketInjectionList describes the command to list all the packet injections
var PacketInjectorCmd = &cobra.Command{ Use: "injection", Short: "Inject packets", Long: "Inject packets", Aliases: []string{"inject-packet"}, SilenceUsage: false, }
PacketInjectorCmd skydive inject-packet root command
var PcapCmd = &cobra.Command{ Use: "pcap", Short: "Import flows from PCAP file", Long: "Import flows from PCAP file", PreRun: func(cmd *cobra.Command, args []string) { if pcapTrace == "" { logging.GetLogger().Error("You need to specify a PCAP file") cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } file, err := os.Open(pcapTrace) if err != nil { exitOnError(err) } defer file.Close() resp, err := client.Request("POST", "pcap", file, nil) if err != nil { exitOnError(err) } if resp.StatusCode == http.StatusAccepted { fmt.Printf("%s was successfully imported\n", pcapTrace) } else { content, _ := ioutil.ReadAll(resp.Body) exitOnError(fmt.Errorf("Failed to import %s: %s", pcapTrace, string(content))) } }, }
PcapCmd skydive pcap root command
var QueryCmd = &cobra.Command{ Use: "query [gremlin]", Short: "Issue Gremlin queries", Long: "Issue Gremlin queries", PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 || args[0] == "" { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { gremlinQuery = args[0] queryHelper := client.NewGremlinQueryHelper(&AuthenticationOpts) switch outputFormat { case "json": data, err := queryHelper.Query(gremlinQuery) if err != nil { exitOnError(err) } var out bytes.Buffer json.Indent(&out, data, "", "\t") out.WriteTo(os.Stdout) case "dot": header := make(http.Header) header.Set("Accept", "vnd.graphviz") resp, err := queryHelper.Request(gremlinQuery, header) if err != nil { exitOnError(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { data, _ := ioutil.ReadAll(resp.Body) exitOnError(fmt.Errorf("%s: %s", resp.Status, string(data))) } bufio.NewReader(resp.Body).WriteTo(os.Stdout) case "pcap": header := make(http.Header) header.Set("Accept", "vnd.tcpdump.pcap") resp, err := queryHelper.Request(gremlinQuery, header) if err != nil { exitOnError(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { data, _ := ioutil.ReadAll(resp.Body) exitOnError(fmt.Errorf("%s: %s", resp.Status, string(data))) } bufio.NewReader(resp.Body).WriteTo(os.Stdout) default: logging.GetLogger().Errorf("Invalid output format %s", outputFormat) os.Exit(1) } }, }
QueryCmd skydive topology query command
var ShellCmd = &cobra.Command{ Use: "shell", Short: "Shell Command Line Interface", Long: "Skydive Shell Command Line Interface, yet another shell", SilenceUsage: false, Run: func(cmd *cobra.Command, args []string) { s, err := NewSession() if err != nil { logging.GetLogger().Errorf("Error while creating session: %s", err) os.Exit(1) } defer s.Close() if shellScript != "" { result := s.runtime.RunScript(shellScript) if result.IsDefined() { logging.GetLogger().Errorf("Error while executing script %s: %s", shellScript, result.String()) } } s.prompt() if err := s.saveHistory(); err != nil { logging.GetLogger().Errorf("Error while saving history: %s", err) } }, }
ShellCmd skydive shell root command
var StatusCmd = &cobra.Command{ Use: "status", Short: "Show analyzer status", Long: "Show analyzer status", Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } resp, err := client.Request("GET", "status", nil, nil) if err != nil { exitOnError(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { data, _ := ioutil.ReadAll(resp.Body) exitOnError(fmt.Errorf("Failed to get status, %s: %s", resp.Status, data)) } var status analyzer.Status if err := common.JSONDecode(resp.Body, &status); err != nil { exitOnError(err) } printJSON(&status) }, }
StatusCmd implents the skydive 'status' command that return the status of an analyzer by quering its API
var TopologyCmd = &cobra.Command{ Use: "topology", Short: "Request on topology", Long: "Request on topology", SilenceUsage: false, }
TopologyCmd skydive topology root command
var TopologyExport = &cobra.Command{ Use: "export", Short: "export topology", Long: "export topology", Run: func(cmd *cobra.Command, args []string) { QueryCmd.Run(cmd, []string{"G"}) }, }
TopologyExport skydive topology export command
var TopologyImport = &cobra.Command{ Use: "import", Short: "import topology", Long: "import topology", Run: func(cmd *cobra.Command, args []string) { sa, err := config.GetOneAnalyzerServiceAddress() if err != nil { exitOnError(err) } url := config.GetURL("ws", sa.Addr, sa.Port, "/ws/publisher") opts := websocket.ClientOpts{AuthOpts: &AuthenticationOpts, Headers: http.Header{}} opts.Headers.Add("X-Persistence-Policy", string(hub.Persistent)) client, err := config.NewWSClient(common.UnknownService, url, opts) if err != nil { exitOnError(err) } if err := client.Connect(); err != nil { exitOnError(err) } go client.Run() defer func() { client.Flush() client.StopAndWait() }() content, err := ioutil.ReadFile(filename) if err != nil { exitOnError(err) } els := []*graph.Elements{} if err := json.Unmarshal(content, &els); err != nil { exitOnError(err) } if len(els) != 1 { exitOnError(errors.New("Invalid graph format")) } for _, node := range els[0].Nodes { msg := gws.NewStructMessage(gws.NodeAddedMsgType, node) if err := client.SendMessage(msg); err != nil { exitOnError(fmt.Errorf("Failed to send message: %s", err)) } } for _, edge := range els[0].Edges { msg := gws.NewStructMessage(gws.EdgeAddedMsgType, edge) if err := client.SendMessage(msg); err != nil { exitOnError(fmt.Errorf("Failed to send message: %s", err)) } } }, }
TopologyImport skydive topology import command
var TopologyRequest = &cobra.Command{ Use: "query", Short: "query topology [deprecated: use 'client query' instead]", Long: "query topology [deprecated: use 'client query' instead]", Run: func(cmd *cobra.Command, args []string) { fmt.Fprintln(os.Stderr, "The 'client topology query' command is deprecated. Please use 'client query' instead") QueryCmd.Run(cmd, []string{gremlinQuery}) }, }
TopologyRequest skydive topology query command
var WorkflowCall = &cobra.Command{ Use: "call workflow", Short: "Call workflow", Long: "Call workflow", SilenceUsage: false, PreRun: func(cmd *cobra.Command, args []string) { if len(args) < 1 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { var workflowCall types.WorkflowCall var result interface{} client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } params := make([]interface{}, len(args)-1) for i, arg := range args[1:] { params[i] = arg } workflowCall.Params = params s, err := json.Marshal(workflowCall) if err != nil { exitOnError(err) } contentReader := bytes.NewReader(s) resp, err := client.Request("POST", "workflow/"+args[0]+"/call", contentReader, nil) if err != nil { exitOnError(err) } defer resp.Body.Close() if err := common.JSONDecode(resp.Body, &result); err != nil { exitOnError(err) } printJSON(result) }, }
WorkflowCall describes the "workflow call" command
var WorkflowCmd = &cobra.Command{ Use: "workflow", Short: "Manage workflows", Long: "Manage workflows", SilenceUsage: false, }
WorkflowCmd describe the "workflow" root command
var WorkflowCreate = &cobra.Command{ Use: "create", Short: "create workflow", Long: "create workflow", SilenceUsage: false, PreRun: func(cmd *cobra.Command, args []string) { }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } workflow, err := loadWorklow(workflowPath) if err != nil { exitOnError(err) } if err := client.Create("workflow", &workflow, nil); err != nil { exitOnError(err) } printJSON(workflow) }, }
WorkflowCreate describes the "workflow create" command
var WorkflowDelete = &cobra.Command{ Use: "delete", Short: "delete workflow", Long: "delete workflow", SilenceUsage: false, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() os.Exit(1) } }, Run: func(cmd *cobra.Command, args []string) { client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } for _, id := range args { if err := client.Delete("workflow", id); err != nil { logging.GetLogger().Error(err) } } }, }
WorkflowDelete describes the "workflow delete" command
var WorkflowList = &cobra.Command{ Use: "list", Short: "List workflows", Long: "List workflows", SilenceUsage: false, Run: func(cmd *cobra.Command, args []string) { var workflows map[string]types.Workflow client, err := client.NewCrudClientFromConfig(&AuthenticationOpts) if err != nil { exitOnError(err) } if err := client.List("workflow", &workflows); err != nil { exitOnError(err) } printJSON(workflows) }, }
WorkflowList describes the "workflow list" command
Functions ¶
func RegisterClientCommands ¶
RegisterClientCommands registers the 'client' CLI subcommands