abide_dev_utils 0.6.0 → 0.9.3

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.
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
3
4
  require 'yaml'
4
5
  require 'selenium-webdriver'
5
6
  require 'abide_dev_utils/errors/comply'
6
7
  require 'abide_dev_utils/gcloud'
7
8
  require 'abide_dev_utils/output'
8
9
  require 'abide_dev_utils/prompt'
10
+ require 'pry'
9
11
 
10
12
  module AbideDevUtils
11
13
  # Holds module methods and a class for dealing with Puppet Comply
@@ -16,56 +18,55 @@ module AbideDevUtils
16
18
  ReportScraper.new(url, config, **opts).build_report(password)
17
19
  end
18
20
 
19
- def self.check_for_regressions(url, password, config = nil, **opts)
20
- current_report = build_report(url, password, config, **opts)
21
- last_report = if opts.fetch(:remote_report_storage, '') == 'gcloud'
22
- fetch_report
21
+ def self.compare_reports(report_a, report_b, **opts)
22
+ report_name = opts.fetch(:report_name, nil)
23
+ current_report = ScanReport.new.from_yaml(report_a)
24
+ last_report = if opts.fetch(:remote_storage, '') == 'gcloud'
25
+ report_name = report_b if report_name.nil?
26
+ ScanReport.new.from_yaml(ScanReport.fetch_report(name: report_b))
23
27
  else
24
- File.open(opts[:last_report], 'r', &:read)
28
+ report_name = File.basename(report_b) if report_name.nil?
29
+ ScanReport.new.from_yaml(File.read(report_b))
25
30
  end
26
- result, details = good_comparison?(report_comparison(current_report, last_report))
31
+ result, details = current_report.report_comparison(last_report, check_goodness: true)
27
32
  if result
28
- puts 'A-OK'
33
+ AbideDevUtils::Output.simple('No negative differences detected...')
34
+ AbideDevUtils::Output.simple(JSON.pretty_generate(details))
29
35
  else
30
- puts 'Uh-Oh'
31
- puts details
36
+ AbideDevUtils::Output.simple('Negative differences detected!', stream: $stderr)
37
+ AbideDevUtils::Output.simple(JSON.pretty_generate(details), stream: $stderr)
32
38
  end
39
+ if opts.fetch(:upload, false) && !opts.fetch(:remote_storage, '').empty? && !report_name.nil?
40
+ AbideDevUtils::Output.simple('Uploading current report...')
41
+ ScanReport.upload_report(File.expand_path(report_a), name: report_name)
42
+ AbideDevUtils::Output.simple('Successfully uploaded report.')
43
+ end
44
+ result
33
45
  end
34
46
 
35
47
  # Class that uses Selenium WebDriver to gather scan reports from Puppet Comply
36
48
  class ReportScraper
49
+ attr_reader :timeout,
50
+ :username,
51
+ :status,
52
+ :ignorelist,
53
+ :onlylist,
54
+ :max_pagination,
55
+ :screenshot_on_error,
56
+ :page_source_on_error
57
+
37
58
  def initialize(url, config = nil, **opts)
38
59
  @url = url
39
60
  @config = config
40
61
  @opts = opts
41
- end
42
-
43
- def timeout
44
- @timeout ||= fetch_option(:timeout, 10).to_i
45
- end
46
-
47
- def username
48
- @username ||= fetch_option(:username, 'comply')
49
- end
50
-
51
- def status
52
- @status ||= fetch_option(:status)
53
- end
54
-
55
- def ignorelist
56
- @ignorelist ||= fetch_option(:ignorelist, [])
57
- end
58
-
59
- def onlylist
60
- @onlylist ||= fetch_option(:onlylist, [])
61
- end
62
-
63
- def screenshot_on_error
64
- @screenshot_on_error ||= fetch_option(:screenshot_on_error, true)
65
- end
66
-
67
- def page_source_on_error
68
- @page_source_on_error ||= fetch_option(:page_source_on_error, true)
62
+ @timeout = fetch_option(:timeout, 10).to_i
63
+ @username = fetch_option(:username, 'comply')
64
+ @status = fetch_option(:status)
65
+ @ignorelist = fetch_option(:ignorelist, [])
66
+ @onlylist = fetch_option(:onlylist, [])
67
+ @max_pagination = fetch_option(:max_pagination, 5).to_i
68
+ @screenshot_on_error = fetch_option(:screenshot_on_error, false)
69
+ @page_source_on_error = fetch_option(:page_source_on_error, false)
69
70
  end
