This repository has been archived by the owner on Feb 26, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
job.go
209 lines (178 loc) · 5.67 KB
/
job.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package cortex
import (
"context"
"fmt"
"io"
"net/http"
"strconv"
"time"
)
const (
jobsURL = APIRoute + "/job"
)
// Task represents a Cortex task to run
type Task struct {
Data string `json:"data,omitempty"`
DataType string `json:"dataType,omitempty"`
TLP *TLP `json:"tlp,omitempty"`
PAP *PAP `json:"pap,omitempty"`
Message string `json:"message,omitempty"`
Parameters interface{} `json:"parameters,omitempty"`
}
// Type returns DataType of the task, satisfying an Observable interface
func (t *Task) Type() string {
return t.DataType
}
// Description returns Data of the task, satisfying an Observable interface
func (t *Task) Description() string {
return t.Data
}
// FileTask is a file to be analyzed
type FileTask struct {
FileTaskMeta
Reader io.Reader
FileName string
}
// FileTaskMeta represents meta data of the file observable
type FileTaskMeta struct {
DataType string `json:"dataType"`
TLP *TLP `json:"tlp,omitempty"`
PAP *PAP `json:"pap,omitempty"`
}
// Type usually returns just a string "file" for a file task
func (f *FileTask) Type() string {
return f.FileTaskMeta.DataType
}
// Description returns a file name
func (f *FileTask) Description() string {
return f.FileName
}
// Job is a sample Cortex job
type Job struct {
Task
ID string `json:"id"`
AnalyzerDefinitionID string `json:"analyzerDefinitionId"`
AnalyzerID string `json:"analyzerID"`
AnalyzerName string `json:"analyzerName"`
Status string `json:"status"`
Organization string `json:"organization"`
StartDate int64 `json:"startDate"`
EndDate int64 `json:"endDate"`
Date int64 `json:"date"`
CreatedAt int64 `json:"createdAt"`
CreatedBy string `json:"createdBy"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
UpdatedBy string `json:"updatedBy,omitempty"`
}
// Taxonomy represents a taxonomy object in a report
type Taxonomy struct {
Predicate string `json:"predicate"`
Namespace string `json:"namespace"`
Value interface{} `json:"value"`
Level string `json:"level"`
}
// Report represents a struct returned by the Cortex
type Report struct {
Job
ReportBody ReportBody `json:"report,omitempty"`
}
// Taxonomies is a shortcut to get taxonomies from the report
func (r *Report) Taxonomies() []Taxonomy {
return r.ReportBody.Summary.Taxonomies
}
// Artifact represents an artifact
type Artifact struct {
DataType string `json:"dataType"`
CreatedBy string `json:"createdBy"`
CreatedAt int64 `json:"createdAt"`
Data string `json:"data"`
TLP TLP `json:"tlp"`
PAP PAP `json:"pap"`
ID string `json:"id"`
}
// Summary is a customized report object which may have taxonomies
type Summary struct {
Taxonomies []Taxonomy `json:"taxonomies,omitempty"`
}
// ReportBody represents a report with analyzer results
type ReportBody struct {
Artifacts []Artifact `json:"artifacts,omitempty"`
FullReport interface{} `json:"full,omitempty"`
Success bool `json:"success,omitempty"`
Summary Summary `json:"summary,omitempty"`
ErrorMessage string `json:"errorMessage,omitempty"`
Input string `json:"input,omitempty"`
}
// Observable is an interface for string type artifact and file type artifact
type Observable interface {
Type() string
Description() string
}
// JobService is an interface for managing jobs
type JobService interface {
Get(context.Context, string) (*Job, *http.Response, error)
GetReport(context.Context, string) (*Report, *http.Response, error)
WaitReport(context.Context, string, time.Duration) (*Report, *http.Response, error)
Delete(context.Context, string) (*http.Response, error)
}
// JobServiceOp handles cases methods from the Cortex API
type JobServiceOp struct {
client *Client
}
// Get retrieves a Job by it's ID
func (j *JobServiceOp) Get(ctx context.Context, jobid string) (*Job, *http.Response, error) {
req, err := j.client.NewRequest("GET", fmt.Sprintf(jobsURL+"/%s", jobid), nil)
if err != nil {
return nil, nil, err
}
var job Job
resp, err := j.client.Do(ctx, req, &job)
if err != nil {
return nil, nil, err
}
return &job, resp, nil
}
// GetReport retrieves the analysis Report by a job ID
func (j *JobServiceOp) GetReport(ctx context.Context, jobid string) (*Report, *http.Response, error) {
req, err := j.client.NewRequest("GET", fmt.Sprintf(jobsURL+"/%s/report", jobid), nil)
if err != nil {
return nil, nil, err
}
var r Report
resp, err := j.client.Do(ctx, req, &r)
if err != nil {
return nil, nil, err
}
return &r, resp, nil
}
// WaitReport synchronously waits a certain job id for a specified duration of time
// and returns a report
func (j *JobServiceOp) WaitReport(ctx context.Context, jid string, d time.Duration) (*Report, *http.Response, error) {
sd := strconv.FormatFloat(d.Seconds(), 'f', 2, 64) + "seconds"
req, err := j.client.NewRequest("GET", fmt.Sprintf(jobsURL+"/%s/waitreport?atMost=%s", jid, sd), nil)
if err != nil {
return nil, nil, err
}
var report Report
resp, err := j.client.Do(ctx, req, &report)
if err != nil {
if resp != nil {
return nil, resp, err
}
return nil, nil, err
}
return &report, resp, err
}
// Delete the job from Cortex. This marks the job as Deleted. However the job's
// data is not removed from the database.
func (j *JobServiceOp) Delete(ctx context.Context, jobid string) (*http.Response, error) {
req, err := j.client.NewRequest("DELETE", fmt.Sprintf(jobsURL+"/%s", jobid), nil)
if err != nil {
return nil, err
}
resp, err := j.client.Do(ctx, req, nil)
if err != nil {
return nil, err
}
return resp, nil
}