nexpose 7.0.1 → 7.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +184 -13
- data/COPYING +1 -1
- data/Gemfile.lock +72 -61
- data/README.markdown +10 -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/connection.rb +8 -4
- data/lib/nexpose/group.rb +1 -1
- data/lib/nexpose/maint.rb +23 -2
- data/lib/nexpose/report.rb +10 -0
- data/lib/nexpose/role.rb +3 -2
- data/lib/nexpose/scan.rb +4 -2
- data/lib/nexpose/site.rb +4 -2
- data/lib/nexpose/util.rb +2 -1
- data/lib/nexpose/version.rb +1 -1
- data/lib/nexpose/vuln_exception.rb +6 -6
- metadata +20 -9
@@ -0,0 +1,124 @@
|
|
1
|
+
module Eso
|
2
|
+
# This class represents the Configuration that is sent to the server for new
|
3
|
+
# style Discovery Connections.
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :service_name, :config_name, :config_id, :properties
|
6
|
+
|
7
|
+
def initialize(service_name:, config_name:, properties:[], config_id:)
|
8
|
+
@service_name = service_name
|
9
|
+
@config_name = config_name
|
10
|
+
@properties = properties
|
11
|
+
@config_id = config_id
|
12
|
+
end
|
13
|
+
|
14
|
+
# Convert the Configuration to a JSON string for sending to Nexpose
|
15
|
+
#
|
16
|
+
# @return [String] A JSON String representation of the Configuration
|
17
|
+
def to_json
|
18
|
+
self.to_hash.to_json
|
19
|
+
end
|
20
|
+
|
21
|
+
# Convert the Configuration to a Hash
|
22
|
+
#
|
23
|
+
# @return [Hash] A Hash representation of the Configuration
|
24
|
+
def to_hash
|
25
|
+
hash = {:configId => @config_id,
|
26
|
+
:serviceName => @service_name,
|
27
|
+
:configName => @config_name,
|
28
|
+
:configurationAttributes => {:valueClass => Eso::Values::OBJECT,
|
29
|
+
:objectType => 'service_configuration',
|
30
|
+
:properties => []}}
|
31
|
+
properties.each {|prop| hash[:configurationAttributes][:properties] << prop.to_hash}
|
32
|
+
end
|
33
|
+
|
34
|
+
# Retrieve a Configuration attribute property value given the name of the property
|
35
|
+
#
|
36
|
+
# @param [String] name The name of the property to retrieve
|
37
|
+
# @return [String] The value of the property
|
38
|
+
def property(name)
|
39
|
+
prop = properties.find{|attr| attr.property == name}
|
40
|
+
prop.value unless prop.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
# Update a Configuration attribute property value given the name of the property
|
44
|
+
#
|
45
|
+
# @param [String] name The name of the property to update
|
46
|
+
# @param [String] value The value of the property to update
|
47
|
+
# @return [String] The value of the property
|
48
|
+
def update_property(name, value)
|
49
|
+
properties.find{|attr| attr.property == name}.value = value
|
50
|
+
end
|
51
|
+
|
52
|
+
# Delete a Configuration attribute property value given the name of the property
|
53
|
+
#
|
54
|
+
# @param [String] name The name of the property to update
|
55
|
+
def delete_property(name)
|
56
|
+
properties.delete_if{|attr| attr.property == name}
|
57
|
+
end
|
58
|
+
|
59
|
+
# Load a Configuration object from a Hash
|
60
|
+
#
|
61
|
+
# @param [Hash] hash The Hash containing the Configuration object
|
62
|
+
# @return [Configuration] The Configuration object which was in the Hash
|
63
|
+
def self.load(hash)
|
64
|
+
configuration = self.new(service_name: hash[:serviceName],
|
65
|
+
config_name: hash[:configName],
|
66
|
+
config_id: hash[:configID])
|
67
|
+
hash[:configurationAttributes][:properties].each do |prop|
|
68
|
+
configuration.properties << ConfigurationAttribute.load(prop)
|
69
|
+
end
|
70
|
+
configuration
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# The ConfigurationAttribute is a property of the Configuration
|
75
|
+
class ConfigurationAttribute
|
76
|
+
attr_accessor :property, :value_class, :value
|
77
|
+
|
78
|
+
def initialize(property, value_class, value)
|
79
|
+
@property = property
|
80
|
+
@value_class = value_class
|
81
|
+
@value = value
|
82
|
+
end
|
83
|
+
|
84
|
+
# Convert the ConfigurationAttribute to a JSON string for sending to Nexpose
|
85
|
+
#
|
86
|
+
# @return [String] A JSON String representation of the ConfigurationAttribute
|
87
|
+
def to_json
|
88
|
+
self.to_hash.to_json
|
89
|
+
end
|
90
|
+
|
91
|
+
# Convert the ConfigurationAttribute to a Hash
|
92
|
+
#
|
93
|
+
# @return [Hash] A Hash representation of the ConfigurationAttribute
|
94
|
+
def to_hash
|
95
|
+
prop = @property.to_sym
|
96
|
+
hash = {prop => {}}
|
97
|
+
hash[prop]['valueClass'] = @value_class
|
98
|
+
if @value_class == Eso::Values::ARRAY
|
99
|
+
items = []
|
100
|
+
@value.each{|v| items<< {'value' => v, 'valueClass' => Eso::Values::STRING}}
|
101
|
+
hash[prop]['items'] = items
|
102
|
+
else
|
103
|
+
hash[prop]['value'] = @value
|
104
|
+
end
|
105
|
+
hash
|
106
|
+
end
|
107
|
+
|
108
|
+
# Load a ConfigurationAttribute object from an Array
|
109
|
+
#
|
110
|
+
# @param [Array] array The Array containing the ConfigurationAttribute object
|
111
|
+
# @return [ConfigurationAttribute] The ConfigurationAttribute object which was in the Array
|
112
|
+
def self.load(array)
|
113
|
+
property = array.first
|
114
|
+
value_class = array.last['valueClass']
|
115
|
+
value =
|
116
|
+
if value_class == Eso::Values::ARRAY
|
117
|
+
array.last['items'].map{|item| item['value']}
|
118
|
+
else
|
119
|
+
array.last['value']
|
120
|
+
end
|
121
|
+
self.new(property, value_class, value)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
module Eso
|
2
|
+
##
|
3
|
+
# This class represents a configuration manager service, which manages a number of configurations (ie a hostname,
|
4
|
+
# port, username, and password) used to connect to services, and the services they connect to (ie, ePO, dxl, palo-alto).
|
5
|
+
#
|
6
|
+
class ConfigurationManager
|
7
|
+
attr_accessor :url, :nexpose_console
|
8
|
+
|
9
|
+
##
|
10
|
+
# Constructor for ConfigurationManager.
|
11
|
+
#
|
12
|
+
# @param [Nexpose::Connection] nsc A logged-in Nexpose::Connection object with a valid session used to authenticate.
|
13
|
+
# @return [Eso::ConfigurationManager] The newly created configurationManager object
|
14
|
+
#
|
15
|
+
def initialize(nsc)
|
16
|
+
@nexpose_console = nsc
|
17
|
+
@url = "https://#{nsc.host}:#{nsc.port}/eso/configuration-manager/api/"
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Return all of the services that are currently supported by this configuration manager.
|
22
|
+
#
|
23
|
+
# @return [Array] An array containing all of services in the configuration manager in String object form.
|
24
|
+
# Returns an empty array if no services have been configured.
|
25
|
+
#
|
26
|
+
def services
|
27
|
+
json_data = ::Nexpose::AJAX.get(@nexpose_console, "#{@url}service/", ::Nexpose::AJAX::CONTENT_TYPE::JSON)
|
28
|
+
JSON.parse(json_data)
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Return all of the configurations of a particular service type.
|
33
|
+
#
|
34
|
+
# @param [String] service_name The name of a service to find configurations of.
|
35
|
+
# @return [Array] An array containing all the configurations of the given service type.
|
36
|
+
#
|
37
|
+
def service_configurations(service_name)
|
38
|
+
json_data = ::Nexpose::AJAX.get(@nexpose_console,
|
39
|
+
"#{@url}service/configuration/#{service_name}/",
|
40
|
+
::Nexpose::AJAX::CONTENT_TYPE::JSON)
|
41
|
+
JSON.parse(json_data, :symbolize_names => true)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Return the configuration of a particular service type with a particular name.
|
46
|
+
#
|
47
|
+
# @param [String] service_name The name of a service to find configurations of.
|
48
|
+
# @param [String] config_name The name of the Configuration.
|
49
|
+
# @return [Eso::Configuration] A Configuration object which matches the service name and config name requested.
|
50
|
+
def configuration_by_name(service_name, config_name)
|
51
|
+
service_configs_by_type = service_configurations(service_name)
|
52
|
+
config_hash = service_configs_by_type.find { |config| config[:configName] == config_name }
|
53
|
+
Eso::Configuration.load(config_hash)
|
54
|
+
end
|
55
|
+
|
56
|
+
def configuration_type(service_name:)
|
57
|
+
json_data = ::Nexpose::AJAX.get(@nexpose_console,
|
58
|
+
"#{@url}service/configurationType/#{service_name.downcase}",
|
59
|
+
::Nexpose::AJAX::CONTENT_TYPE::JSON)
|
60
|
+
JSON.parse(json_data)
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Get a configuration by id. Runs a GET call against the eso/configuration-manager/api/service/configuration/CONFIGURATION_ID endpoint
|
65
|
+
# @param [String] configuration_id The id of the configuration to get
|
66
|
+
# return [JSON] A json object representing a configuration
|
67
|
+
# TODO : Update to use an Eso::Configuration
|
68
|
+
def get_configuration(configuration_id)
|
69
|
+
json_data = ::Nexpose::AJAX.get(@nexpose_console, "#{@url}/service/configuration/id/#{configuration_id}", ::Nexpose::AJAX::CONTENT_TYPE::JSON)
|
70
|
+
JSON.parse(json_data, :symbolize_names => true)
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Create a new configuration.
|
75
|
+
#
|
76
|
+
# @param [String] payload The JSON representation of a configuration.
|
77
|
+
# @return [Integer] The configID (>= 1) of the newly created configuration. Raises error on failure.
|
78
|
+
# TODO: Update to use an Eso::Configuration
|
79
|
+
def post_service_configuration(payload)
|
80
|
+
# TODO retry if the post fails on timeout
|
81
|
+
response_body = ::Nexpose::AJAX.post(@nexpose_console, "#{@url}service/configuration", payload, ::Nexpose::AJAX::CONTENT_TYPE::JSON)
|
82
|
+
config_id = Integer(JSON.parse(response_body)['data'])
|
83
|
+
raise Exception.new("API returned invalid configID (#{config_id}) while attempting to create configuration.") unless config_id >= 1
|
84
|
+
config_id
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Test a configuration.
|
89
|
+
#
|
90
|
+
# @param [String] payload The JSON representation of a configuration.
|
91
|
+
# @return [String] The response from the call or an APIError
|
92
|
+
# TODO: Update to use an Eso::Configuration
|
93
|
+
def test_service_configuration(payload)
|
94
|
+
::Nexpose::AJAX.post(@nexpose_console,
|
95
|
+
"#{@url}service/configuration/test",
|
96
|
+
payload,
|
97
|
+
::Nexpose::AJAX::CONTENT_TYPE::JSON)
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Delete a configuration. Runs a DELETE call against the eso/configuration-manager/api/service/configuration/CONFIGURATION_ID endpoint
|
102
|
+
#
|
103
|
+
# @param [String] configuration_id The id of the configuration to delete
|
104
|
+
# return [Boolean] Return true if the api reports a successful delete. Raises an error on failure.
|
105
|
+
def delete(configuration_id)
|
106
|
+
response_body = ::Nexpose::AJAX.delete(@nexpose_console, "#{@url}service/configuration/#{configuration_id}")
|
107
|
+
raise Exception.new("Failed to delete configuration with ID: #{configuration_id}") unless 'success' == response_body
|
108
|
+
true
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# Preview assets for a configuration. Calls a POST to the eso/configuration-manager/api/service/configuration/preview endpoint
|
113
|
+
#
|
114
|
+
# @param configuration The configuration to preview
|
115
|
+
# return [Array] previewed assets
|
116
|
+
# TODO: Update to use an Eso::Configuration
|
117
|
+
def preview_assets(configuration)
|
118
|
+
response_body = ::Nexpose::AJAX.post(@nexpose_console,
|
119
|
+
"#{@url}service/configuration/preview",
|
120
|
+
configuration,
|
121
|
+
::Nexpose::AJAX::CONTENT_TYPE::JSON)
|
122
|
+
@preview_assets = JSON.parse(response_body)["previewAssets"]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
module ConfigManagerMessages
|
127
|
+
module TestConfig
|
128
|
+
AUTH_FAILED_AWS = 'Could not authenticate to Amazon Web Services.'
|
129
|
+
# Actual message will list out the bad ARNs
|
130
|
+
AUTH_FAILED_AWS_ARN = /Could not authenticate to Amazon Web Services with the following ARNs/
|
131
|
+
|
132
|
+
CONNECTION_SUCCESSFUL = 'The connection to the external service was successful.'
|
133
|
+
# Applies to invalid user, password, wrong protocol, can't reach server, bad base or search query
|
134
|
+
CONNECTION_FAILED = 'The connection to the external service failed.'
|
135
|
+
|
136
|
+
INVALID_FIELDS = 'The configuration had invalid fields.'
|
137
|
+
|
138
|
+
RETRY_AD = 'Failed to reach out to the Active Directory service, will try again.'
|
139
|
+
RETRY_AWS = 'Failed to reach out to Amazon Web Services, will try again.'
|
140
|
+
RETRY_AZURE = 'Failed to reach out to the Azure service, will try again.'
|
141
|
+
RETRY_DXL = 'The DXL connection is currently down and the connection is in retry status.'
|
142
|
+
RETRY_EPO = 'Failed to reach out to the ePO service, will try again.'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/eso/filter.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
module Eso
|
2
|
+
class Filter
|
3
|
+
# These are defined in Eso::Filters which reside in the respective service they are related to.
|
4
|
+
attr_accessor :type
|
5
|
+
|
6
|
+
# These are the individual filter items
|
7
|
+
attr_accessor :filter_items
|
8
|
+
|
9
|
+
# Constructor for Filter.
|
10
|
+
#
|
11
|
+
# @param [String] type The type of filter this is. They are based on the service this filter exists in. These are defined in Eso::Filters which reside in the respective service they are related to.
|
12
|
+
# @param [Array] items Array of filters of this type
|
13
|
+
# @return [Eso::Filter] The newly created filter object
|
14
|
+
#
|
15
|
+
def initialize(type:, items: [])
|
16
|
+
@type = type
|
17
|
+
@filter_items = items
|
18
|
+
end
|
19
|
+
|
20
|
+
# Append a filter_item later
|
21
|
+
def <<(filter_item)
|
22
|
+
@filter_items << filter_item
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_json
|
26
|
+
self.to_hash.to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_hash
|
30
|
+
hash = {}
|
31
|
+
hash[@type.to_sym] = {
|
32
|
+
valueClass: 'Array',
|
33
|
+
items: @filter_items.map{|item| item.to_hash}
|
34
|
+
}
|
35
|
+
hash
|
36
|
+
end
|
37
|
+
alias_method :to_h, :to_hash
|
38
|
+
|
39
|
+
class FilterItem
|
40
|
+
attr_accessor :type
|
41
|
+
# Examples are "OR", "IN", "CONTAINS". These should probably be constantized somewhere.
|
42
|
+
attr_accessor :operator
|
43
|
+
|
44
|
+
# Array containing the values to filter on
|
45
|
+
attr_accessor :operands
|
46
|
+
|
47
|
+
def initialize(type:, operator:, operands:)
|
48
|
+
@type = "#{type}_ITEM"
|
49
|
+
@operator = operator
|
50
|
+
process_operands(operands)
|
51
|
+
end
|
52
|
+
|
53
|
+
def process_operands(operands)
|
54
|
+
@operands =
|
55
|
+
if ["IS_EMPTY", "IS_NOT_EMPTY"].include? @operator
|
56
|
+
nil
|
57
|
+
elsif @type == "#{Eso::Filters::IP_ADDRESS}_ITEM" ||
|
58
|
+
@type == "#{Eso::Filters::IP_RANGE}_ITEM" ||
|
59
|
+
@type == "#{Eso::Filters::OPEN_PORT}_ITEM" ||
|
60
|
+
@type == "#{Eso::Filters::RISK_SCORE}_ITEM" ||
|
61
|
+
@type == "#{Eso::Filters::CVSS_SCORE}_ITEM"
|
62
|
+
operands.first.split('-')
|
63
|
+
else
|
64
|
+
operands
|
65
|
+
end
|
66
|
+
|
67
|
+
if @operands == nil
|
68
|
+
return
|
69
|
+
end
|
70
|
+
@operands.map! do |value|
|
71
|
+
# This regex is used to determine if the string is actually a float.
|
72
|
+
# http://stackoverflow.com/questions/1034418/determine-if-a-string-is-a-valid-float-value
|
73
|
+
if value =~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/
|
74
|
+
if (@type == "#{Eso::Filters::OPEN_PORT}_ITEM")
|
75
|
+
value.to_i
|
76
|
+
else
|
77
|
+
value.to_f
|
78
|
+
end
|
79
|
+
# If it's not a float, let's see if it's an integer.
|
80
|
+
elsif value.to_i.to_s == value
|
81
|
+
value.to_i
|
82
|
+
# Guess not, so lets keep the original value.
|
83
|
+
else
|
84
|
+
value
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_hash
|
90
|
+
hash = {
|
91
|
+
valueClass: "Object",
|
92
|
+
objectType: @type,
|
93
|
+
properties: {
|
94
|
+
operator: {
|
95
|
+
valueClass: "String",
|
96
|
+
value: @operator
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
# Currently there are no standards that say how many operands a filter can have
|
101
|
+
operand_hash = {}
|
102
|
+
operand_counter = 1
|
103
|
+
unless @operands.nil?
|
104
|
+
@operands.each do |operand|
|
105
|
+
label = "operand#{operand_counter}".to_sym
|
106
|
+
|
107
|
+
# A correct value class is required because Jackson expects it.
|
108
|
+
# A Jackson processor for Ruby would probably make this much nicer
|
109
|
+
# Also, defaulting to Number is probably a bad idea, but based on current possible values in ESO this works.
|
110
|
+
case operand.class.to_s
|
111
|
+
|
112
|
+
when "String"
|
113
|
+
value_class = "String"
|
114
|
+
when "Array"
|
115
|
+
value_class = "Array"
|
116
|
+
when "Fixnum"
|
117
|
+
value_class = "Integer"
|
118
|
+
else
|
119
|
+
value_class = "Number"
|
120
|
+
end
|
121
|
+
|
122
|
+
operand_hash[label] = {
|
123
|
+
valueClass: value_class,
|
124
|
+
value: operand
|
125
|
+
}
|
126
|
+
operand_counter += 1
|
127
|
+
end
|
128
|
+
|
129
|
+
hash[:properties].merge! operand_hash
|
130
|
+
end
|
131
|
+
|
132
|
+
hash
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Eso
|
2
|
+
|
3
|
+
module IntegrationOptionNames
|
4
|
+
IMPORT_AD_ASSETS = 'import_ad_assets'
|
5
|
+
IMPORT_EPO_ASSETS = 'import_epo_assets'
|
6
|
+
SYNC_AZURE_ASSETS = 'sync_azure_assets'
|
7
|
+
SYNC_AZURE_ASSETS_WITH_TAGS = 'sync_azure_assets_with_tags'
|
8
|
+
end
|
9
|
+
|
10
|
+
# IntegrationOptionTypes is a way to categorize what various Integration Options do.
|
11
|
+
module IntegrationOptionTypes
|
12
|
+
# The IMPORT_TO_SITE Array tracks Integration Options which load Assets into a Site.
|
13
|
+
IMPORT_TO_SITE = [
|
14
|
+
IntegrationOptionNames::IMPORT_AD_ASSETS,
|
15
|
+
IntegrationOptionNames::IMPORT_EPO_ASSETS,
|
16
|
+
IntegrationOptionNames::SYNC_AZURE_ASSETS,
|
17
|
+
IntegrationOptionNames::SYNC_AZURE_ASSETS_WITH_TAGS
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
class IntegrationOption
|
22
|
+
attr_accessor :name
|
23
|
+
attr_accessor :steps
|
24
|
+
attr_accessor :id
|
25
|
+
|
26
|
+
def initialize(id: nil, name:, steps: [])
|
27
|
+
@id = id
|
28
|
+
@name = name
|
29
|
+
@steps = steps
|
30
|
+
end
|
31
|
+
|
32
|
+
def site_id=(site_id)
|
33
|
+
# As of now, the site is always in the last Step of the IntegrationOption. Might change.
|
34
|
+
@steps.last.add_property(StepConfiguration::ConfigParamProperties::SITE_ID, site_id)
|
35
|
+
end
|
36
|
+
|
37
|
+
def site_id
|
38
|
+
# As of now, the site is always in the last Step of the IntegrationOption. Might change.
|
39
|
+
@steps.last.site_id
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return this object and the associated steps in a digestible JSON format.
|
43
|
+
#
|
44
|
+
# @return [String] JSON interpretation of this workflow.
|
45
|
+
#
|
46
|
+
def to_json
|
47
|
+
# Convert Object to Hash
|
48
|
+
hash = self.to_hash
|
49
|
+
|
50
|
+
# Grab the Step objects and convert to Hashes
|
51
|
+
steps = hash['steps']
|
52
|
+
hashified_steps = []
|
53
|
+
steps.each {|step| hashified_steps << step.to_hash}
|
54
|
+
hash['steps'] = hashified_steps
|
55
|
+
|
56
|
+
# Convert Hash to JSON
|
57
|
+
hash.to_json
|
58
|
+
end
|
59
|
+
|
60
|
+
# Return this object as a Hash. The corresponding Steps will still be objects.
|
61
|
+
#
|
62
|
+
# @return [Hash] Hash interpretation of this IntegrationOption.
|
63
|
+
def to_hash
|
64
|
+
hash = {}
|
65
|
+
instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var)}
|
66
|
+
hash
|
67
|
+
end
|
68
|
+
|
69
|
+
# Load a Hash of an IntegrationOption into an actual IntegrationOption. Probably didn't need to
|
70
|
+
# break out separately, but might be useful
|
71
|
+
#
|
72
|
+
# @param [Hash] raw_integration_option is a Hash representation of an IntegrationOption
|
73
|
+
# @return [IntegrationOption] The IntegrationOption version of the Hash
|
74
|
+
def self.load(raw_integration_option)
|
75
|
+
integration_option = IntegrationOption.new(id: raw_integration_option[:id], name: raw_integration_option[:name])
|
76
|
+
steps = raw_integration_option[:steps]
|
77
|
+
steps.each do |step|
|
78
|
+
step_config = step[:stepConfiguration]
|
79
|
+
integration_option.steps << Step.new(uuid: step[:uuid],
|
80
|
+
service_name: step[:serviceName],
|
81
|
+
type_name: step_config[:typeName],
|
82
|
+
previous_type_name: step_config[:previousTypeName],
|
83
|
+
configuration_params: step_config[:configurationParams])
|
84
|
+
end
|
85
|
+
integration_option
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|