70
71
 
71
72
  def build_report(password)
@@ -119,6 +120,7 @@ module AbideDevUtils
119
120
  --headless
120
121
  --test-type
121
122
  --disable-gpu
123
+ --no-sandbox
122
124
  --no-first-run
123
125
  --no-default-browser-check
124
126
  --ignore-certificate-errors
@@ -133,27 +135,37 @@ module AbideDevUtils
133
135
  subject.find_element(**kwargs)
134
136
  end
135
137
 
136
- def wait_on(ignore_nse: false, ignore: [Selenium::WebDriver::Error::NoSuchElementError], &block)
138
+ def find_elements(subject = driver, **kwargs)
139
+ driver.manage.window.resize_to(1920, 1080)
140
+ subject.find_elements(**kwargs)
141
+ end
142
+
143
+ def wait_on(timeout: @timeout,
144
+ ignore_nse: false,
145
+ quit_driver: true,
146
+ quiet: false,
147
+ ignore: [Selenium::WebDriver::Error::NoSuchElementError],
148
+ &block)
137
149
  raise 'wait_on must be passed a block' unless block
138
150
 
139
151
  value = nil
140
152
  if ignore_nse
141
153
  begin
142
- Selenium::WebDriver::Wait.new(ignore: [], timeout: timeout).until do
154
+ Selenium::WebDriver::Wait.new(ignore: [], timeout: timeout, interval: 1).until do
143
155
  value = yield
144
156
  end
145
157
  rescue Selenium::WebDriver::Error::NoSuchElementError
146
158
  return value
147
- rescue => e
148
- raise_error(e)
159
+ rescue StandardError => e
160
+ raise_error(e, AbideDevUtils::Comply::WaitOnError, quit_driver: quit_driver, quiet: quiet)
149
161
  end
150
162
  else
151
163
  begin
152
- Selenium::WebDriver::Wait.new(ignore: ignore, timeout: timeout).until do
164
+ Selenium::WebDriver::Wait.new(ignore: ignore, timeout: timeout, interval: 1).until do
153
165
  value = yield
154
166
  end
155
- rescue => e
156
- raise_error(e)
167
+ rescue StandardError => e
168
+ raise_error(e, AbideDevUtils::Comply::WaitOnError, quit_driver: quit_driver, quiet: quiet)
157
169
  end
158
170
  end
159
171
  value
@@ -169,20 +181,21 @@ module AbideDevUtils
169
181
  FileUtils.mkdir_p path
170
182
  end
171
183
 
172
- def raise_error(err)
173
- output.simple 'Something went wrong!'
184
+ def raise_error(original, err_class = nil, quit_driver: true, quiet: false)
185
+ output.simple 'Something went wrong!' unless quiet
174
186
  if screenshot_on_error
175
- output.simple 'Taking a screenshot of current page state...'
187
+ output.simple 'Taking a screenshot of current page state...' unless quiet
176
188
  screenshot
177
189
  end
178
190
 
179
191
  if page_source_on_error
180
- output.simple 'Saving page source of current page...'
192
+ output.simple 'Saving page source of current page...' unless quiet
181
193
  page_source
182
194
  end
183
195
 
184
- driver.quit
185
- raise err
196
+ driver.quit if quit_driver
197
+ actual_err_class = err_class.nil? ? original.class : err_class
198
+ raise actual_err_class, original.message
186
199
  end
