Skip to content

Commit b4f7fe9

Browse files
feat(workflows): Add get workflowruns command (#76)
* feat(workflows): Add `get workflowruns` command Signed-off-by: PrayagS <prayagsavsani@gmail.com> * Added error message Co-authored-by: Saranya Jena <saranya.jena@harness.io>
1 parent eb54bb6 commit b4f7fe9

File tree

3 files changed

+303
-0
lines changed

3 files changed

+303
-0
lines changed

pkg/apis/workflow.go

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,187 @@ func CreateWorkflow(requestData model.ChaosWorkFlowRequest, cred types.Credentia
102102
return ChaosWorkflowCreationData{}, err
103103
}
104104
}
105+
106+
type WorkflowListData struct {
107+
Errors []struct {
108+
Message string `json:"message"`
109+
Path []string `json:"path"`
110+
} `json:"errors"`
111+
Data WorkflowList `json:"data"`
112+
}
113+
114+
type WorkflowList struct {
115+
ListWorkflowDetails model.ListWorkflowsResponse `json:"listWorkflows"`
116+
}
117+
118+
type GetChaosWorkFlowsGraphQLRequest struct {
119+
Query string `json:"query"`
120+
Variables struct {
121+
GetChaosWorkFlowsRequest model.ListWorkflowsRequest `json:"request"`
122+
} `json:"variables"`
123+
}
124+
125+
// GetWorkflowList sends GraphQL API request for fetching a list of workflows.
126+
func GetWorkflowList(in model.ListWorkflowsRequest, cred types.Credentials) (WorkflowListData, error) {
127+
128+
var gqlReq GetChaosWorkFlowsGraphQLRequest
129+
var err error
130+
131+
gqlReq.Query = `query listWorkflows($request: ListWorkflowsRequest!) {
132+
listWorkflows(request: $request) {
133+
totalNoOfWorkflows
134+
workflows {
135+
workflowID
136+
workflowManifest
137+
cronSyntax
138+
clusterName
139+
workflowName
140+
workflowDescription
141+
weightages {
142+
experimentName
143+
weightage
144+
}
145+
isCustomWorkflow
146+
updatedAt
147+
createdAt
148+
projectID
149+
clusterID
150+
clusterType
151+
isRemoved
152+
lastUpdatedBy
153+
}
154+
}
155+
}`
156+
gqlReq.Variables.GetChaosWorkFlowsRequest = in
157+
158+
query, err := json.Marshal(gqlReq)
159+
if err != nil {
160+
return WorkflowListData{}, err
161+
}
162+
163+
resp, err := SendRequest(
164+
SendRequestParams{
165+
Endpoint: cred.Endpoint + utils.GQLAPIPath,
166+
Token: cred.Token,
167+
},
168+
query,
169+
string(types.Post),
170+
)
171+
if err != nil {
172+
return WorkflowListData{}, err
173+
}
174+
175+
bodyBytes, err := ioutil.ReadAll(resp.Body)
176+
defer resp.Body.Close()
177+
if err != nil {
178+
return WorkflowListData{}, err
179+
}
180+
181+
if resp.StatusCode == http.StatusOK {
182+
var workflowList WorkflowListData
183+
err = json.Unmarshal(bodyBytes, &workflowList)
184+
if err != nil {
185+
return WorkflowListData{}, err
186+
}
187+
188+
if len(workflowList.Errors) > 0 {
189+
return WorkflowListData{}, errors.New(workflowList.Errors[0].Message)
190+
}
191+
192+
return workflowList, nil
193+
} else {
194+
return WorkflowListData{}, err
195+
}
196+
}
197+
198+
type WorkflowRunsListData struct {
199+
Errors []struct {
200+
Message string `json:"message"`
201+
Path []string `json:"path"`
202+
} `json:"errors"`
203+
Data WorkflowRunsList `json:"data"`
204+
}
205+
206+
type WorkflowRunsList struct {
207+
ListWorkflowRunsDetails model.ListWorkflowRunsResponse `json:"listWorkflowRuns"`
208+
}
209+
210+
type GetChaosWorkFlowRunsGraphQLRequest struct {
211+
Query string `json:"query"`
212+
Variables struct {
213+
GetChaosWorkFlowRunsRequest model.ListWorkflowRunsRequest `json:"request"`
214+
} `json:"variables"`
215+
}
216+
217+
// GetWorkflowRunsList sends GraphQL API request for fetching a list of workflow runs.
218+
func GetWorkflowRunsList(in model.ListWorkflowRunsRequest, cred types.Credentials) (WorkflowRunsListData, error) {
219+
220+
var gqlReq GetChaosWorkFlowRunsGraphQLRequest
221+
var err error
222+
223+
gqlReq.Query = `query listWorkflowRuns($request: ListWorkflowRunsRequest!) {
224+
listWorkflowRuns(request: $request) {
225+
totalNoOfWorkflowRuns
226+
workflowRuns {
227+
workflowRunID
228+
workflowID
229+
clusterName
230+
workflowName
231+
projectID
232+
clusterID
233+
clusterType
234+
isRemoved
235+
lastUpdated
236+
phase
237+
resiliencyScore
238+
experimentsPassed
239+
experimentsFailed
240+
experimentsAwaited
241+
experimentsStopped
242+
experimentsNa
243+
totalExperiments
244+
executedBy
245+
}
246+
}
247+
}`
248+
gqlReq.Variables.GetChaosWorkFlowRunsRequest = in
249+
250+
query, err := json.Marshal(gqlReq)
251+
if err != nil {
252+
return WorkflowRunsListData{}, err
253+
}
254+
255+
resp, err := SendRequest(
256+
SendRequestParams{
257+
Endpoint: cred.Endpoint + utils.GQLAPIPath,
258+
Token: cred.Token,
259+
},
260+
query,
261+
string(types.Post),
262+
)
263+
if err != nil {
264+
return WorkflowRunsListData{}, err
265+
}
266+
267+
bodyBytes, err := ioutil.ReadAll(resp.Body)
268+
defer resp.Body.Close()
269+
if err != nil {
270+
return WorkflowRunsListData{}, err
271+
}
272+
273+
if resp.StatusCode == http.StatusOK {
274+
var workflowRunsList WorkflowRunsListData
275+
err = json.Unmarshal(bodyBytes, &workflowRunsList)
276+
if err != nil {
277+
return WorkflowRunsListData{}, err
278+
}
279+
280+
if len(workflowRunsList.Errors) > 0 {
281+
return WorkflowRunsListData{}, errors.New(workflowRunsList.Errors[0].Message)
282+
}
283+
284+
return workflowRunsList, nil
285+
} else {
286+
return WorkflowRunsListData{}, errors.New("Error while fetching the chaos workflow runs")
287+
}
288+
}

