nexpose 7.2.1 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +134 -15
- data/Gemfile.lock +89 -36
- data/README.markdown +6 -1
- data/Rakefile +2 -0
- data/lib/eso.rb +23 -0
- data/lib/eso/conductor.rb +227 -0
- data/lib/eso/configuration/configuration.rb +124 -0
- data/lib/eso/configuration/configuration_manager.rb +145 -0
- data/lib/eso/filter.rb +137 -0
- data/lib/eso/integration_option.rb +88 -0
- data/lib/eso/integration_options_manager.rb +178 -0
- data/lib/eso/nexpose.rb +212 -0
- data/lib/eso/service.rb +83 -0
- data/lib/eso/step.rb +166 -0
- data/lib/eso/step_configuration.rb +73 -0
- data/lib/eso/workflow.rb +149 -0
- data/lib/nexpose/ajax.rb +1 -0
- data/lib/nexpose/role.rb +1 -0
- data/lib/nexpose/util.rb +2 -1
- data/lib/nexpose/version.rb +1 -1
- metadata +19 -8
data/lib/eso/nexpose.rb
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'nexpose'
|
2
|
+
|
3
|
+
module Eso
|
4
|
+
module ServiceNames
|
5
|
+
ACTIVE_DIRECTORY = 'active-directory'
|
6
|
+
AWS = 'amazon-web-services'
|
7
|
+
AZURE = 'azure'
|
8
|
+
DXL = 'dxl'
|
9
|
+
EPO = 'epo'
|
10
|
+
NEXPOSE = 'nexpose'
|
11
|
+
end
|
12
|
+
|
13
|
+
module StepNames
|
14
|
+
ADD_TO_SITE = 'add-to-site'
|
15
|
+
ADD_VULN_AND_SCAN = 'add-vulnerabilities-to-site-and-scan'
|
16
|
+
DISCOVER_ACTIVE_DIRECTORY = 'discover-ad-assets'
|
17
|
+
DISCOVER_AWS_ASSETS = 'discover-aws-assets'
|
18
|
+
DISCOVER_AZURE_ASSETS = 'discover-azure-assets'
|
19
|
+
DISCOVER_EPO = 'discover-epo-assets'
|
20
|
+
DISCOVER_KNOWN = 'discover-known-assets'
|
21
|
+
DISCOVER_NEW = 'discover-new-assets'
|
22
|
+
DISCOVERY_CONFIG_METADATA = 'discoveryConfigMetadata'
|
23
|
+
EMPTY = ''
|
24
|
+
FILE_REPUTATION_TRIGGER = 'tie-file-reputation-trigger'
|
25
|
+
IMPORT_EXTERNAL = 'import-external-assets'
|
26
|
+
NEW_ASSET_VULN = 'new-asset-vulnerability'
|
27
|
+
NEW_VULN = 'new-vulnerabilities'
|
28
|
+
PUBLISH_VULN_INT_TYPE = 'publish-vulnerability-integration-type'
|
29
|
+
PUSH_RISK_SCORE = 'push-risk-score'
|
30
|
+
RISK_SCORE_UPDATED = 'risk-score-updated'
|
31
|
+
SCAN = 'scan'
|
32
|
+
SCAN_IN_SITE = 'scan-in-site'
|
33
|
+
SYNC_EXTERNAL = 'sync-external-assets'
|
34
|
+
TAG = 'tag'
|
35
|
+
VERIFY_AWS_ASSETS = 'verify-aws-targets'
|
36
|
+
VERIFY_EXTERNAL_TARGETS = 'verify-external-targets'
|
37
|
+
VULN_DETAILS = 'vulnerability-details'
|
38
|
+
VULN_DETAILS_REQUEST = 'vulnerability-details-request'
|
39
|
+
end
|
40
|
+
|
41
|
+
module Values
|
42
|
+
ARRAY = 'Array'
|
43
|
+
BOOLEAN = 'Boolean'
|
44
|
+
INTEGER = 'Integer'
|
45
|
+
OBJECT = 'Object'
|
46
|
+
STRING = 'String'
|
47
|
+
end
|
48
|
+
|
49
|
+
module StepConfigTypes
|
50
|
+
DISCOVERY_CONFIG = [StepNames::DISCOVER_ACTIVE_DIRECTORY,
|
51
|
+
StepNames::DISCOVER_AWS_ASSETS,
|
52
|
+
StepNames::DISCOVER_AZURE_ASSETS,
|
53
|
+
StepNames::DISCOVER_EPO,
|
54
|
+
StepNames::DISCOVER_KNOWN,
|
55
|
+
StepNames::DISCOVER_NEW,
|
56
|
+
StepNames::FILE_REPUTATION_TRIGGER,
|
57
|
+
StepNames::PUBLISH_VULN_INT_TYPE,
|
58
|
+
StepNames::PUSH_RISK_SCORE,
|
59
|
+
StepNames::VULN_DETAILS_REQUEST]
|
60
|
+
EMPTY = [StepNames::NEW_ASSET_VULN,
|
61
|
+
StepNames::NEW_VULN,
|
62
|
+
StepNames::RISK_SCORE_UPDATED,
|
63
|
+
StepNames::VULN_DETAILS]
|
64
|
+
SITE = [StepNames::ADD_TO_SITE,
|
65
|
+
StepNames::ADD_VULN_AND_SCAN,
|
66
|
+
StepNames::IMPORT_EXTERNAL,
|
67
|
+
StepNames::SCAN,
|
68
|
+
StepNames::SCAN_IN_SITE,
|
69
|
+
StepNames::SYNC_EXTERNAL]
|
70
|
+
TAG = [StepNames::TAG]
|
71
|
+
VERIFY = [StepNames::DISCOVER_AWS_ASSETS]
|
72
|
+
end
|
73
|
+
|
74
|
+
module Filters
|
75
|
+
CVSS_SCORE = 'CVSS_SCORE'
|
76
|
+
DHCP_HOST_NAME = 'DHCP_HOST_NAME'
|
77
|
+
HOURS_SINCE_LAST_SCAN= 'HOURS_SINCE_LAST_SCAN'
|
78
|
+
HOURS_SINCE_LAST_SCAN_ITEM = 'HOURS_SINCE_LAST_SCAN_ITEM'
|
79
|
+
IP_ADDRESS = 'IP_ADDRESS'
|
80
|
+
IP_RANGE = 'IP_RANGE'
|
81
|
+
MAC_ADDRESS = 'MAC_ADDRESS'
|
82
|
+
OPEN_PORT = 'OPEN_PORT'
|
83
|
+
RISK_SCORE = 'RISK_SCORE'
|
84
|
+
SERVICE_NAME = 'SERVICE_NAME'
|
85
|
+
end
|
86
|
+
|
87
|
+
module Nexpose
|
88
|
+
def self.create_discovery_workflow(conductor:, name:, step1_type:, step1_param: nil, step2_type:, step2_param:)
|
89
|
+
step1 = self.send("create_#{step1_type.to_s.gsub(/-/, "_")}_step", id: step1_param)
|
90
|
+
step2 = self.send("create_#{step2_type.to_s.gsub(/-/, "_")}_step", id: step2_param)
|
91
|
+
step2.previous_type_name = step1.type_name
|
92
|
+
conductor.create_workflow(name: name, steps: [step1, step2])
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.create_scan_new_vuln_workflow(conductor:, name:, filters:, site_id:)
|
96
|
+
step1 = self.create_new_vuln_step(workflow: nil, filters: filters, previous_type_name: StepNames::EMPTY)
|
97
|
+
step2 = self.create_add_vuln_and_scan_step(id: site_id)
|
98
|
+
step2.previous_type_name = step1.type_name
|
99
|
+
conductor.create_workflow(name: name, steps: [step1, step2])
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.create_file_trigger_workflow(conductor:, name:, step1_param:, step2_param:)
|
103
|
+
step1 = self.create_file_reputation_step(workflow: nil, id: step1_param)
|
104
|
+
step2 = self.create_tag_step(workflow: nil, id: step2_param)
|
105
|
+
step2.previous_type_name = step1.type_name
|
106
|
+
conductor.create_workflow(name: name, steps: [step1, step2])
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.create_scan_in_site_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
|
110
|
+
Step.new(workflow: workflow,
|
111
|
+
service_name: ServiceNames::NEXPOSE,
|
112
|
+
type_name: StepNames::SCAN_IN_SITE,
|
113
|
+
previous_type_name: previous_type_name)
|
114
|
+
.add_property(StepConfiguration::ConfigParamProperties::SITE_ID, id)
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.create_file_reputation_step(workflow: nil, id:)
|
118
|
+
Step.new(workflow: workflow,
|
119
|
+
service_name: ServiceNames::DXL,
|
120
|
+
type_name: StepNames::FILE_REPUTATION_TRIGGER,
|
121
|
+
previous_type_name: nil)
|
122
|
+
.add_property(StepConfiguration::ConfigParamProperties::DISCOVERY_CONFIG_ID, id)
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.create_discover_new_assets_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
|
126
|
+
Step.new(workflow: workflow,
|
127
|
+
service_name: ServiceNames::NEXPOSE,
|
128
|
+
type_name: StepNames::DISCOVER_NEW,
|
129
|
+
previous_type_name: previous_type_name)
|
130
|
+
.add_property(StepConfiguration::ConfigParamProperties::DISCOVERY_CONFIG_ID, id)
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.create_discover_known_assets_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
|
134
|
+
step = Step.new(workflow: workflow,
|
135
|
+
service_name: ServiceNames::NEXPOSE,
|
136
|
+
type_name: StepNames::DISCOVER_KNOWN,
|
137
|
+
previous_type_name: previous_type_name)
|
138
|
+
.add_property(StepConfiguration::ConfigParamProperties::DISCOVERY_CONFIG_ID, id)
|
139
|
+
config_params = step.configuration_params
|
140
|
+
config_params[:HOURS_SINCE_LAST_SCAN] = {
|
141
|
+
:valueClass => Values::ARRAY,
|
142
|
+
:items => [
|
143
|
+
{
|
144
|
+
:valueClass => Values::OBJECT,
|
145
|
+
:objectType => Filters::HOURS_SINCE_LAST_SCAN_ITEM,
|
146
|
+
:properties => {
|
147
|
+
:operator => {
|
148
|
+
:valueClass => Values::STRING,
|
149
|
+
:value => ::Nexpose::Search::Operator::GREATER_THAN
|
150
|
+
},
|
151
|
+
:operand1 => {
|
152
|
+
:valueClass => Values::STRING,
|
153
|
+
:value => '1'
|
154
|
+
}
|
155
|
+
}
|
156
|
+
}
|
157
|
+
]
|
158
|
+
}
|
159
|
+
step.configuration_params = config_params
|
160
|
+
step
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.create_new_vuln_step(workflow: nil, filters:, previous_type_name: StepNames::EMPTY)
|
164
|
+
# The filter definitions on the server are not standard at this point so that is why it is necessary to hard code this
|
165
|
+
# Opening a defect to fix the consistency on these on the backend so we can use the add_filter function in the automation
|
166
|
+
step = Step.new(workflow: workflow,
|
167
|
+
service_name: ServiceNames::NEXPOSE,
|
168
|
+
type_name: StepNames::NEW_VULN,
|
169
|
+
previous_type_name: previous_type_name)
|
170
|
+
|
171
|
+
filters.each { |filter| step.add_filter(filter) }
|
172
|
+
step
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.create_add_vuln_and_scan_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
|
176
|
+
Step.new(workflow: workflow,
|
177
|
+
service_name: ServiceNames::NEXPOSE,
|
178
|
+
type_name: StepNames::ADD_VULN_AND_SCAN,
|
179
|
+
previous_type_name: previous_type_name)
|
180
|
+
.add_property(StepConfiguration::ConfigParamProperties::SITE_ID, id)
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.create_add_to_site_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
|
184
|
+
Step.new(workflow: workflow,
|
185
|
+
service_name: ServiceNames::NEXPOSE,
|
186
|
+
type_name: StepNames::ADD_TO_SITE,
|
187
|
+
previous_type_name: previous_type_name)
|
188
|
+
.add_property(StepConfiguration::ConfigParamProperties::SITE_ID, id)
|
189
|
+
end
|
190
|
+
|
191
|
+
def self.create_scan_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
|
192
|
+
Step.new(workflow: workflow,
|
193
|
+
service_name: ServiceNames::NEXPOSE,
|
194
|
+
type_name: StepNames::SCAN,
|
195
|
+
previous_type_name: previous_type_name)
|
196
|
+
.add_property(StepConfiguration::ConfigParamProperties::SITE_ID, id)
|
197
|
+
end
|
198
|
+
|
199
|
+
def self.create_tag_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
|
200
|
+
Step.new(workflow: workflow,
|
201
|
+
service_name: ServiceNames::NEXPOSE,
|
202
|
+
type_name: StepNames::TAG,
|
203
|
+
previous_type_name: previous_type_name)
|
204
|
+
.add_property(StepConfiguration::ConfigParamProperties::TAG_ID, id)
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.get_discover_step(workflow: )
|
208
|
+
workflow.get_step(StepNames::DISCOVER_NEW) || workflow.get_step(StepNames::DISCOVER_KNOWN)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
data/lib/eso/service.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
module Eso
|
2
|
+
class Service
|
3
|
+
attr_accessor :host
|
4
|
+
|
5
|
+
attr_accessor :port
|
6
|
+
|
7
|
+
attr_accessor :url
|
8
|
+
|
9
|
+
CONTENT_TYPE_JSON = 'application/json; charset-utf-8'
|
10
|
+
|
11
|
+
def initialize(host:, port: 3780, nsc:)
|
12
|
+
@host = host
|
13
|
+
@port = port
|
14
|
+
@nexpose_console = nsc
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(url:, content_type: CONTENT_TYPE_JSON)
|
18
|
+
get = Net::HTTP::Get.new(url)
|
19
|
+
get.set_content_type(content_type)
|
20
|
+
request(request: get)
|
21
|
+
end
|
22
|
+
|
23
|
+
def put(url:, payload:, content_type: CONTENT_TYPE_JSON)
|
24
|
+
put = Net::HTTP::Put.new(url)
|
25
|
+
put.set_content_type(content_type)
|
26
|
+
put.body = payload.to_s if payload
|
27
|
+
request(request: put)
|
28
|
+
end
|
29
|
+
|
30
|
+
def post(url:, payload: nil, content_type: CONTENT_TYPE_JSON)
|
31
|
+
post = Net::HTTP::Post.new(url)
|
32
|
+
post.set_content_type(content_type)
|
33
|
+
post.body = payload.to_s if payload
|
34
|
+
request(request: post)
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(url:, content_type: CONTENT_TYPE_JSON)
|
38
|
+
delete = Net::HTTP::Delete.new(url)
|
39
|
+
delete.set_content_type(content_type)
|
40
|
+
request(request: delete)
|
41
|
+
end
|
42
|
+
|
43
|
+
def http(timeout:)
|
44
|
+
http = Net::HTTP.new(@host, @port)
|
45
|
+
http.read_timeout = timeout if timeout
|
46
|
+
http.use_ssl = false
|
47
|
+
http
|
48
|
+
end
|
49
|
+
|
50
|
+
def https(timeout:)
|
51
|
+
http = Net::HTTP.new(@host, @port)
|
52
|
+
http.read_timeout = timeout if timeout
|
53
|
+
http.use_ssl = true
|
54
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
55
|
+
http
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_nexpose_session(request:)
|
59
|
+
request.add_field('nexposeCCSessionID', @nexpose_console.session_id)
|
60
|
+
request.add_field('Cookie', "nexposeCCSessionID=#{@nexpose_console.session_id}")
|
61
|
+
request.add_field('X-Requested-With', 'XMLHttpRequest')
|
62
|
+
end
|
63
|
+
|
64
|
+
def request(request:, timeout: nil)
|
65
|
+
http = https(timeout: timeout)
|
66
|
+
add_nexpose_session(request: request)
|
67
|
+
response = http.request(request)
|
68
|
+
case response
|
69
|
+
when Net::HTTPOK, Net::HTTPCreated
|
70
|
+
rv = nil
|
71
|
+
if response.content_type == "application/json" && !response.body.empty?
|
72
|
+
json_data = JSON.parse(response.body, symbolize_names: true)
|
73
|
+
json_data[:data].nil? ? rv = json_data : rv = json_data[:data]
|
74
|
+
end
|
75
|
+
rv
|
76
|
+
when Net::HTTPForbidden
|
77
|
+
raise "Access denied. Response was #{response.body}"
|
78
|
+
else
|
79
|
+
raise "There was an error sending the request. Response was #{response.body}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/eso/step.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
module Eso
|
2
|
+
# Object representation of a step, which are attributes of Workflows and Integration Options
|
3
|
+
#
|
4
|
+
class Step
|
5
|
+
# UUID of this step. This is generated on creation on the server.
|
6
|
+
attr_accessor :uuid
|
7
|
+
|
8
|
+
# Type of this step. Should be one of Eso::ServiceNames
|
9
|
+
attr_accessor :serviceName
|
10
|
+
|
11
|
+
# The configuration for this step.
|
12
|
+
attr_accessor :stepConfiguration
|
13
|
+
|
14
|
+
# Constructor for Step.
|
15
|
+
#
|
16
|
+
# @param [String] uuid UUID of this Step. This is created on the server side upon creation through the API.
|
17
|
+
# @param [String] service_name The name of step this is.
|
18
|
+
# @param [Workflow] workflow The workflow this step belongs to.
|
19
|
+
# @param [Hash] configuration_params Hash of the parameters for this step.
|
20
|
+
#
|
21
|
+
def initialize(uuid: nil, service_name:, workflow: nil, type_name:, previous_type_name: StepNames::EMPTY, configuration_params: nil)
|
22
|
+
@uuid = uuid if uuid
|
23
|
+
@serviceName = service_name
|
24
|
+
@stepConfiguration = StepConfiguration.new(type_name, previous_type_name)
|
25
|
+
@stepConfiguration.configurationParams = configuration_params if configuration_params
|
26
|
+
@stepConfiguration.workflowID = workflow.id if workflow
|
27
|
+
end
|
28
|
+
|
29
|
+
# Return the configuration parameters for this step.
|
30
|
+
#
|
31
|
+
# @return [Hash] Hash of the configuration parameters for this step.
|
32
|
+
#
|
33
|
+
def configuration_params
|
34
|
+
@stepConfiguration.configurationParams
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the the configuration parameters for this step.
|
38
|
+
#
|
39
|
+
# @param [Hash] config_params of the new configuration parameters you would like to set.
|
40
|
+
# @return [Hash] Hash of the updated configuration parameters for this step.
|
41
|
+
#
|
42
|
+
def configuration_params=(config_params)
|
43
|
+
@stepConfiguration.configurationParams = config_params
|
44
|
+
end
|
45
|
+
|
46
|
+
# Return the type name for this step.
|
47
|
+
#
|
48
|
+
# @return [String] The currently configured type name.
|
49
|
+
#
|
50
|
+
def type_name
|
51
|
+
@stepConfiguration.typeName
|
52
|
+
end
|
53
|
+
|
54
|
+
# Set the type name for this step.
|
55
|
+
#
|
56
|
+
# @param [String] The new type_name that you would like to set this to. See Eso::StepNames for valid names.
|
57
|
+
# @return [String] The newly set type name.
|
58
|
+
#
|
59
|
+
def type_name=(wf_action_name)
|
60
|
+
@stepConfiguration.typeName = wf_action_name
|
61
|
+
end
|
62
|
+
|
63
|
+
# Return the previous type name for this step.
|
64
|
+
#
|
65
|
+
# @return [String] The previous type name for this step.
|
66
|
+
#
|
67
|
+
def previous_type_name
|
68
|
+
@stepConfiguration.previousTypeName
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set the previous type name for this step.
|
72
|
+
#
|
73
|
+
# @param [String] The new previous type name that you would like to set. See Eso::StepNames for valid names.
|
74
|
+
# @return [String] Hash of the configuration parameters for this step.
|
75
|
+
#
|
76
|
+
def previous_type_name=(action_name)
|
77
|
+
@stepConfiguration.previousTypeName = action_name
|
78
|
+
end
|
79
|
+
|
80
|
+
# Return the properties of this step.
|
81
|
+
#
|
82
|
+
# @return [Hash{}] Hash of the properties for this step.
|
83
|
+
#
|
84
|
+
def properties
|
85
|
+
@stepConfiguration.configurationParams[:properties]
|
86
|
+
end
|
87
|
+
|
88
|
+
# Set the properties of this step.
|
89
|
+
#
|
90
|
+
# @param [Hash] The new properties to set for this step.
|
91
|
+
# @return [Hash] Hash of the newly configured properties for this step.
|
92
|
+
#
|
93
|
+
def properties=(new_properties)
|
94
|
+
@stepConfiguration.configurationParams[:properties] = new_properties
|
95
|
+
end
|
96
|
+
|
97
|
+
# Determine the siteID of this step, if it exists
|
98
|
+
#
|
99
|
+
# @return [String|nil] The String siteID value or nil if no siteID
|
100
|
+
def site_id
|
101
|
+
if @stepConfiguration.configurationParams[:properties][:siteID]
|
102
|
+
@stepConfiguration.configurationParams[:properties][:siteID][:value]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns all configured filters for this step.
|
107
|
+
#
|
108
|
+
# @return [Array] An array of the currently configured filters for this step, each represented as a hash.
|
109
|
+
#
|
110
|
+
def filters
|
111
|
+
rv = {}
|
112
|
+
self.properties.each_pair do |key, value|
|
113
|
+
if value[:properties]
|
114
|
+
rv[key] = value if value[:properties].has_key?(:operators)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
rv
|
118
|
+
end
|
119
|
+
|
120
|
+
# Convenience method which calls the #add_property method of the @stepConfiguration, but returns the Step
|
121
|
+
#
|
122
|
+
# @return [Step] Returns this Step for chaining
|
123
|
+
def add_property(name, value)
|
124
|
+
@stepConfiguration.add_property(name, value)
|
125
|
+
self
|
126
|
+
end
|
127
|
+
|
128
|
+
# Convenience method which calls the #add_property method of the @stepConfiguration, but returns the Step
|
129
|
+
#
|
130
|
+
# @return [Step] Returns this Step for chaining
|
131
|
+
def update_property(name, value)
|
132
|
+
@stepConfiguration.add_property(name, value)
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
# Add the specified filter to this step. The filter is converted to a hash and saved as such instead of being saved as a ESO::Filter object.
|
137
|
+
#
|
138
|
+
# @param [Filter] filter The filter to add to this step.
|
139
|
+
#
|
140
|
+
def add_filter(filter)
|
141
|
+
@stepConfiguration.configurationParams[:properties].merge! filter.to_hash
|
142
|
+
end
|
143
|
+
|
144
|
+
# Return this step in a JSON digestible format.
|
145
|
+
#
|
146
|
+
# @return [String] JSON interpretation of this step.
|
147
|
+
#
|
148
|
+
def to_json
|
149
|
+
self.to_hash.to_json
|
150
|
+
end
|
151
|
+
|
152
|
+
# Return this step as a hash.
|
153
|
+
#
|
154
|
+
# @return [Hash] Hash interpretation of this step.
|
155
|
+
#
|
156
|
+
def to_hash
|
157
|
+
hash = {}
|
158
|
+
instance_variables.each do |var|
|
159
|
+
value = instance_variable_get(var)
|
160
|
+
value = value.to_h if value.respond_to?('to_h')
|
161
|
+
hash[var.to_s.delete('@')] = value
|
162
|
+
end
|
163
|
+
hash
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|