187
200
 
188
201
  def screenshot
@@ -223,15 +236,59 @@ module AbideDevUtils
223
236
  error_text = wait_on(ignore_nse: true) { find_element(class: 'kc-feedback-text').text }
224
237
  return if error_text.nil? || error_text.empty?
225
238
 
226
- raise ComplyLoginFailedError, error_text
239
+ raise AbideDevUtils::Comply::ComplyLoginFailedError, error_text
240
+ end
241
+
242
+ def filter_node_report_links(node_report_links)
243
+ if onlylist.empty? && ignorelist.empty?
244
+ output.simple 'No filters set, using all node reports...'
245
+ return node_report_links
246
+ end
247
+
248
+ unless onlylist.empty?
249
+ output.simple 'Onlylist found, filtering node reports...'
250
+ return node_report_links.select { |l| onlylist.include?(l[:name]) }
251
+ end
252
+
253
+ output.simple 'Ignorelist found, filtering node reports...'
254
+ node_report_links.reject { |l| ignorelist.include?(l[:name]) }
255
+ end
256
+
257
+ def find_node_report_table(subject)
258
+ wait_on { find_element(subject, class: 'metric-containers-failed-hosts-count') }
259
+ hosts = find_element(subject, class: 'metric-containers-failed-hosts-count')
260
+ table = find_element(hosts, class: 'rc-table')
261
+ wait_on { find_element(table, tag_name: 'tbody') }
262
+ find_element(table, tag_name: 'tbody')
263
+ end
264
+
265
+ def wait_for_node_report_links(table_body)
266
+ wait_on(timeout: 2, quit_driver: false, quiet: true) { table_body.find_element(tag_name: 'a') }
267
+ output.simple 'Found node report links...'
268
+ table_body.find_elements(tag_name: 'a')
269
+ rescue AbideDevUtils::Comply::WaitOnError
270
+ []
227
271
  end
228
272
 
229
273
  def find_node_report_links
230
274
  output.simple 'Finding nodes with scan reports...'
231
- hosts = wait_on { find_element(class: 'metric-containers-failed-hosts-count') }
232
- table = find_element(hosts, class: 'rc-table')
233
- table_body = find_element(table, tag_name: 'tbody')
234
- wait_on { table_body.find_elements(tag_name: 'a') }
275
+ node_report_links = []
276
+ (1..max_pagination).each do |page|
277
+ output.simple "Trying page #{page}..."
278
+ driver.get("#{@url}/dashboard?page=#{page}&limit=50")
279
+ table_body = find_node_report_table(driver)
280
+ elems = wait_for_node_report_links(table_body)
281
+ if elems.empty?
282
+ output.simple "No links found on page #{page}, stopping search..."
283
+ break
284
+ end
285
+
286
+ elems.each do |elem|
287
+ node_report_links << { name: elem.text, url: elem.attribute('href') }
288
+ end
289
+ end
290
+ driver.get(@url)
291
+ filter_node_report_links(node_report_links)
235
292
  end
236
293
 
237
294
  def connect(password)
@@ -249,67 +306,69 @@ module AbideDevUtils
249
306
  nstr
250
307
  end
251
308
 
309
+ def wait_on_element_and_increment(subject = driver, **element_id)
310
+ element = wait_on { find_element(subject, **element_id) }
311
+ progress.increment
312
+ element
313
+ end
314
+
315
+ def wait_on_elements_and_increment(subject = driver, **element_id)
316
+ elements = wait_on { find_elements(subject, **element_id) }
317
+ progress.increment
318
+ elements
319
+ end
320
+
252
321
  def scrape_report
253
322
  output.simple 'Building scan reports, this may take a while...'
254
323
  all_checks = {}
255
324
  original_window = driver.window_handle
