nexpose 7.2.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 +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/Gemfile.lock
CHANGED
@@ -1,65 +1,118 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nexpose (
|
4
|
+
nexpose (7.3.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
activesupport (6.1.1)
|
10
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
11
|
+
i18n (>= 1.6, < 2)
|
12
|
+
minitest (>= 5.1)
|
13
|
+
tzinfo (~> 2.0)
|
14
|
+
zeitwerk (~> 2.3)
|
15
|
+
addressable (2.7.0)
|
16
|
+
public_suffix (>= 2.0.2, < 5.0)
|
17
|
+
ast (2.4.1)
|
18
|
+
codeclimate-test-reporter (0.4.8)
|
14
19
|
simplecov (>= 0.7.1, < 1.0.0)
|
15
|
-
|
16
|
-
|
17
|
-
|
20
|
+
coderay (1.1.3)
|
21
|
+
concurrent-ruby (1.1.7)
|
22
|
+
crack (0.4.5)
|
23
|
+
rexml
|
24
|
+
diff-lcs (1.4.4)
|
18
25
|
docile (1.1.5)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
faraday (1.3.0)
|
27
|
+
faraday-net_http (~> 1.0)
|
28
|
+
multipart-post (>= 1.2, < 3)
|
29
|
+
ruby2_keywords
|
30
|
+
faraday-http-cache (2.2.0)
|
31
|
+
faraday (>= 0.8)
|
32
|
+
faraday-net_http (1.0.1)
|
33
|
+
github_changelog_generator (1.15.2)
|
34
|
+
activesupport
|
35
|
+
faraday-http-cache
|
36
|
+
multi_json
|
37
|
+
octokit (~> 4.6)
|
38
|
+
rainbow (>= 2.2.1)
|
39
|
+
rake (>= 10.0)
|
40
|
+
retriable (~> 3.0)
|
41
|
+
i18n (1.8.7)
|
42
|
+
concurrent-ruby (~> 1.0)
|
43
|
+
method_source (0.9.2)
|
44
|
+
minitest (5.14.3)
|
45
|
+
multi_json (1.15.0)
|
46
|
+
multipart-post (2.1.1)
|
47
|
+
octokit (4.20.0)
|
48
|
+
faraday (>= 0.9)
|
49
|
+
sawyer (~> 0.8.0, >= 0.5.3)
|
50
|
+
parallel (1.20.1)
|
51
|
+
parser (3.0.0.0)
|
52
|
+
ast (~> 2.4.1)
|
53
|
+
pry (0.9.12.6)
|
54
|
+
coderay (~> 1.0)
|
55
|
+
method_source (~> 0.8)
|
56
|
+
slop (~> 3.4)
|
57
|
+
public_suffix (4.0.6)
|
58
|
+
rainbow (3.0.0)
|
59
|
+
rake (13.0.3)
|
60
|
+
regexp_parser (2.0.3)
|
61
|
+
retriable (3.1.2)
|
62
|
+
rexml (3.2.4)
|
63
|
+
rspec (3.10.0)
|
64
|
+
rspec-core (~> 3.10.0)
|
65
|
+
rspec-expectations (~> 3.10.0)
|
66
|
+
rspec-mocks (~> 3.10.0)
|
67
|
+
rspec-core (3.10.1)
|
68
|
+
rspec-support (~> 3.10.0)
|
69
|
+
rspec-expectations (3.10.1)
|
32
70
|
diff-lcs (>= 1.2.0, < 2.0)
|
33
|
-
rspec-support (~> 3.
|
34
|
-
rspec-mocks (3.
|
71
|
+
rspec-support (~> 3.10.0)
|
72
|
+
rspec-mocks (3.10.1)
|
35
73
|
diff-lcs (>= 1.2.0, < 2.0)
|
36
|
-
rspec-support (~> 3.
|
37
|
-
rspec-support (3.
|
38
|
-
rubocop (
|
39
|
-
|
40
|
-
parser (>=
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
74
|
+
rspec-support (~> 3.10.0)
|
75
|
+
rspec-support (3.10.1)
|
76
|
+
rubocop (1.8.1)
|
77
|
+
parallel (~> 1.10)
|
78
|
+
parser (>= 3.0.0.0)
|
79
|
+
rainbow (>= 2.2.2, < 4.0)
|
80
|
+
regexp_parser (>= 1.8, < 3.0)
|
81
|
+
rexml
|
82
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
83
|
+
ruby-progressbar (~> 1.7)
|
84
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
85
|
+
rubocop-ast (1.4.0)
|
86
|
+
parser (>= 2.7.1.5)
|
87
|
+
ruby-progressbar (1.11.0)
|
88
|
+
ruby2_keywords (0.0.2)
|
89
|
+
sawyer (0.8.2)
|
90
|
+
addressable (>= 2.3.5)
|
91
|
+
faraday (> 0.8, < 2.0)
|
46
92
|
simplecov (0.9.2)
|
47
93
|
docile (~> 1.1.0)
|
48
94
|
multi_json (~> 1.0)
|
49
95
|
simplecov-html (~> 0.9.0)
|
50
96
|
simplecov-html (0.9.0)
|
97
|
+
slop (3.6.0)
|
98
|
+
tzinfo (2.0.4)
|
99
|
+
concurrent-ruby (~> 1.0)
|
100
|
+
unicode-display_width (2.0.0)
|
51
101
|
vcr (2.9.3)
|
52
102
|
webmock (1.20.4)
|
53
103
|
addressable (>= 2.3.6)
|
54
104
|
crack (>= 0.3.2)
|
105
|
+
zeitwerk (2.4.2)
|
55
106
|
|
56
107
|
PLATFORMS
|
57
108
|
ruby
|
58
109
|
|
59
110
|
DEPENDENCIES
|
60
|
-
bundler
|
111
|
+
bundler
|
61
112
|
codeclimate-test-reporter (~> 0.4.6)
|
113
|
+
github_changelog_generator
|
62
114
|
nexpose!
|
115
|
+
pry (= 0.9.12.6)
|
63
116
|
rake
|
64
117
|
rspec (~> 3.2)
|
65
118
|
rubocop
|
@@ -68,4 +121,4 @@ DEPENDENCIES
|
|
68
121
|
webmock (~> 1.20.4)
|
69
122
|
|
70
123
|
BUNDLED WITH
|
71
|
-
1.
|
124
|
+
1.17.3
|
data/README.markdown
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
# DEPRECATED
|
2
|
+
The [RESTful API for the Nexpose/InsightVM Security Console](https://help.rapid7.com/insightvm/en-us/api/index.html) has rendered this library obsolete. If you require a Ruby library for that API you can use a [generated client](https://github.com/rapid7/vm-console-client-ruby). Clients for other languages can be generated from the Swagger specification. Note that generated clients are not officially supported or maintained by Rapid7.
|
3
|
+
|
4
|
+
While this project is no longer under active development, it is still maintained by Rapid7 for internal testing needs. Pull requests will continue to be reviewed and accepted, and new versions published as requested.
|
5
|
+
|
1
6
|
# Nexpose-Client
|
2
|
-
[![Gem Version](https://badge.fury.io/rb/nexpose.svg)](http://badge.fury.io/rb/nexpose) [![Build Status](https://travis-ci.org/rapid7/nexpose-client.svg?branch=master)](https://travis-ci.org/rapid7/nexpose-client) [![Test Coverage](https://codeclimate.com/github/rapid7/nexpose-client/badges/coverage.svg)](https://codeclimate.com/github/rapid7/nexpose-client) [![Inline docs](http://inch-ci.org/github/rapid7/nexpose-client.svg?branch=master)](http://inch-ci.org/github/rapid7/nexpose-client) [![Code Climate](https://codeclimate.com/github/rapid7/nexpose-client/badges/gpa.svg)](https://codeclimate.com/github/rapid7/nexpose-client)
|
7
|
+
[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) [![Gem Version](https://badge.fury.io/rb/nexpose.svg)](http://badge.fury.io/rb/nexpose) [![Build Status](https://travis-ci.org/rapid7/nexpose-client.svg?branch=master)](https://travis-ci.org/rapid7/nexpose-client) [![Test Coverage](https://codeclimate.com/github/rapid7/nexpose-client/badges/coverage.svg)](https://codeclimate.com/github/rapid7/nexpose-client) [![Inline docs](http://inch-ci.org/github/rapid7/nexpose-client.svg?branch=master)](http://inch-ci.org/github/rapid7/nexpose-client) [![Code Climate](https://codeclimate.com/github/rapid7/nexpose-client/badges/gpa.svg)](https://codeclimate.com/github/rapid7/nexpose-client)
|
3
8
|
|
4
9
|
This is the official gem package for the Ruby Nexpose API client library.
|
5
10
|
|
data/Rakefile
CHANGED
@@ -12,4 +12,6 @@ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
|
12
12
|
if token.nil?
|
13
13
|
warn "!!WARNING!! Missing Github Token Environment Variable. Fix before you run rake changelog. !!WARNING!!"
|
14
14
|
end
|
15
|
+
config.user = 'rapid7'
|
16
|
+
config.project = 'nexpose-client'
|
15
17
|
end
|
data/lib/eso.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/https'
|
5
|
+
require 'nexpose'
|
6
|
+
require 'time'
|
7
|
+
require 'uri'
|
8
|
+
|
9
|
+
require 'eso/conductor'
|
10
|
+
require 'eso/configuration/configuration'
|
11
|
+
require 'eso/configuration/configuration_manager'
|
12
|
+
require 'eso/filter'
|
13
|
+
require 'eso/integration_option'
|
14
|
+
require 'eso/integration_options_manager'
|
15
|
+
require 'eso/nexpose'
|
16
|
+
require 'eso/service'
|
17
|
+
require 'eso/step'
|
18
|
+
require 'eso/step_configuration'
|
19
|
+
require 'eso/workflow'
|
20
|
+
|
21
|
+
module Eso
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'eso/service'
|
2
|
+
|
3
|
+
module Eso
|
4
|
+
class Conductor < Service
|
5
|
+
|
6
|
+
# Constructor for Conductor.
|
7
|
+
#
|
8
|
+
# @param [String] host Hostname or IP address where this conductor resides.
|
9
|
+
# @param [Integer] port The TCP port to connect to this conductor on.
|
10
|
+
# @param [Nexpose::Connection] nsc A logged-in Nexpose::Connection object with a valid session used to authenticate.
|
11
|
+
# @return [Eso::Conductor] The newly created conductor object
|
12
|
+
#
|
13
|
+
def initialize(host:, port: 3780, nsc:)
|
14
|
+
super(host: host, port: port, nsc: nsc)
|
15
|
+
@url = "https://#{@host}:#{@port}/eso/conductor-service/api/"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return all of the workflows that currently exist on this conductor.
|
19
|
+
#
|
20
|
+
# @return [Array] An array containing all of the current workflows on the conductor in Eso::Workflow object format. Returns an empty array if no workflows are present.
|
21
|
+
#
|
22
|
+
def workflows
|
23
|
+
rv = []
|
24
|
+
json_data = get(url: "#{@url}workflows/")
|
25
|
+
json_data.each do |wf|
|
26
|
+
workflow = Workflow.new(id: wf[:id], name: wf[:name])
|
27
|
+
steps = wf[:steps]
|
28
|
+
steps.each do |step|
|
29
|
+
workflow_step = Step.new(uuid: step[:uuid],
|
30
|
+
service_name: step[:serviceName],
|
31
|
+
workflow: workflow,
|
32
|
+
type_name: step[:stepConfiguration][:typeName],
|
33
|
+
previous_type_name: step[:stepConfiguration][:previousTypeName],
|
34
|
+
configuration_params: step[:stepConfiguration][:configurationParams])
|
35
|
+
workflow.steps << workflow_step
|
36
|
+
end
|
37
|
+
rv << workflow
|
38
|
+
end
|
39
|
+
rv
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return the workflow histories with only the state histories for the given date range.
|
43
|
+
#
|
44
|
+
# @param [Fixnum] starttime The time in milliseconds since epoch for which you want the workflow histories
|
45
|
+
# @param [Fixnum] endtime The time in milliseconds since epoch for which you want the workflow histories
|
46
|
+
# @return [Array[Eso::Workflow::History]] An array containing all of the workflow histories from the
|
47
|
+
# Conductor, which has StateHistory objects containing startTime's within the specified time range. Only the
|
48
|
+
# StateHistories within that range are returned in the WorkflowHistory object. Returns an empty array if none are present.
|
49
|
+
def workflow_histories(starttime, endtime)
|
50
|
+
histories = []
|
51
|
+
json_data = get(url: "#{@url}workflows/history/#{starttime}/#{endtime}")
|
52
|
+
json_data.each do |wf|
|
53
|
+
# Initialize WorkflowHistory elements
|
54
|
+
workflow_steps = []
|
55
|
+
state_histories = []
|
56
|
+
|
57
|
+
# Create a new WorkflowHistory with the details we already know
|
58
|
+
workflow_history = Eso::Workflow::History.new(id: wf[:id],
|
59
|
+
name: wf[:name],
|
60
|
+
timeCreated: wf[:timeCreated],
|
61
|
+
state: wf[:state],
|
62
|
+
message: wf[:message],
|
63
|
+
steps: workflow_steps,
|
64
|
+
history: state_histories
|
65
|
+
)
|
66
|
+
|
67
|
+
# Parse the steps out of the response to be returned with the WorkflowHistory
|
68
|
+
wf[:steps].each do |step|
|
69
|
+
workflow_steps << Step.new(uuid: step[:uuid],
|
70
|
+
service_name: step[:serviceName],
|
71
|
+
workflow: workflow_history,
|
72
|
+
type_name: step[:stepConfiguration][:typeName],
|
73
|
+
previous_type_name: step[:stepConfiguration][:previousTypeName],
|
74
|
+
configuration_params: step[:stepConfiguration][:configurationParams])
|
75
|
+
end
|
76
|
+
workflow_history.steps = workflow_steps
|
77
|
+
|
78
|
+
# Parse the histories out of the response, to be returned with the WorkflowHistory. For some reason.
|
79
|
+
# this failed with named parameters. For now I returned it to positional.
|
80
|
+
wf[:history].each do |history|
|
81
|
+
state_histories << Eso::Workflow::StateHistory.new(history[:message],
|
82
|
+
history[:state],
|
83
|
+
history[:startTime])
|
84
|
+
end
|
85
|
+
workflow_history.state_histories = state_histories
|
86
|
+
|
87
|
+
# Add the Workflow History we just built to the list to be returned.
|
88
|
+
histories << workflow_history
|
89
|
+
end
|
90
|
+
histories
|
91
|
+
end
|
92
|
+
|
93
|
+
# Get the state of the specified workflow.
|
94
|
+
#
|
95
|
+
# @param [String] workflow_id The ID of the workflow to retrieve the state of.
|
96
|
+
# @return [String] The current state of the workflow.
|
97
|
+
#
|
98
|
+
def workflow_state(workflow_id:)
|
99
|
+
get(url: "#{@url}workflows/#{workflow_id}/state")
|
100
|
+
end
|
101
|
+
|
102
|
+
# Get the count of items in a state of the specified workflow.
|
103
|
+
#
|
104
|
+
# @param [Eso::Workflow::State] state The state of the workflows to retrieve the count of.
|
105
|
+
# @return [Integer] The number of workflows in the requested state.
|
106
|
+
#
|
107
|
+
def workflows_state_count(state)
|
108
|
+
get(url: "#{@url}workflows/count/#{state}")
|
109
|
+
end
|
110
|
+
|
111
|
+
# Retrieve the states for all of the workflows created on the conductor.
|
112
|
+
#
|
113
|
+
# @return [Hash] A hash containing the states of all existing workflows, keyed by workflow ID.
|
114
|
+
#
|
115
|
+
def workflow_states
|
116
|
+
wfs = workflows
|
117
|
+
states = {}
|
118
|
+
wfs.each { |wf| states[wf.id] = workflow_state(workflow_id: wf.id) }
|
119
|
+
states
|
120
|
+
end
|
121
|
+
|
122
|
+
# Create a new workflow on this conductor.
|
123
|
+
#
|
124
|
+
# @param [String] name The user-facing name the workflow will be created with.
|
125
|
+
# @param [Array] steps An array containing each of the steps that the workflow will be created with, in Eso::Step format.
|
126
|
+
# @return [Eso::Workflow] The newly created workflow object
|
127
|
+
#
|
128
|
+
def create_workflow(name:, steps:)
|
129
|
+
workflow = Workflow.new(name: name, steps: steps)
|
130
|
+
|
131
|
+
resp = post(url: "#{@url}workflows/", payload: workflow.to_json)
|
132
|
+
created_workflow = Workflow.load(self, resp[:id])
|
133
|
+
|
134
|
+
created_workflow
|
135
|
+
end
|
136
|
+
|
137
|
+
# Update an existing workflow on the conductor to have the configuration of the workflow object passed into this method.
|
138
|
+
#
|
139
|
+
# @param [Eso::Workflow] updated_workflow A workflow object that has already had all required changes made to it. This workflow must have an ID set.
|
140
|
+
#
|
141
|
+
def update_workflow(updated_workflow:)
|
142
|
+
payload = updated_workflow.to_json
|
143
|
+
put(url: "#{@url}workflows/#{updated_workflow.id}", payload: payload)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Delete an existing workflow from the conductor.
|
147
|
+
#
|
148
|
+
# @param [String] workflow_id The ID of the workflow to be deleted.
|
149
|
+
#
|
150
|
+
def delete_workflow(workflow_id:)
|
151
|
+
delete(url: "#{@url}workflows/#{workflow_id}")
|
152
|
+
end
|
153
|
+
|
154
|
+
# Delete all current workflows on the conductor.
|
155
|
+
#
|
156
|
+
def delete_all_workflows
|
157
|
+
wfs = workflows
|
158
|
+
wfs.each { |wf| delete_workflow(workflow_id: wf.id) }
|
159
|
+
end
|
160
|
+
|
161
|
+
# Start the specified workflow.
|
162
|
+
#
|
163
|
+
# @param [String] workflow_id The ID of the workflow to be started.
|
164
|
+
#
|
165
|
+
def start_workflow(workflow_id:)
|
166
|
+
post(url: "#{@url}workflows/#{workflow_id}/state")
|
167
|
+
end
|
168
|
+
|
169
|
+
# Stop the specified workflow.
|
170
|
+
#
|
171
|
+
# @param [String] workflow_id The ID of the workflow to be stopped.
|
172
|
+
#
|
173
|
+
def stop_workflow(workflow_id:)
|
174
|
+
delete(url: "#{@url}workflows/#{workflow_id}/state")
|
175
|
+
end
|
176
|
+
|
177
|
+
# Start all workflows that exist on the conductor.
|
178
|
+
#
|
179
|
+
# @return [Hash] A hash containing the states of all existing workflows, keyed by workflow ID.
|
180
|
+
#
|
181
|
+
def start_all_workflows
|
182
|
+
wf_states = workflow_states
|
183
|
+
|
184
|
+
wf_states.each { |wf_id, state| start_workflow(workflow_id: wf_id) if state[:workflow_state] == "STOPPED" }
|
185
|
+
workflow_states
|
186
|
+
end
|
187
|
+
|
188
|
+
# Stop all workflows that exist on the conductor.
|
189
|
+
#
|
190
|
+
# @return [Hash] A hash containing the states of all existing workflows, keyed by workflow ID.
|
191
|
+
#
|
192
|
+
def stop_all_workflows
|
193
|
+
wf_states = workflow_states
|
194
|
+
|
195
|
+
wf_states.each { |wf_id, state| stop_workflow(workflow_id: wf_id) if state[:workflow_state] == "RUNNING" }
|
196
|
+
workflow_states
|
197
|
+
end
|
198
|
+
|
199
|
+
# Returns the translated value of the specified key for a step type (defined in Eso::StepNames).
|
200
|
+
# The translated value will be based on the language settings the user has configured.
|
201
|
+
#
|
202
|
+
# @param [String] step_type The step type to query metadata for. Valid values defined in Eso::StepNames
|
203
|
+
# @param [String] key The key value in the metadata that maps to the desired label.
|
204
|
+
# @return [String] The translated value of the key.
|
205
|
+
#
|
206
|
+
def get_translation_label(step_type, key)
|
207
|
+
json_data = get(url: "#{@url}services/nexpose/metadata/#{step_type}")
|
208
|
+
|
209
|
+
target_hash = json_data[:labels].values.find { |label_hash| label_hash.has_key?(key) }
|
210
|
+
target_hash[key] if target_hash
|
211
|
+
end
|
212
|
+
|
213
|
+
# Returns the metadata key for a specified translated string.
|
214
|
+
# The translated value needs to be in language that the user has configured.
|
215
|
+
#
|
216
|
+
# @param [String] step_type The step type to query metadata for. Valid values defined in Eso::StepNames
|
217
|
+
# @param [String] label The translated value of which you are requesting the key for.
|
218
|
+
# @return [String] The metadata key corresponding to this label.
|
219
|
+
#
|
220
|
+
def get_translation_key(step_type, label)
|
221
|
+
json_data = get(url: "#{@url}services/nexpose/metadata/#{step_type}")
|
222
|
+
|
223
|
+
target_hash = json_data[:labels].values.find { |label_hash| label_hash.values.include?(label) }
|
224
|
+
target_hash.key(label).to_s if target_hash
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -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
|