pkg/cmd/get/get.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ var GetCmd = &cobra.Command{
2929
#get list of agents within the project
3030
litmusctl get agents --project-id=""
3131
32+
#get list of chaos workflows
33+
litmusctl get workflows --project-id=""
34+
35+
#get list of chaos workflow runs
36+
litmusctl get workflowruns --project-id=""
37+
3238
Note: The default location of the config file is $HOME/.litmusconfig, and can be overridden by a --config flag
3339
`,
3440
}

pkg/cmd/get/workflowruns.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
Copyright © 2021 The LitmusChaos Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package get
17+
18+
import (
19+
"fmt"
20+
"os"
21+
"strconv"
22+
"text/tabwriter"
23+
"time"
24+
25+
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/graph/model"
26+
"github.com/litmuschaos/litmusctl/pkg/apis"
27+
"github.com/litmuschaos/litmusctl/pkg/utils"
28+
"github.com/spf13/cobra"
29+
)
30+
31+
// workflowRunsCmd represents the workflow runs command
32+
var workflowRunsCmd = &cobra.Command{
33+
Use: "workflowruns",
34+
Short: "Display list of workflow runs within the project",
35+
Long: `Display list of workflow runs within the project`,
36+
Run: func(cmd *cobra.Command, args []string) {
37+
credentials, err := utils.GetCredentials(cmd)
38+
utils.PrintError(err)
39+
40+
var listWorkflowRunsRequest model.ListWorkflowRunsRequest
41+
42+
listWorkflowRunsRequest.ProjectID, err = cmd.Flags().GetString("project-id")
43+
utils.PrintError(err)
44+
45+
if listWorkflowRunsRequest.ProjectID == "" {
46+
utils.White_B.Print("\nEnter the Project ID: ")
47+
fmt.Scanln(&listWorkflowRunsRequest.ProjectID)
48+
49+
for listWorkflowRunsRequest.ProjectID == "" {
50+
utils.Red.Println("⛔ Project ID can't be empty!!")
51+
os.Exit(1)
52+
}
53+
}
54+
55+
listAllWorkflowRuns, _ := cmd.Flags().GetBool("all")
56+
if !listAllWorkflowRuns {
57+
listWorkflowRunsRequest.Pagination = &model.Pagination{}
58+
listWorkflowRunsRequest.Pagination.Limit, _ = cmd.Flags().GetInt("count")
59+
}
60+
61+
workflowRuns, err := apis.GetWorkflowRunsList(listWorkflowRunsRequest, credentials)
62+
utils.PrintError(err)
63+
64+
output, err := cmd.Flags().GetString("output")
65+
utils.PrintError(err)
66+
67+
switch output {
68+
case "json":
69+
utils.PrintInJsonFormat(workflowRuns.Data)
70+
71+
case "yaml":
72+
utils.PrintInYamlFormat(workflowRuns.Data)
73+
74+
case "":
75+
76+
writer := tabwriter.NewWriter(os.Stdout, 4, 8, 1, '\t', 0)
77+
utils.White_B.Fprintln(writer, "WORKFLOW RUN ID\tSTATUS\tRESILIENCY SCORE\tWORKFLOW ID\tWORKFLOW NAME\tTARGET AGENT\tLAST RUN\tEXECUTED BY")
78+
79+
for _, workflowRun := range workflowRuns.Data.ListWorkflowRunsDetails.WorkflowRuns {
80+
81+
var lastUpdated string
82+
unixSecondsInt, err := strconv.ParseInt(workflowRun.LastUpdated, 10, 64)
83+
if err != nil {
84+
lastUpdated = "None"
85+
} else {
86+
lastUpdated = time.Unix(unixSecondsInt, 0).Format("January 2 2006, 03:04:05 pm")
87+
}
88+
89+
utils.White.Fprintln(
90+
writer,
91+
workflowRun.WorkflowRunID+"\t"+workflowRun.Phase+"\t"+strconv.FormatFloat(*workflowRun.ResiliencyScore, 'f', 2, 64)+"\t"+workflowRun.WorkflowID+"\t"+workflowRun.WorkflowName+"\t"+workflowRun.ClusterName+"\t"+lastUpdated+"\t"+workflowRun.ExecutedBy)
92+
}
93+
94+
if listAllWorkflowRuns || (workflowRuns.Data.ListWorkflowRunsDetails.TotalNoOfWorkflowRuns <= listWorkflowRunsRequest.Pagination.Limit) {
95+
utils.White_B.Fprintln(writer, fmt.Sprintf("\nShowing %d of %d workflow runs", workflowRuns.Data.ListWorkflowRunsDetails.TotalNoOfWorkflowRuns, workflowRuns.Data.ListWorkflowRunsDetails.TotalNoOfWorkflowRuns))
96+
} else {
97+
utils.White_B.Fprintln(writer, fmt.Sprintf("\nShowing %d of %d workflow runs", listWorkflowRunsRequest.Pagination.Limit, workflowRuns.Data.ListWorkflowRunsDetails.TotalNoOfWorkflowRuns))
98+
}
99+
100+
writer.Flush()
101+
}
102+
},
103+
}
104+
105+
func init() {
106+
GetCmd.AddCommand(workflowRunsCmd)
107+
108+
workflowRunsCmd.Flags().String("project-id", "", "Set the project-id to list workflows from the particular project. To see the projects, apply litmusctl get projects")
109+
workflowRunsCmd.Flags().Int("count", 30, "Set the count of workflow runs to display. Default value is 30")
110+
workflowRunsCmd.Flags().BoolP("all", "A", false, "Set to true to display all workflow runs")
111+
112+
workflowRunsCmd.Flags().StringP("output", "o", "", "Output format. One of:\njson|yaml")
113+
}

0 commit comments

Comments
 (0)