256
- if !onlylist.empty?
257
- node_report_links.reject! { |l| !onlylist.include?(l.text) }
258
- elsif !ignorelist.empty?
259
- node_report_links.reject! { |l| ignorelist.include?(l.text) }
260
- end
261
325
  node_report_links.each do |link|
262
- begin
263
- node_name = link.text
264
- new_progress(node_name)
265
- link_url = link.attribute('href')
266
- driver.manage.new_window(:tab)
326
+ node_name = link[:name]
327
+ link_url = link[:url]
328
+ new_progress(node_name)
329
+ driver.manage.new_window(:tab)
330
+ progress.increment
331
+ wait_on { driver.window_handles.length == 2 }
332
+ progress.increment
333
+ driver.switch_to.window driver.window_handles[1]
334
+ driver.get(link_url)
335
+ wait_on_element_and_increment(class: 'details-header')
336
+ wait_on_element_and_increment(class: 'details-scan-info')
337
+ wait_on_element_and_increment(class: 'details-table')
338
+ report = { 'scan_results' => {} }
339
+ scan_info_table = wait_on_element_and_increment(class: 'details-scan-info')
340
+ scan_info_table_rows = wait_on_elements_and_increment(scan_info_table, tag_name: 'tr')
341
+ check_table_body = wait_on_element_and_increment(tag_name: 'tbody')
342
+ check_table_rows = wait_on_elements_and_increment(check_table_body, tag_name: 'tr')
343
+ scan_info_table_rows.each do |row|
344
+ key = find_element(row, tag_name: 'h5').text
345
+ value = find_element(row, tag_name: 'strong').text
346
+ report[key.downcase.tr(':', '').tr(' ', '_')] = value
267
347
  progress.increment
268
- wait_on { driver.window_handles.length == 2 }
269
- progress.increment
270
- driver.switch_to.window driver.window_handles[1]
271
- driver.get(link_url)
272
- wait_on { find_element(class: 'details-scan-info') }
273
- progress.increment
274
- wait_on { find_element(class: 'details-table') }
275
- progress.increment
276
- report = { 'scan_results' => {} }
277
- scan_info_table = find_element(class: 'details-scan-info')
278
- scan_info_table_rows = scan_info_table.find_elements(tag_name: 'tr')
279
- progress.increment
280
- check_table_body = find_element(tag_name: 'tbody')
281
- check_table_rows = check_table_body.find_elements(tag_name: 'tr')
282
- progress.increment
283
- scan_info_table_rows.each do |row|
284
- key = find_element(row, tag_name: 'h5').text
285
- value = find_element(row, tag_name: 'strong').text
286
- report[key.downcase.tr(':', '').tr(' ', '_')] = value
287
- progress.increment
288
- end
289
- check_table_rows.each do |row|
290
- chk_objs = row.find_elements(tag_name: 'td')
291
- chk_objs.map!(&:text)
292
- if status.nil? || status.include?(chk_objs[1].downcase)
293
- name_parts = chk_objs[0].match(/^([0-9.]+) (.+)$/)
294
- key = normalize_cis_rec_name(name_parts[2])
295
- unless report['scan_results'].key?(chk_objs[1])
296
- report['scan_results'][chk_objs[1]] = {}
297
- end
298
- report['scan_results'][chk_objs[1]][key] = {
299
- 'name' => name_parts[2].chomp,
300
- 'number' => name_parts[1].chomp
301
- }
348
+ end
349
+ check_table_rows.each do |row|
350
+ chk_objs = row.find_elements(tag_name: 'td')
351
+ chk_objs.map!(&:text)
352
+ if status.nil? || status.include?(chk_objs[1].downcase)
353
+ name_parts = chk_objs[0].match(/^([0-9.]+) (.+)$/)
354
+ key = normalize_cis_rec_name(name_parts[2])
355
+ unless report['scan_results'].key?(chk_objs[1])
356
+ report['scan_results'][chk_objs[1]] = {}
302
357
  end
