abide_dev_utils 0.2.3 → 0.5.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 +4 -4
- data/.dockerignore +1 -0
- data/Dockerfile +23 -0
- data/README.md +20 -0
- data/abide_dev_utils.gemspec +2 -0
- data/lib/abide_dev_utils/cli.rb +2 -0
- data/lib/abide_dev_utils/cli/abstract.rb +2 -0
- data/lib/abide_dev_utils/cli/comply.rb +97 -0
- data/lib/abide_dev_utils/cli/jira.rb +4 -2
- data/lib/abide_dev_utils/cli/puppet.rb +11 -2
- data/lib/abide_dev_utils/cli/test.rb +1 -1
- data/lib/abide_dev_utils/cli/xccdf.rb +7 -3
- data/lib/abide_dev_utils/comply.rb +130 -0
- data/lib/abide_dev_utils/config.rb +24 -1
- data/lib/abide_dev_utils/errors/xccdf.rb +4 -0
- data/lib/abide_dev_utils/jira.rb +17 -0
- data/lib/abide_dev_utils/ppt/new_obj.rb +86 -47
- data/lib/abide_dev_utils/resources/generic_spec.erb +13 -0
- data/lib/abide_dev_utils/version.rb +1 -1
- data/lib/abide_dev_utils/xccdf.rb +1 -1
- data/lib/abide_dev_utils/xccdf/cis/hiera.rb +22 -7
- metadata +35 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a27976b9f740b67261fa080eeba927bc6fc98e73ffb592fafdd91d4d612cc51f
|
4
|
+
data.tar.gz: 64778a0d476e2f96d70a14ab318b517c597aa3c5e33afd8939173385b013fe6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e31df40e6dd34a57156ff517d39fcc036f5655ce2f31bf86b1ebb66754304575b7379e0a3751ae378bc81bc1520dbe095255012dc7e10b24e4f6c3f4a85e6551
|
7
|
+
data.tar.gz: c9dd204d55a37d389c0c8a4d3d281310b87241cbbd149ca029a3fa6a38fd8414bcb350467cd348cdd330fe946e6ee75625bfe2828319ad25d9eb8ed5cc37a9a3
|
data/.dockerignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/Dockerfile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
FROM ruby:2.7.3-alpine
|
2
|
+
|
3
|
+
ARG version
|
4
|
+
|
5
|
+
RUN mkdir /extvol && \
|
6
|
+
apk update && \
|
7
|
+
apk add git build-base
|
8
|
+
|
9
|
+
VOLUME /extvol
|
10
|
+
|
11
|
+
WORKDIR /usr/src/app
|
12
|
+
|
13
|
+
RUN mkdir -p ./lib/abide_dev_utils/
|
14
|
+
COPY Gemfile abide_dev_utils.gemspec ./
|
15
|
+
COPY lib/abide_dev_utils/version.rb lib/abide_dev_utils
|
16
|
+
RUN bundle install
|
17
|
+
|
18
|
+
COPY . .
|
19
|
+
|
20
|
+
RUN bundle exec rake build && \
|
21
|
+
gem install pkg/abide_dev_utils-${version}.gem
|
22
|
+
|
23
|
+
ENTRYPOINT [ "abide" ]
|
data/README.md
CHANGED
@@ -29,6 +29,10 @@ Issues and pull requests are welcome!
|
|
29
29
|
|
30
30
|
* Create Jira issues in bulk from coverage reports
|
31
31
|
|
32
|
+
### Puppet Comply Report Generation
|
33
|
+
|
34
|
+
* Allows you ot programatically generate compliance reports from Puppet Comply
|
35
|
+
|
32
36
|
### Supports Configuration via Local YAML file
|
33
37
|
|
34
38
|
* Fully configurable via the `~/.abide_dev.yaml` file
|
@@ -128,6 +132,8 @@ Install the gem:
|
|
128
132
|
* `--absolute-template-dir`, `-A` - Allows you to specify an absolute path with `--template-dir`. This is useful if your template directory is not relative to your module's root directory
|
129
133
|
* `--template-name`, `-n` - Allows you to specify a template name if it is different than the `TYPE` parameter
|
130
134
|
* `--vars`, `-V` - Comma-separated key=value pairs to pass in to the template renderer. This allows you to pass arbitrary values that can be used in your templates.
|
135
|
+
* `--spec-template`, `-S` - Path to an ERB template to use for rspec test generation instead of the default
|
136
|
+
* `--force`, `-f` - Skips any prompts and executes the command
|
131
137
|
|
132
138
|
`abide puppet new` exposes a few variables for you to use in your templates by default:
|
133
139
|
|
@@ -179,8 +185,10 @@ $ ls manifests
|
|
179
185
|
init.pp
|
180
186
|
$ abide puppet new control_class 'test_module::controls::test_new_control'
|
181
187
|
Created file /Users/the.dude/test_module/manifests/controls/test_new_control.pp
|
188
|
+
Created file /Users/the.dude/test_module/spec/classes/controls/test_new_control_spec.rb
|
182
189
|
$ abide puppet new util_class 'test_module::utils::test_new_util' -v 'testvar1=dude,testvar2=sweet'
|
183
190
|
Created file /Users/the.dude/test_module/manifests/utils/test_new_util.pp
|
191
|
+
Created file /Users/the.dude/test_module/spec/classes/utils/test_new_util_spec.rb
|
184
192
|
$ cat manifests/controls/test_new_control.pp
|
185
193
|
# @api private
|
186
194
|
class test_module::controls::test_new_control (
|
@@ -204,6 +212,9 @@ class test_module::utils::test_new_util (
|
|
204
212
|
|
205
213
|
```
|
206
214
|
|
215
|
+
**NOTE**: You can use two special prefixes on your template files to denote where the rspec test should be generated for that object.
|
216
|
+
If the prefix `c-` is used, the test will be generated in the `spec/classes` directory. If the prefix `d-` is used, the test will be generated in the `spec/defines` directory. For example, to create a template for a defined type, name the template something like this: `d-my_defined_type.pp.erb`.
|
217
|
+
|
207
218
|
### XCCDF Command Reference
|
208
219
|
|
209
220
|
#### to_hiera
|
@@ -224,6 +235,15 @@ NOTE: When converting XCCDF files to Hiera, control names are sanitized. This me
|
|
224
235
|
* `--out-file`, `-o` - A path to a file where you would like to save the generated Hiera
|
225
236
|
* `--parent-key-prefix`, `-p` - Allows you to append a prefix to all top-level Hiera keys
|
226
237
|
|
238
|
+
## Docker
|
239
|
+
|
240
|
+
A Dockerfile has been provided in this repo for convenience since Ruby environments can be painful to deal with. To abide_dev_utils with Docker:
|
241
|
+
|
242
|
+
* Build the Dockerfile: `docker build . -t abide_dev_utils --build-arg version=<semver>`
|
243
|
+
* Run the commands using the container: `docker run -it abide_dev_utils --help`
|
244
|
+
* The container declares a volume for external resources such as files. To use the volume, add the following flag to your `docker run` commands: `-v /path/to/my/files:/extvol`
|
245
|
+
* When using the volume, all paths should be absolute based on the root directory `/extvol`
|
246
|
+
|
227
247
|
## Development
|
228
248
|
|
229
249
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/abide_dev_utils.gemspec
CHANGED
@@ -37,10 +37,12 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.add_dependency 'puppet', '>= 6.19'
|
38
38
|
spec.add_dependency 'jira-ruby', '~> 2.1'
|
39
39
|
spec.add_dependency 'ruby-progressbar', '~> 1.11'
|
40
|
+
spec.add_dependency 'selenium-webdriver', '~> 4.0.0.beta4'
|
40
41
|
|
41
42
|
# Dev dependencies
|
42
43
|
spec.add_development_dependency 'bundler'
|
43
44
|
spec.add_development_dependency 'rake'
|
45
|
+
spec.add_development_dependency 'console'
|
44
46
|
spec.add_development_dependency 'github_changelog_generator'
|
45
47
|
spec.add_development_dependency 'gem-release'
|
46
48
|
spec.add_development_dependency 'rspec', '~> 3.10'
|
data/lib/abide_dev_utils/cli.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'cmdparse'
|
4
4
|
require 'abide_dev_utils/version'
|
5
5
|
require 'abide_dev_utils/constants'
|
6
|
+
require 'abide_dev_utils/cli/comply'
|
6
7
|
require 'abide_dev_utils/cli/puppet'
|
7
8
|
require 'abide_dev_utils/cli/xccdf'
|
8
9
|
require 'abide_dev_utils/cli/test'
|
@@ -21,6 +22,7 @@ module Abide
|
|
21
22
|
parser.main_options.banner = ROOT_CMD_BANNER
|
22
23
|
parser.add_command(CmdParse::HelpCommand.new, default: true)
|
23
24
|
parser.add_command(CmdParse::VersionCommand.new(add_switches: true))
|
25
|
+
parser.add_command(ComplyCommand.new)
|
24
26
|
parser.add_command(PuppetCommand.new)
|
25
27
|
parser.add_command(XccdfCommand.new)
|
26
28
|
parser.add_command(TestCommand.new)
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'abide_dev_utils/comply'
|
4
|
+
require 'abide_dev_utils/cli/abstract'
|
5
|
+
|
6
|
+
module Abide
|
7
|
+
module CLI
|
8
|
+
class ComplyCommand < AbideCommand
|
9
|
+
CMD_NAME = 'comply'
|
10
|
+
CMD_SHORT = 'Commands related to Puppet Comply'
|
11
|
+
CMD_LONG = 'Namespace for commands related to Puppet Comply'
|
12
|
+
def initialize
|
13
|
+
super(CMD_NAME, CMD_SHORT, CMD_LONG, takes_commands: true)
|
14
|
+
add_command(ComplyReportCommand.new)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ComplyReportCommand < AbideCommand
|
19
|
+
CMD_NAME = 'report'
|
20
|
+
CMD_SHORT = 'Generates a yaml report of Puppet Comply scan results'
|
21
|
+
CMD_LONG = <<~LONGCMD
|
22
|
+
Generates a yaml file that shows the scan results of all nodes in Puppet Comply.
|
23
|
+
This command utilizes Selenium WebDriver and the Google Chrome browser to automate
|
24
|
+
clicking through the Comply UI and building a report. In order to use this command,
|
25
|
+
you MUST have Google Chrome installed and you MUST install the chromedriver binary.
|
26
|
+
More info and instructions can be found here:
|
27
|
+
https://www.selenium.dev/documentation/en/getting_started_with_webdriver/.
|
28
|
+
LONGCMD
|
29
|
+
CMD_COMPLY_URL = 'The URL (including https://) of Puppet Comply'
|
30
|
+
CMD_COMPLY_PASSWORD = 'The password for Puppet Comply'
|
31
|
+
OPT_STATUS_DESC = <<~EODESC
|
32
|
+
A comma-separated list of check statuses to ONLY include in the report.
|
33
|
+
Valid statuses are: pass, fail, error, notapplicable, notchecked, unknown, informational
|
34
|
+
EODESC
|
35
|
+
OPT_IGNORE_NODES = <<~EOIGN
|
36
|
+
A comma-separated list of node certnames to ignore building reports for. This
|
37
|
+
options is mutually exclusive with --only and, if both are set, --only will take precedence
|
38
|
+
over this option.
|
39
|
+
EOIGN
|
40
|
+
OPT_ONLY_NODES = <<~EOONLY
|
41
|
+
A comma-separated list of node certnames to ONLY build reports for. No other
|
42
|
+
nodes will have reports built for them except the ones specified. This option
|
43
|
+
is mutually exclusive with --ignore and, if both are set, this options will
|
44
|
+
take precedence over --ignore.
|
45
|
+
EOONLY
|
46
|
+
def initialize
|
47
|
+
super(CMD_NAME, CMD_SHORT, CMD_LONG, takes_commands: false)
|
48
|
+
argument_desc(COMPLY_URL: CMD_COMPLY_URL, COMPLY_PASSWORD: CMD_COMPLY_PASSWORD)
|
49
|
+
options.on('-o [FILE]', '--out-file [FILE]', 'Path to save the report') { |f| @data[:file] = f }
|
50
|
+
options.on('-u [USERNAME]', '--username [USERNAME]', 'The username for Comply (defaults to comply)') do |u|
|
51
|
+
@data[:username] = u
|
52
|
+
end
|
53
|
+
options.on('-s [STATUS]', '--status [STATUS]', OPT_STATUS_DESC) do |s|
|
54
|
+
status_array = s.nil? ? nil : s.split(',').map(&:downcase)
|
55
|
+
status_array&.map! { |i| i == 'notchecked' ? 'not checked' : i }
|
56
|
+
@data[:status] = status_array
|
57
|
+
end
|
58
|
+
options.on('-O [CERTNAME]', '--only [CERTNAME]', OPT_ONLY_NODES) do |o|
|
59
|
+
only_array = o.nil? ? nil : s.split(',').map(&:downcase)
|
60
|
+
@data[:only] = only_array
|
61
|
+
end
|
62
|
+
options.on('-I [CERTNAME]', '--ignore [CERTNAME]', OPT_IGNORE_NODES) do |i|
|
63
|
+
ignore_array = i.nil? ? nil : i.split(',').map(&:downcase)
|
64
|
+
@data[:ignore] = ignore_array
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def help_arguments
|
69
|
+
<<~ARGHELP
|
70
|
+
Arguments:
|
71
|
+
COMPLY_URL #{CMD_COMPLY_URL}
|
72
|
+
COMPLY_PASSWORD #{CMD_COMPLY_PASSWORD}
|
73
|
+
|
74
|
+
ARGHELP
|
75
|
+
end
|
76
|
+
|
77
|
+
def execute(comply_url = nil, comply_password = nil)
|
78
|
+
Abide::CLI::VALIDATE.filesystem_path(`command -v chromedriver`.strip)
|
79
|
+
conf = config_section('comply')
|
80
|
+
comply_url = conf.fetch(:url) if comply_url.nil?
|
81
|
+
comply_password = comply_password.nil? ? conf.fetch(:password, Abide::CLI::PROMPT.password) : comply_password
|
82
|
+
username = @data.fetch(:username, nil).nil? ? conf.fetch(:username, 'comply') : @data[:username]
|
83
|
+
status = @data.fetch(:status, nil).nil? ? conf.fecth(:status, nil) : @data[:status]
|
84
|
+
ignorelist = @data.fetch(:ignore, nil).nil? ? conf.fetch(:ignore, nil) : @data[:ignore]
|
85
|
+
onlylist = @data.fetch(:only, nil).nil? ? conf.fetch(:only, nil) : @data[:only]
|
86
|
+
report = AbideDevUtils::Comply.scan_report(comply_url,
|
87
|
+
comply_password,
|
88
|
+
username: username,
|
89
|
+
status: status,
|
90
|
+
ignorelist: ignorelist,
|
91
|
+
onlylist: onlylist)
|
92
|
+
outfile = @data.fetch(:file, nil).nil? ? conf.fetch(:report_path, 'comply_scan_report.yaml') : @data[:file]
|
93
|
+
Abide::CLI::OUTPUT.yaml(report, file: outfile)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'json'
|
4
|
+
require 'abide_dev_utils/config'
|
4
5
|
require 'abide_dev_utils/jira'
|
5
6
|
|
6
7
|
module Abide
|
7
8
|
module CLI
|
9
|
+
CONFIG = AbideDevUtils::Config
|
8
10
|
JIRA = AbideDevUtils::Jira
|
9
11
|
|
10
12
|
class JiraCommand < CmdParse::Command
|
@@ -57,8 +59,8 @@ module Abide
|
|
57
59
|
def execute(issue)
|
58
60
|
client = JIRA.client(options: {})
|
59
61
|
issue = client.Issue.find(issue)
|
60
|
-
console = @data[:file].nil?
|
61
|
-
out_json = issue.attrs.select { |_,v| !v.nil? || !v.empty? }
|
62
|
+
console = @data[:file].nil?
|
63
|
+
out_json = issue.attrs.select { |_, v| !v.nil? || !v.empty? }
|
62
64
|
Abide::CLI::OUTPUT.json(out_json, console: console, file: @data[:file])
|
63
65
|
end
|
64
66
|
end
|
@@ -87,6 +87,16 @@ module Abide
|
|
87
87
|
'--vars [VARNAME=VALUE]',
|
88
88
|
'Allows you to specify comma-separated variable names and values that will be converted into a hash that is available for you to use in your templates'
|
89
89
|
) { |v| @data[:vars] = v }
|
90
|
+
options.on(
|
91
|
+
'-S [PATH]',
|
92
|
+
'--spec-template [PATH]',
|
93
|
+
'Path to an ERB template to use for rspec test generation instead of the default'
|
94
|
+
)
|
95
|
+
options.on(
|
96
|
+
'-f',
|
97
|
+
'--force',
|
98
|
+
'Skips any prompts and executes the command'
|
99
|
+
) { |_| @data[:force] = true }
|
90
100
|
end
|
91
101
|
|
92
102
|
def execute(type, name)
|
@@ -97,8 +107,7 @@ module Abide
|
|
97
107
|
opts: @data,
|
98
108
|
vars: @data.fetch(:vars, '').split(',').map { |i| i.split('=') }.to_h # makes the str a hash
|
99
109
|
)
|
100
|
-
|
101
|
-
Abide::CLI::OUTPUT.simple(result)
|
110
|
+
builder.build
|
102
111
|
end
|
103
112
|
end
|
104
113
|
end
|
@@ -35,10 +35,10 @@ module Abide
|
|
35
35
|
@litmus_im = [CMD_LIT_BASE, "'litmus:install_module'"]
|
36
36
|
@litmus_ap = [CMD_LIT_BASE, "'litmus:acceptance:parallel'"]
|
37
37
|
@litmus_td = [CMD_LIT_BASE, "'litmus:tear_down'"]
|
38
|
-
validate_env_and_opts
|
39
38
|
end
|
40
39
|
|
41
40
|
def execute(suite)
|
41
|
+
validate_env_and_opts
|
42
42
|
case suite.downcase
|
43
43
|
when /^a[A-Za-z]*/
|
44
44
|
run_command(@validate)
|
@@ -27,7 +27,12 @@ module Abide
|
|
27
27
|
long_desc(CMD_LONG)
|
28
28
|
options.on('-b [TYPE]', '--benchmark-type [TYPE]', 'XCCDF Benchmark type') { |b| @data[:type] = b }
|
29
29
|
options.on('-o [FILE]', '--out-file [FILE]', 'Path to save file') { |f| @data[:file] = f }
|
30
|
-
options.on('-p [PREFIX]', '--parent-key-prefix [PREFIX]', 'A prefix to append to the parent key')
|
30
|
+
options.on('-p [PREFIX]', '--parent-key-prefix [PREFIX]', 'A prefix to append to the parent key') do |p|
|
31
|
+
@data[:parent_key_prefix] = p
|
32
|
+
end
|
33
|
+
options.on('-N', '--number-fmt', 'Format Hiera control names based off of control number instead of name.') do
|
34
|
+
@data[:num] = true
|
35
|
+
end
|
31
36
|
end
|
32
37
|
|
33
38
|
def execute(xccdf_file)
|
@@ -40,8 +45,7 @@ module Abide
|
|
40
45
|
|
41
46
|
def to_hiera(xccdf_file)
|
42
47
|
xfile = AbideDevUtils::XCCDF.to_hiera(xccdf_file, @data)
|
43
|
-
console
|
44
|
-
Abide::CLI::OUTPUT.yaml(xfile, console: console, file: @data[:file])
|
48
|
+
Abide::CLI::OUTPUT.yaml(xfile, console: @data[:file].nil?, file: @data[:file])
|
45
49
|
end
|
46
50
|
end
|
47
51
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'selenium-webdriver'
|
5
|
+
require 'abide_dev_utils/output'
|
6
|
+
|
7
|
+
module AbideDevUtils
|
8
|
+
module Comply
|
9
|
+
def self.scan_report(url, password, username: 'comply', status: nil, ignorelist: nil, onlylist: nil)
|
10
|
+
begin
|
11
|
+
AbideDevUtils::Output.simple 'Starting headless Chrome...'
|
12
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
13
|
+
options.args = %w[
|
14
|
+
--headless
|
15
|
+
--test-type
|
16
|
+
--disable-gpu
|
17
|
+
--no-first-run
|
18
|
+
--no-default-browser-check
|
19
|
+
--ignore-certificate-errors
|
20
|
+
--start-maximized
|
21
|
+
]
|
22
|
+
driver = Selenium::WebDriver.for :chrome, options: options
|
23
|
+
driver.get(url)
|
24
|
+
bypass_ssl_warning_page(driver)
|
25
|
+
AbideDevUtils::Output.simple "Logging into Comply at #{url}..."
|
26
|
+
login_to_comply(driver, username: username, password: password)
|
27
|
+
AbideDevUtils::Output.simple 'Finding nodes with scan reports...'
|
28
|
+
links = find_node_report_links(driver)
|
29
|
+
AbideDevUtils::Output.simple 'Building scan reports, this may take a while...'
|
30
|
+
build_report(driver, links, status: status, ignorelist: ignorelist, onlylist: onlylist)
|
31
|
+
ensure
|
32
|
+
driver.quit
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.ignore_no_such_element
|
37
|
+
begin
|
38
|
+
yield
|
39
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
40
|
+
AbideDevUtils::Output.simple "Ignored exception #{e}", stream: $stderr
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.wait_on(timeout = 10)
|
45
|
+
Selenium::WebDriver::Wait.new(timeout: timeout).until do
|
46
|
+
yield
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.bypass_ssl_warning_page(driver)
|
51
|
+
ignore_no_such_element do
|
52
|
+
driver.find_element(id: 'details-button').click
|
53
|
+
driver.find_element(id: 'proceed-link').click
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.login_to_comply(driver, username: 'comply', password: 'compliance')
|
58
|
+
wait_on { driver.find_element(id: 'username') }
|
59
|
+
driver.find_element(id: 'username').send_keys username
|
60
|
+
driver.find_element(id: 'password').send_keys password
|
61
|
+
driver.find_element(id: 'kc-login').click
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.find_node_report_links(driver)
|
65
|
+
wait_on { driver.find_element(class: 'metric-containers-failed-hosts-count') }
|
66
|
+
hosts = driver.find_element(class: 'metric-containers-failed-hosts-count')
|
67
|
+
table = hosts.find_element(class: 'rc-table')
|
68
|
+
table_body = table.find_element(tag_name: 'tbody')
|
69
|
+
wait_on { table_body.find_element(tag_name: 'a') }
|
70
|
+
table_body.find_elements(tag_name: 'a')
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.build_report(driver, links, status: nil, ignorelist: nil, onlylist: nil)
|
74
|
+
all_checks = {}
|
75
|
+
original_window = driver.window_handle
|
76
|
+
links.each do |link|
|
77
|
+
if !onlylist.nil? && !onlylist.empty?
|
78
|
+
next unless onlylist.include?(link.text)
|
79
|
+
elsif !ignorelist.nil? && !ignorelist.empty?
|
80
|
+
next if ignorelist.include?(link.text)
|
81
|
+
end
|
82
|
+
begin
|
83
|
+
node_name = link.text
|
84
|
+
progress = AbideDevUtils::Output.progress title: "Builingd report for #{node_name}", total: nil
|
85
|
+
link_url = link.attribute('href')
|
86
|
+
driver.manage.new_window(:tab)
|
87
|
+
wait_on { driver.window_handles.length == 2 }
|
88
|
+
progress.increment
|
89
|
+
driver.switch_to.window driver.window_handles[1]
|
90
|
+
driver.get(link_url)
|
91
|
+
wait_on { driver.find_element(class: 'details-scan-info') }
|
92
|
+
progress.increment
|
93
|
+
wait_on { driver.find_element(class: 'details-table') }
|
94
|
+
progress.increment
|
95
|
+
report = {}
|
96
|
+
report['scan_results'] = {}
|
97
|
+
scan_info_table = driver.find_element(class: 'details-scan-info')
|
98
|
+
scan_info_table_rows = scan_info_table.find_elements(tag_name: 'tr')
|
99
|
+
progress.increment
|
100
|
+
check_table_body = driver.find_element(tag_name: 'tbody')
|
101
|
+
check_table_rows = check_table_body.find_elements(tag_name: 'tr')
|
102
|
+
progress.increment
|
103
|
+
scan_info_table_rows.each do |row|
|
104
|
+
key = row.find_element(tag_name: 'h5').text
|
105
|
+
value = row.find_element(tag_name: 'strong').text
|
106
|
+
report[key.downcase.gsub(/:/, '').gsub(/ /, '_')] = value
|
107
|
+
progress.increment
|
108
|
+
end
|
109
|
+
check_table_rows.each do |row|
|
110
|
+
chk_objs = row.find_elements(tag_name: 'td')
|
111
|
+
chk_objs.map!(&:text)
|
112
|
+
if status.nil? || status.include?(chk_objs[1].downcase)
|
113
|
+
report['scan_results'][chk_objs[0][/^[0-9.]+/, 0]] = {
|
114
|
+
'name' => chk_objs[0].gsub(/\n/, ' '),
|
115
|
+
'status' => chk_objs[1]
|
116
|
+
}
|
117
|
+
end
|
118
|
+
progress.increment
|
119
|
+
end
|
120
|
+
all_checks[node_name] = report
|
121
|
+
driver.close
|
122
|
+
AbideDevUtils::Output.simple "Created report for #{node_name}"
|
123
|
+
ensure
|
124
|
+
driver.switch_to.window original_window
|
125
|
+
end
|
126
|
+
end
|
127
|
+
all_checks
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -7,18 +7,41 @@ module AbideDevUtils
|
|
7
7
|
DEFAULT_PATH = "#{File.expand_path('~')}/.abide_dev.yaml"
|
8
8
|
|
9
9
|
def self.to_h(path = DEFAULT_PATH)
|
10
|
+
return {} unless File.file?(path)
|
11
|
+
|
12
|
+
h = YAML.safe_load(File.open(path), [Symbol])
|
13
|
+
h.transform_keys(&:to_sym)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_h(path = DEFAULT_PATH)
|
17
|
+
return {} unless File.file?(path)
|
18
|
+
|
10
19
|
h = YAML.safe_load(File.open(path), [Symbol])
|
11
20
|
h.transform_keys(&:to_sym)
|
12
21
|
end
|
13
22
|
|
14
23
|
def self.config_section(section, path = DEFAULT_PATH)
|
15
24
|
h = to_h(path)
|
16
|
-
s = h
|
25
|
+
s = h.fetch(section.to_sym, nil)
|
26
|
+
return {} if s.nil?
|
27
|
+
|
28
|
+
s.transform_keys(&:to_sym)
|
29
|
+
end
|
30
|
+
|
31
|
+
def config_section(section, path = DEFAULT_PATH)
|
32
|
+
h = to_h(path)
|
33
|
+
s = h.fetch(section.to_sym, nil)
|
34
|
+
return {} if s.nil?
|
35
|
+
|
17
36
|
s.transform_keys(&:to_sym)
|
18
37
|
end
|
19
38
|
|
20
39
|
def self.fetch(key, default = nil, path = DEFAULT_PATH)
|
21
40
|
to_h(path).fetch(key, default)
|
22
41
|
end
|
42
|
+
|
43
|
+
def fetch(key, default = nil, path = DEFAULT_PATH)
|
44
|
+
to_h(path).fetch(key, default)
|
45
|
+
end
|
23
46
|
end
|
24
47
|
end
|
@@ -8,5 +8,9 @@ module AbideDevUtils
|
|
8
8
|
class XPathSearchError < GenericError
|
9
9
|
@default = 'XPath seach failed to find anything at:'
|
10
10
|
end
|
11
|
+
|
12
|
+
class StrategyInvalidError < GenericError
|
13
|
+
@default = 'Invalid strategy selected. Should be either \'name\' or \'num\''
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
data/lib/abide_dev_utils/jira.rb
CHANGED
@@ -86,6 +86,8 @@ module AbideDevUtils
|
|
86
86
|
|
87
87
|
def self.client(options: {})
|
88
88
|
opts = merge_options(options)
|
89
|
+
return client_from_prompts if opts.empty?
|
90
|
+
|
89
91
|
opts[:username] = AbideDevUtils::Prompt.username if opts[:username].nil?
|
90
92
|
opts[:password] = AbideDevUtils::Prompt.password if opts[:password].nil?
|
91
93
|
opts[:site] = AbideDevUtils::Prompt.single_line('Jira URL') if opts[:site].nil?
|
@@ -133,6 +135,16 @@ module AbideDevUtils
|
|
133
135
|
end
|
134
136
|
end
|
135
137
|
|
138
|
+
# def self.new_issues_from_comply_report(client, project, report, dry_run: false)
|
139
|
+
# dr_prefix = dry_run ? 'DRY RUN: ' : ''
|
140
|
+
# i_attrs = all_project_issues_attrs(project)
|
141
|
+
# rep_sums = summaries_from_coverage_report(report)
|
142
|
+
# rep_sums.each do |k, v|
|
143
|
+
# next if summary_exist?(k, i_attrs)
|
144
|
+
|
145
|
+
# progress = AbideDevUtils::Output.progress(title: "#{dr_prefix}Creating Tasks", total: nil)
|
146
|
+
# v.each do |s|
|
147
|
+
|
136
148
|
def self.merge_options(options)
|
137
149
|
config.merge(options)
|
138
150
|
end
|
@@ -165,6 +177,11 @@ module AbideDevUtils
|
|
165
177
|
summaries.transform_keys { |k| "#{COV_PARENT_SUMMARY_PREFIX}#{benchmark}-#{k}"}
|
166
178
|
end
|
167
179
|
|
180
|
+
# def self.summaries_from_comply_report(report)
|
181
|
+
# summaries = {}
|
182
|
+
# report.each do |_, v|
|
183
|
+
# end
|
184
|
+
|
168
185
|
class Dummy
|
169
186
|
def attrs
|
170
187
|
{ 'fields' => {
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'erb'
|
4
4
|
require 'pathname'
|
5
|
+
require 'abide_dev_utils/output'
|
5
6
|
require 'abide_dev_utils/prompt'
|
6
7
|
require 'abide_dev_utils/errors/ppt'
|
7
8
|
|
@@ -9,6 +10,10 @@ module AbideDevUtils
|
|
9
10
|
module Ppt
|
10
11
|
class NewObjectBuilder
|
11
12
|
DEFAULT_EXT = '.pp'
|
13
|
+
VALID_EXT = /(\.pp|\.rb)\.erb$/.freeze
|
14
|
+
TMPL_PATTERN = /^[a-zA-Z][^\s]*\.erb$/.freeze
|
15
|
+
OBJ_PREFIX = /^(c-|d-)/.freeze
|
16
|
+
PREFIX_TEST_PATH = { 'c-' => 'classes', 'd-' => 'defines' }.freeze
|
12
17
|
|
13
18
|
def initialize(obj_type, obj_name, opts: {}, vars: {})
|
14
19
|
@obj_type = obj_type
|
@@ -17,25 +22,17 @@ module AbideDevUtils
|
|
17
22
|
@vars = vars
|
18
23
|
class_vars
|
19
24
|
validate_class_vars
|
25
|
+
@tmpl_data = template_data(@opts.fetch(:tmpl_name, @obj_type))
|
20
26
|
end
|
21
27
|
|
22
|
-
attr_reader :obj_type, :obj_name, :
|
23
|
-
|
24
|
-
def render
|
25
|
-
ERB.new(File.read(@tmpl_path.to_s), 0, '<>-').result(binding)
|
26
|
-
end
|
28
|
+
attr_reader :obj_type, :obj_name, :root_dir, :tmpl_dir, :obj_path, :vars, :tmpl_data
|
27
29
|
|
28
30
|
def build
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
content = render
|
35
|
-
File.open(obj_path, 'w') { |f| f.write(render) } unless content.empty?
|
36
|
-
raise AbideDevUtils::Errors::Ppt::FailedToCreateFileError, obj_path unless File.file?(obj_path)
|
37
|
-
|
38
|
-
"Created file #{obj_path}"
|
31
|
+
force = @opts.fetch(:force, false)
|
32
|
+
obj_cont = force ? true : continue?(obj_path)
|
33
|
+
spec_cont = force ? true : continue?(@tmpl_data[:spec_path])
|
34
|
+
write_file(obj_path, @tmpl_data[:path]) if obj_cont
|
35
|
+
write_file(@tmpl_data[:spec_path], @spec_tmpl) if spec_cont
|
39
36
|
end
|
40
37
|
|
41
38
|
# If a method gets called on the Hiera object which is not defined,
|
@@ -59,42 +56,98 @@ module AbideDevUtils
|
|
59
56
|
|
60
57
|
private
|
61
58
|
|
59
|
+
def continue?(path)
|
60
|
+
continue = if File.exist?(path)
|
61
|
+
AbideDevUtils::Prompt.yes_no('File exists, would you like to overwrite?')
|
62
|
+
else
|
63
|
+
true
|
64
|
+
end
|
65
|
+
AbideDevUtils::Output.simple("Not overwriting file #{path}") unless continue
|
66
|
+
|
67
|
+
continue
|
68
|
+
end
|
69
|
+
|
70
|
+
def write_file(path, tmpl_path)
|
71
|
+
dir, = Pathname.new(path).split
|
72
|
+
Pathname.new(dir).mkpath unless Dir.exist?(dir)
|
73
|
+
content = render(tmpl_path)
|
74
|
+
File.open(path, 'w') { |f| f.write(content) } unless content.empty?
|
75
|
+
raise AbideDevUtils::Errors::Ppt::FailedToCreateFileError, path unless File.file?(path)
|
76
|
+
|
77
|
+
AbideDevUtils::Output.simple("Created file #{path}")
|
78
|
+
end
|
79
|
+
|
80
|
+
def build_obj; end
|
81
|
+
|
62
82
|
def class_vars
|
63
|
-
@tmpl_name = @opts.fetch(:tmpl_name, "#{@obj_type}.erb")
|
64
83
|
@root_dir = Pathname.new(@opts.fetch(:root_dir, Dir.pwd))
|
65
84
|
@tmpl_dir = if @opts.fetch(:absolute_template_dir, false)
|
66
85
|
@opts.fetch(:tmpl_dir)
|
67
86
|
else
|
68
|
-
"#{@
|
87
|
+
"#{@root_dir}/#{@opts.fetch(:tmpl_dir, 'object_templates')}"
|
69
88
|
end
|
70
|
-
@tmpl_path = Pathname.new("#{@tmpl_dir}/#{@opts.fetch(:tmpl_name, "#{@obj_type}.erb")}")
|
71
|
-
@type_path_map = @opts.fetch(:type_path_map, {})
|
72
89
|
@obj_path = new_obj_path
|
90
|
+
@spec_tmpl = @opts.fetch(:spec_template, File.expand_path(File.join(__dir__, '../resources/generic_spec.erb')))
|
73
91
|
end
|
74
92
|
|
75
93
|
def validate_class_vars
|
76
94
|
raise AbideDevUtils::Errors::PathNotDirectoryError, @root_dir unless Dir.exist? @root_dir
|
77
95
|
raise AbideDevUtils::Errors::PathNotDirectoryError, @tmpl_dir unless Dir.exist? @tmpl_dir
|
78
|
-
raise AbideDevUtils::Errors::Ppt::TemplateNotFoundError, @tmpl_path.to_s unless @tmpl_path.file?
|
79
96
|
end
|
80
97
|
|
81
98
|
def basename(obj_name)
|
82
99
|
obj_name.split('::')[-1]
|
83
100
|
end
|
84
101
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
102
|
+
def prefix
|
103
|
+
pfx = basename.match(OBJ_PREFIX)
|
104
|
+
return pfx[1] unless pfx.empty?
|
105
|
+
end
|
106
|
+
|
107
|
+
def templates
|
108
|
+
return [] if Dir.entries(tmpl_dir).empty?
|
109
|
+
|
110
|
+
file_names = Dir.entries(tmpl_dir).select { |f| f.match?(TMPL_PATTERN) }
|
111
|
+
file_names.map { |i| File.join(tmpl_dir, i) }
|
112
|
+
end
|
113
|
+
|
114
|
+
def template_data(query)
|
115
|
+
raise AbideDevUtils::Errors::Ppt::TemplateNotFoundError, @tmpl_dir if Dir.entries(@tmpl_dir).empty?
|
116
|
+
|
117
|
+
data = {}
|
118
|
+
pattern = /#{Regexp.quote(query)}/
|
119
|
+
templates.each do |i|
|
120
|
+
pn = Pathname.new(i)
|
121
|
+
next unless pn.basename.to_s.match?(pattern)
|
122
|
+
|
123
|
+
data[:path] = pn.to_s
|
124
|
+
data[:fname] = pn.basename.to_s
|
90
125
|
end
|
126
|
+
raise AbideDevUtils::Errors::Ppt::TemplateNotFoundError, @tmpl_dir unless data.key?(:fname)
|
127
|
+
|
128
|
+
data[:ext] = data[:fname].match?(VALID_EXT) ? data[:fname].match(VALID_EXT)[1] : '.pp'
|
129
|
+
data[:pfx] = data[:fname].match?(OBJ_PREFIX) ? data[:fname].match(OBJ_PREFIX)[1] : 'c-'
|
130
|
+
data[:spec_base] = PREFIX_TEST_PATH[data[:pfx]]
|
131
|
+
data[:obj_name] = normalize_obj_name(data.dup)
|
132
|
+
data[:spec_name] = "#{@obj_name.split('::')[-1]}_spec.rb"
|
133
|
+
data[:spec_path] = spec_path(data[:spec_base], data[:spec_name])
|
134
|
+
data
|
135
|
+
end
|
136
|
+
|
137
|
+
def normalize_obj_name(data)
|
138
|
+
new_name = data[:fname].slice(/^(?:#{Regexp.quote(data[:pfx])})?(?<name>[^\s.]+)(?:#{Regexp.quote(data[:ext])})?\.erb$/, 'name')
|
139
|
+
"#{new_name}#{data[:ext]}"
|
140
|
+
end
|
141
|
+
|
142
|
+
def render(path)
|
143
|
+
ERB.new(File.read(path), 0, '<>-').result(binding)
|
91
144
|
end
|
92
145
|
|
93
146
|
def namespace_format(name)
|
94
147
|
name.split(':').reject(&:empty?).join('::')
|
95
148
|
end
|
96
149
|
|
97
|
-
def
|
150
|
+
def new_obj_path
|
98
151
|
parts = @obj_name.split('::')[1..-2]
|
99
152
|
parts.insert(0, 'manifests')
|
100
153
|
parts.insert(-1, "#{basename(@obj_name)}#{DEFAULT_EXT}")
|
@@ -102,27 +155,13 @@ module AbideDevUtils
|
|
102
155
|
path.to_s
|
103
156
|
end
|
104
157
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
abs_path = Pathname.new(map_val).absolute? ? map_val : "#{Dir.pwd}/#{map_val}"
|
113
|
-
"#{abs_path}/#{basename(@obj_name)}#{DEFAULT_EXT}"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def custom_obj_path_from_hash(map_val, obj_name)
|
118
|
-
raise AbideDevUtils::Errors::Ppt::CustomObjPathKeyError, map_val unless map_val.key?(:path)
|
119
|
-
|
120
|
-
abs_path = Pathname.new(map_val[:path]).absolute? ? map_val[:path] : "#{Dir.pwd}/#{map_val[:path]}"
|
121
|
-
if map_val.key?(:extension)
|
122
|
-
"#{abs_path}/#{basename(obj_name)}#{map_val[:extension]}"
|
123
|
-
else
|
124
|
-
"#{abs_path}/#{basename(obj_name)}#{DEFAULT_EXT}"
|
125
|
-
end
|
158
|
+
def spec_path(base_dir, spec_name)
|
159
|
+
parts = @obj_name.split('::')[1..-2]
|
160
|
+
parts.insert(0, 'spec')
|
161
|
+
parts.insert(1, base_dir)
|
162
|
+
parts.insert(-1, spec_name)
|
163
|
+
path = @root_dir + Pathname.new(parts.join('/'))
|
164
|
+
path.to_s
|
126
165
|
end
|
127
166
|
end
|
128
167
|
end
|
@@ -15,7 +15,7 @@ module AbideDevUtils
|
|
15
15
|
type = opts.fetch(:type, 'cis')
|
16
16
|
case type.downcase
|
17
17
|
when 'cis'
|
18
|
-
AbideDevUtils::XCCDF::CIS::Hiera.new(xccdf_file, parent_key_prefix: opts[:parent_key_prefix])
|
18
|
+
AbideDevUtils::XCCDF::CIS::Hiera.new(xccdf_file, parent_key_prefix: opts[:parent_key_prefix], num: opts[:num])
|
19
19
|
else
|
20
20
|
AbideDevUtils::Output.simple("XCCDF type #{type} is unsupported!")
|
21
21
|
end
|
@@ -35,13 +35,13 @@ module AbideDevUtils
|
|
35
35
|
# @param parent_key_prefix [String] a string to be prepended to the
|
36
36
|
# top-level key in the Hiera structure. Useful for namespacing
|
37
37
|
# the top-level key.
|
38
|
-
def initialize(xccdf_file, parent_key_prefix: nil)
|
38
|
+
def initialize(xccdf_file, parent_key_prefix: nil, num: false)
|
39
39
|
@doc = parse(xccdf_file)
|
40
40
|
@title = xpath(XPATHS[:benchmark][:title]).children.to_s
|
41
41
|
@version = xpath(XPATHS[:benchmark][:version]).children.to_s
|
42
42
|
@profiles = xpath(XPATHS[:profiles][:all])
|
43
43
|
@parent_key = make_parent_key(@doc, parent_key_prefix)
|
44
|
-
@hash = make_hash(@doc, @parent_key)
|
44
|
+
@hash = make_hash(@doc, @parent_key, num)
|
45
45
|
end
|
46
46
|
|
47
47
|
def yaml_title
|
@@ -92,13 +92,16 @@ module AbideDevUtils
|
|
92
92
|
|
93
93
|
attr_accessor :doc, :hash, :parent_key, :profiles
|
94
94
|
|
95
|
+
# Accepts a path to an xccdf xml file and returns a parsed Nokogiri object of the file
|
96
|
+
# @param xccdf_file [String] path to an xccdf xml file
|
97
|
+
# @return [Nokogiri::Node] A Nokogiri node object of the XML document
|
95
98
|
def parse(xccdf_file)
|
96
99
|
raise AbideDevUtils::Errors::FileNotFoundError, xccdf_file unless File.file?(xccdf_file)
|
97
100
|
|
98
101
|
Nokogiri.XML(File.open(xccdf_file))
|
99
102
|
end
|
100
103
|
|
101
|
-
def make_hash(doc, parent_key)
|
104
|
+
def make_hash(doc, parent_key, num)
|
102
105
|
hash = { parent_key.to_sym => { title: @title, version: @version } }
|
103
106
|
profiles = doc.xpath('xccdf:Benchmark/xccdf:Profile')
|
104
107
|
profiles.each do |p|
|
@@ -106,7 +109,7 @@ module AbideDevUtils
|
|
106
109
|
hash[parent_key.to_sym][title.to_sym] = []
|
107
110
|
selects = p.xpath('./xccdf:select')
|
108
111
|
selects.each do |s|
|
109
|
-
hash[parent_key.to_sym][title.to_sym] << normalize_ctrl_name(s['idref'].to_s)
|
112
|
+
hash[parent_key.to_sym][title.to_sym] << normalize_ctrl_name(s['idref'].to_s, num)
|
110
113
|
end
|
111
114
|
end
|
112
115
|
hash
|
@@ -114,7 +117,7 @@ module AbideDevUtils
|
|
114
117
|
|
115
118
|
def normalize_str(str)
|
116
119
|
nstr = str.downcase
|
117
|
-
nstr.gsub!(/[^a-
|
120
|
+
nstr.gsub!(/[^a-z0-9]$/, '')
|
118
121
|
nstr.gsub!(/^[^a-z]/, '')
|
119
122
|
nstr.gsub!(/^(l1_|l2_|ng_)/, '')
|
120
123
|
nstr.delete!('(/|\\)')
|
@@ -128,11 +131,23 @@ module AbideDevUtils
|
|
128
131
|
prof_name
|
129
132
|
end
|
130
133
|
|
131
|
-
def normalize_ctrl_name(ctrl)
|
132
|
-
|
134
|
+
def normalize_ctrl_name(ctrl, num)
|
135
|
+
return num_normalize_ctrl(ctrl) if num
|
136
|
+
|
137
|
+
name_normalize_ctrl(ctrl)
|
138
|
+
end
|
139
|
+
|
140
|
+
def name_normalize_ctrl(ctrl)
|
141
|
+
new_ctrl = ctrl.split('benchmarks_rule_')[-1].gsub(CONTROL_PREFIX, '')
|
133
142
|
normalize_str(new_ctrl)
|
134
143
|
end
|
135
144
|
|
145
|
+
def num_normalize_ctrl(ctrl)
|
146
|
+
part = ctrl.split('benchmarks_rule_')[-1]
|
147
|
+
numpart = CONTROL_PREFIX.match(part).to_s.chop.gsub(UNDERSCORED, '_')
|
148
|
+
"c#{numpart}"
|
149
|
+
end
|
150
|
+
|
136
151
|
def make_parent_key(doc, prefix)
|
137
152
|
doc_title = normalize_str(doc.xpath(XPATHS[:benchmark][:title]).children.to_s)
|
138
153
|
return doc_title if prefix.nil?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abide_dev_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Heston Snodgrass
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.11'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: selenium-webdriver
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 4.0.0.beta4
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 4.0.0.beta4
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: bundler
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +122,20 @@ dependencies:
|
|
108
122
|
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: console
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
140
|
name: github_changelog_generator
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -242,11 +270,13 @@ executables:
|
|
242
270
|
extensions: []
|
243
271
|
extra_rdoc_files: []
|
244
272
|
files:
|
273
|
+
- ".dockerignore"
|
245
274
|
- ".gitignore"
|
246
275
|
- ".rspec"
|
247
276
|
- ".rubocop.yml"
|
248
277
|
- ".rubocop_todo.yml"
|
249
278
|
- CHANGELOG.md
|
279
|
+
- Dockerfile
|
250
280
|
- Gemfile
|
251
281
|
- LICENSE.txt
|
252
282
|
- README.md
|
@@ -259,10 +289,12 @@ files:
|
|
259
289
|
- lib/abide_dev_utils.rb
|
260
290
|
- lib/abide_dev_utils/cli.rb
|
261
291
|
- lib/abide_dev_utils/cli/abstract.rb
|
292
|
+
- lib/abide_dev_utils/cli/comply.rb
|
262
293
|
- lib/abide_dev_utils/cli/jira.rb
|
263
294
|
- lib/abide_dev_utils/cli/puppet.rb
|
264
295
|
- lib/abide_dev_utils/cli/test.rb
|
265
296
|
- lib/abide_dev_utils/cli/xccdf.rb
|
297
|
+
- lib/abide_dev_utils/comply.rb
|
266
298
|
- lib/abide_dev_utils/config.rb
|
267
299
|
- lib/abide_dev_utils/constants.rb
|
268
300
|
- lib/abide_dev_utils/errors.rb
|
@@ -278,6 +310,7 @@ files:
|
|
278
310
|
- lib/abide_dev_utils/ppt/coverage.rb
|
279
311
|
- lib/abide_dev_utils/ppt/new_obj.rb
|
280
312
|
- lib/abide_dev_utils/prompt.rb
|
313
|
+
- lib/abide_dev_utils/resources/generic_spec.erb
|
281
314
|
- lib/abide_dev_utils/utils/general.rb
|
282
315
|
- lib/abide_dev_utils/validate.rb
|
283
316
|
- lib/abide_dev_utils/version.rb
|