303
- progress.increment
358
+ report['scan_results'][chk_objs[1]][key] = {
359
+ 'name' => name_parts[2].chomp,
360
+ 'number' => name_parts[1].chomp
361
+ }
304
362
  end
305
- all_checks[node_name] = report
306
- driver.close
307
- output.simple "Created report for #{node_name}"
308
- rescue => e
309
- raise_error(e)
310
- ensure
311
- driver.switch_to.window original_window
363
+ progress.increment
312
364
  end
365
+ all_checks[node_name] = report
366
+ driver.close
367
+ output.simple "Created report for #{node_name}"
368
+ rescue ::StandardError => e
369
+ raise_error(e)
370
+ ensure
371
+ driver.switch_to.window original_window
313
372
  end
314
373
  all_checks
315
374
  end
@@ -317,6 +376,8 @@ module AbideDevUtils
317
376
 
318
377
  # Contains multiple NodeScanReport objects
319
378
  class ScanReport
379
+ attr_reader :node_scan_reports
380
+
320
381
  def from_yaml(report)
321
382
  @scan_report = if report.is_a? Hash
322
383
  report
@@ -325,7 +386,65 @@ module AbideDevUtils
325
386
  else
326
387
  YAML.safe_load(report)
327
388
  end
328
- build_node_scan_reports
389
+ @node_scan_reports = build_node_scan_reports
390
+ self
391
+ end
392
+
393
+ def to_h
394
+ node_scan_reports.each_with_object({}) do |node, h|
395
+ h[node.name] = node.hash
396
+ end
397
+ end
398
+
399
+ def to_yaml
400
+ to_h.to_yaml
401
+ end
402
+
403
+ def self.storage_bucket
404
+ @storage_bucket ||= AbideDevUtils::GCloud.storage_bucket
405
+ end
406
+
407
+ def self.fetch_report(name: 'comply_report.yaml')
408
+ report = storage_bucket.file(name)
409
+ report.download.read
410
+ end
411
+
412
+ def self.upload_report(report, name: 'comply_report.yaml')
413
+ storage_bucket.create_file(report, name)
414
+ end
415
+
416
+ def report_comparison(other, check_goodness: false)
417
+ comparison = []
418
+ node_scan_reports.zip(other.node_scan_reports).each do |cr, lr|
419
+ comparison << { cr.name => { diff: {}, node_presense: :new } } if lr.nil?
420
+ comparison << { lr.name => { diff: {}, node_presense: :dropped } } if cr.nil?
421
+ comparison << { cr.name => { diff: cr.diff(lr), node_presence: :same } } unless cr.nil? || lr.nil?
422
+ end
423
+ comparison.inject(&:merge)
424
+ return good_comparison?(comparison) if check_goodness
425
+
426
+ compairison
427
+ end
428
+
429
+ def good_comparison?(report_comparison)
430
+ good = true
431
+ not_good = {}
432
+ report_comparison.each do |node_report|
433
+ node_name = node_report.keys[0]
434
+ report = node_report[node_name]
435
+ next if report[:diff].empty?
436
+
437
+ not_good[node_name] = {}
438
+ unless report.dig(:diff, :passing, :other).nil?
439
+ good = false
440
+ not_good[node_name][:new_not_passing] = report[:diff][:passing][:other]
441
+ end
442
+ unless report.dig(:diff, :failing, :self).nil?
443
+ good = false
444
+ not_good[node_name][:new_failing] = report[:diff][:failing][:self]
445
+ end
446
+ end
447
+ [good, not_good]
329
448
  end
330
449
 
331
450
  private
@@ -341,20 +460,22 @@ module AbideDevUtils
341
460
 
342
461
  # Class representation of a Comply node scan report
343
462
  class NodeScanReport
344
- attr_reader :name, :passing, :failing, :not_checked, :informational, :benchmark, :last_scan, :profile
463
+ attr_reader :name, :passing, :failing, :error, :not_checked, :informational, :benchmark, :last_scan, :profile
345
464
 
346
- DIFF_PROPERTIES = %i[passing failing not_checked informational].freeze
465
+ DIFF_PROPERTIES = %i[passing failing error not_checked informational].freeze
347
466
 
348
467
  def initialize(node_name, node_hash)
349
468
  @name = node_name
350
469
  @hash = node_hash
351
470
  @passing = node_hash.dig('scan_results', 'Pass') || {}
352
471
  @failing = node_hash.dig('scan_results', 'Fail') || {}
472
+ @error = node_hash.dig('scan_results', 'Error') || {}
353
473
  @not_checked = node_hash.dig('scan_results', 'Not checked') || {}
354
474
  @informational = node_hash.dig('scan_results', 'Informational') || {}
355
475
  @benchmark = node_hash['benchmark']
356
476
  @last_scan = node_hash['last_scan']
357
477
  @profile = node_hash.fetch('custom_profile', nil) || node_hash.fetch('profile', nil)
478
+ create_equality_methods
358
479
  end
359
480
 
360
481
  def diff(other)
@@ -365,21 +486,17 @@ module AbideDevUtils
365
486
  diff
366
487
  end
367
488
 
368
- def method_missing(method_name, *args, &_block)
369
- case method_name
370
- when method_name.match?(/^(passing|failing|not_checked|informational)_equal?$/)
371
- property_equal?(method_name.delete_suffix('_equal?'), *args)
372
- when method_name.match?(/^(to_h|to_yaml)$/)
373
- @hash.send(method_name.to_sym)
374
- end
375
- end
489
+ private
376
490
 
377
- def respond_to_missing?(method_name, _include_private = false)
378
- method_name.match?(/^(((passing|failing|not_checked|informational)_equal?)|to_h|to_yaml)$/)
491
+ def create_equality_methods
492
+ DIFF_PROPERTIES.each do |prop|
493
+ meth_name = "#{prop.to_s}_equal?"
494
+ self.class.define_method(meth_name) do |other|
495
+ property_equal?(prop, other)
496
+ end
497
+ end
379
498
  end
380
499
 
381
- private
382
-
383
500
  def property_diff(property, other)
384
501
  {
385
502
  self: send(property).keys - other.send(property).keys,
@@ -388,54 +505,8 @@ module AbideDevUtils
388
505
  end
389
506
 
390
507
  def property_equal?(property, other_property)
391
- send(property.to_sym) == other_property
392
- end
393
- end
394
-
395
- def self.storage_bucket
396
- @storage_bucket ||= AbideDevUtils::GCloud.storage_bucket
397
- end
398
-
399
- def self.fetch_report
400
- report = storage_bucket.file('comply_report.yaml')
401
- report.download.read
402
- end
403
-
404
- def self.upload_report(report)
405
- file_to_upload = report.is_a?(Hash) ? report.to_yaml : report
406
- storage_bucket.create_file(file_to_upload, 'comply_report.yaml')
407
- end
408
-
409
- def self.report_comparison(current, last)
410
- current_report = ScanReport.new.from_yaml(current)
411
- last_report = ScanReport.new.from_yaml(last)
412
-
413
- comparison = []
414
- current_report.zip(last_report).each do |cr, lr|
415
- comparison << { cr.name => { diff: {}, node_presense: :new } } if lr.nil?
416
- comparison << { lr.name => { diff: {}, node_presense: :dropped } } if cr.nil?
417
- comparison << { cr.name => { diff: cr.diff(lr), node_presence: :same } } unless cr.nil? || lr.nil?
418
- end
419
- comparison.inject(&:merge)
420
- end
421
-
422
- def self.good_comparison?(report_comparison)
423
- good = true
424
- not_good = {}
425
- report_comparison.each do |node_name, report|
426
- next if report[:diff].empty?
427
-
428
- not_good[node_name] = {}
429
- unless report[:diff][:passing][:other].empty?
430
- good = false
431
- not_good[node_name][:new_not_passing] = report[:diff][:passing][:other]
432
- end
433
- unless report[:diff][:failing][:self].empty?
434
- good = false
435
- not_good[node_name][:new_failing] = report[:diff][:failing][:self]
436
- end
508
+ send(property) == other_property
437
509
  end
438
- [good, not_good]
439
510
  end
440
511
  end
441
512
  end
@@ -8,6 +8,10 @@ module AbideDevUtils
8
8
  class ComplyLoginFailedError < GenericError
9
9
  @default = 'Failed to login to Comply:'
10
10
  end
11
+
12
+ class WaitOnError < GenericError
13
+ @default = 'wait_on failed due to error:'
14
+ end
11
15
  end
12
16
  end
13
17
  end
@@ -29,6 +29,11 @@ module AbideDevUtils
29
29
  @default = 'Path is not a directory:'
30
30
  end
31
31
 
32
+ # Raised when a file extension is not correct
33
+ class FileExtensionIncorrectError < GenericError
34
+ @default = 'File extension does not match specified extension:'
35
+ end
36
+
32
37
  # Raised when a searched for service is not found in the parser
33
38
  class ServiceNotFoundError < GenericError
34
39
  @default = 'Service not found:'
@@ -48,5 +53,9 @@ module AbideDevUtils
48
53
  class NotHashableError < GenericError
49
54
  @default = 'Object does not respond to #to_hash or #to_h:'
50
55
  end
56
+
57
+ class CliOptionsConflict < GenericError
58
+ @default = "Console options conflict."
59
+ end
51
60
  end
52
61
  end
@@ -12,5 +12,17 @@ module AbideDevUtils
12
12
  class StrategyInvalidError < GenericError
13
13
  @default = 'Invalid strategy selected. Should be either \'name\' or \'num\''
14
14
  end
15
+
16
+ class ControlPartsError < GenericError
17
+ @default = 'Failed to extract parts from control name:'
18
+ end
19
+
20
+ class ProfilePartsError < GenericError
21
+ @default = 'Failed to extract parts from profile name:'
22
+ end
23
+
24
+ class UnsupportedXCCDFError < GenericError
25
+ @default = "XCCDF type is unsupported!"
26
+ end
15
27
  end
16
28
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
3
4
  require 'abide_dev_utils/errors/gcloud'
4
5
 
5
6
  module AbideDevUtils
@@ -14,7 +15,7 @@ module AbideDevUtils
14
15
  require 'google/cloud/storage'
15
16
  @bucket = Google::Cloud::Storage.new(
16
17
  project_id: project || ENV['ABIDE_GCLOUD_PROJECT'],
17
- credentials: credentials || ENV['ABIDE_GCLOUD_CREDENTIALS']
18
+ credentials: credentials || JSON.parse(ENV['ABIDE_GCLOUD_CREDENTIALS'])
18
19
  ).bucket(name || ENV['ABIDE_GCLOUD_BUCKET'])
19
20
  end
20
21
  end
@@ -22,9 +22,13 @@ module AbideDevUtils
22
22
  end
23
23
 
24
24
  def self.yaml(in_obj, console: false, file: nil)
25
- AbideDevUtils::Validate.hashable(in_obj)
26
- # Use object's #to_yaml method if it exists, convert to hash if not
27
- yaml_out = in_obj.respond_to?(:to_yaml) ? in_obj.to_yaml : in_obj.to_h.to_yaml
25
+ yaml_out = if in_obj.is_a? String
26
+ in_obj
27
+ else
28
+ AbideDevUtils::Validate.hashable(in_obj)
29
+ # Use object's #to_yaml method if it exists, convert to hash if not
30
+ in_obj.respond_to?(:to_yaml) ? in_obj.to_yaml : in_obj.to_h.to_yaml
31
+ end
28
32
  simple(yaml_out) if console
29
33
  FWRITER.write_yaml(yaml_out, file: file) unless file.nil?
30
34
  end