pipedawg 0.4.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 064c29963799087a56d2cde36f785bc9762cd50870dc9eeede4f9efbfc577f0f
4
- data.tar.gz: fd51dfa82c3d16c215f284dfd7c84c5600906738fef8d6f6b0d69b22e967af33
3
+ metadata.gz: 53733705295ce1c9b2ae80fc1c8368e7e08e7d7a0e1fcf3727fe972dd5714fb1
4
+ data.tar.gz: 10e86751592488fbb9972605892d79af662e60e3a3da070292cf4933f31b7981
5
5
  SHA512:
6
- metadata.gz: c7241f30f45d72d1d43e03ef7b007c24756b1a16c483f605c179a02eb02c89b900926fd20c93502fbc94585cc9f1fa94ba41fefa27cabf497568b05ff252a75e
7
- data.tar.gz: 7c72d19557c1f449dd56315465d1f22d66277005dfb39c59a67d83ef5389800511fcbbfc7fae3409f235d66834256d5f9566d63d8610f37b1a718c0d4f99285a
6
+ metadata.gz: 11584d541a5d63f54761dee9ca878e3c79ba168ee1e5e93ec9ddccd559d869672a900a6aa25d966df4ef807a56ac0c75385644baf3bce5498ac7a68a29fd8a9a
7
+ data.tar.gz: 97f20d550f1cbe4bf298a2f6884f02754cd385e317d777887d11a8748d7436d8bb6db035944c6f59d2593b4e3a615db76f28c678bb392cf16ef3e6c6f92770a9
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pipedawg
4
+ # qualys_scan_job class
5
+ class QualysScanJob < Job
6
+ attr_accessor :qualys_opts
7
+
8
+ def initialize(name = 'build', opts = {}, qualys_opts = {})
9
+ @qualys_opts = {
10
+ acceptable_risk: '${QUALYS_ACCEPTABLE_IMAGE_RISK}',
11
+ artifacts: {
12
+ expire_in: '1 month', paths: ['software.json', 'vulnerabilities.json'], when: 'always'
13
+ }, debug: true, gateway: '${QUALYS_GATEWAY}', image: nil, password: '${QUALYS_PASSWORD}', rules: nil,
14
+ scan_image: '${QUALYS_IMAGE}', scan_target_prefix: 'qualys_scan_target', tags: nil, user: '${QUALYS_USERNAME}',
15
+ variables: { GIT_STRATEGY: 'clone' }
16
+ }.merge(qualys_opts)
17
+ super name, opts
18
+ update
19
+ end
20
+
21
+ def update # rubocop:disable Metrics/AbcSize
22
+ require 'json'
23
+ opts[:artifacts] = qualys_opts[:artifacts] if qualys_opts[:artifacts]
24
+ opts[:image] = qualys_opts[:image]
25
+ opts[:rules] = qualys_opts[:rules] if qualys_opts[:rules]
26
+ opts[:tags] = qualys_opts[:tags] if qualys_opts[:tags]
27
+ opts[:variables] = qualys_opts[:variables] if qualys_opts[:variables]
28
+ opts[:script] = debug + image + token + scan_start + scan_complete + artifacts + severities + outputs
29
+ end
30
+
31
+ private
32
+
33
+ def debug # rubocop:disable Metrics/MethodLength
34
+ if qualys_opts[:debug]
35
+ Pipedawg::Util.echo_proxy_vars + [
36
+ 'echo Qualys settings:',
37
+ "echo Qualys gateway: \"#{qualys_opts[:gateway]}\"",
38
+ "echo Qualys username: \"#{qualys_opts[:user]}\"",
39
+ "if [ \"#{qualys_opts[:password]}\" != '' ]; then " \
40
+ 'echo Qualys password is not empty; else ' \
41
+ 'echo Qualys password is not set; exit 1; fi'
42
+ ]
43
+ else
44
+ []
45
+ end
46
+ end
47
+
48
+ def image
49
+ [
50
+ "image_target=\"#{qualys_opts[:scan_target_prefix]}:$(echo #{qualys_opts[:scan_image]} | sed 's/^[^/]*\\///'| sed 's/[:/]/-/g')\"", # rubocop:disable Layout/LineLength
51
+ "docker pull \"#{qualys_opts[:scan_image]}\"",
52
+ "docker image tag \"#{qualys_opts[:scan_image]}\" \"${image_target}\"",
53
+ "image_id=$(docker inspect --format=\"{{index .Id}}\" \"#{qualys_opts[:scan_image]}\" | cut -c8-19)",
54
+ 'echo "Image ID: ${image_id}"'
55
+ ]
56
+ end
57
+
58
+ def token
59
+ ["token=$(curl -s --location --request POST \"https://#{qualys_opts[:gateway]}/auth\" --header \"Content-Type: application/x-www-form-urlencoded\" --data-urlencode \"username=#{qualys_opts[:user]}\" --data-urlencode \"password=#{qualys_opts[:password]}\" --data-urlencode \"token=true\")"] # rubocop:disable Layout/LineLength
60
+ end
61
+
62
+ def scan_start
63
+ [
64
+ 'while true; do ' \
65
+ "result=$(curl -s -o /dev/null -w ''%{http_code}'' --location --request GET \"https://#{qualys_opts[:gateway]}/csapi/v1.2/images/$image_id\" --header \"Authorization: Bearer $token\"); " + # rubocop:disable Layout/LineLength, Style/FormatStringToken
66
+ 'echo "Waiting for scan to start..."; ' \
67
+ 'echo " Result: ${result}"; ' \
68
+ 'if [ "${result}" = "200" ]; then break; fi; ' \
69
+ 'sleep 10; done'
70
+ ]
71
+ end
72
+
73
+ def scan_complete
74
+ [
75
+ 'while true; do ' \
76
+ "result=$(curl -s --location --request GET \"https://#{qualys_opts[:gateway]}/csapi/v1.2/images/$image_id\" --header \"Authorization: Bearer $token\" | jq -r '.scanStatus'); " + # rubocop:disable Layout/LineLength
77
+ 'echo "Waiting for scan to complete..."; ' \
78
+ 'echo " Result: ${result}"; ' \
79
+ 'if [ "${result}" = "SUCCESS" ]; then break; fi; ' \
80
+ 'sleep 10; done; sleep 30'
81
+ ]
82
+ end
83
+
84
+ def artifacts
85
+ [
86
+ "curl -s --location --request GET \"https://#{qualys_opts[:gateway]}/csapi/v1.2/images/$image_id/software\" --header \"Authorization: Bearer $token\" | jq . > software.json", # rubocop:disable Layout/LineLength
87
+ "curl -s --location --request GET \"https://#{qualys_opts[:gateway]}/csapi/v1.2/images/$image_id/vuln\" --header \"Authorization: Bearer $token\" | jq . > vulnerabilities.json" # rubocop:disable Layout/LineLength
88
+ ]
89
+ end
90
+
91
+ def severities
92
+ [
93
+ "response=$(curl -s --location --request GET \"https://#{qualys_opts[:gateway]}/csapi/v1.2/images/$image_id/vuln/count\" --header \"Authorization: Bearer $token\")", # rubocop:disable Layout/LineLength
94
+ 'severity5=$(jq -r ".severity5Count" <<< "${response}")',
95
+ 'severity4=$(jq -r ".severity4Count" <<< "${response}")'
96
+ ]
97
+ end
98
+
99
+ def outputs # rubocop:disable Metrics/MethodLength
100
+ [
101
+ 'if [ "$severity5" = "null" ]; then ' \
102
+ 'echo "ERROR: Wrong ImageID or problem during vulnerabilities count." >&2; ' \
103
+ 'exit 1; fi',
104
+ 'if [ "$severity4" = "null" ]; then ' \
105
+ 'echo "ERROR: Wrong ImageID or problem during vulnerabilities count." >&2; ' \
106
+ 'exit 1; fi',
107
+ 'echo "Severity5: $severity5, Severity4: $severity4"',
108
+ 'risk=$((($severity5*3)+($severity4)))',
109
+ 'echo "Risk: $risk"',
110
+ "if (($risk > \"#{qualys_opts[:acceptable_risk]}\")); then " \
111
+ 'echo "Too many vulnerabilities. Severity5: $severity5, Severity4: $severity4" >&2; ' \
112
+ 'exit 1; fi'
113
+ ]
114
+ end
115
+ end
116
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pipedawg
4
- VERSION = '0.4.0'
4
+ VERSION = '0.5.0'
5
5
  end
data/lib/pipedawg.rb CHANGED
@@ -4,6 +4,7 @@ require 'pipedawg/job'
4
4
  require 'pipedawg/helm_copy_job'
5
5
  require 'pipedawg/kaniko_job'
6
6
  require 'pipedawg/pipeline'
7
+ require 'pipedawg/qualys_scan_job'
7
8
  require 'pipedawg/util'
8
9
  require 'pipedawg/version'
9
10
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pipedawg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - harbottle
@@ -24,6 +24,7 @@ files:
24
24
  - lib/pipedawg/job.rb
25
25
  - lib/pipedawg/kaniko_job.rb
26
26
  - lib/pipedawg/pipeline.rb
27
+ - lib/pipedawg/qualys_scan_job.rb
27
28
  - lib/pipedawg/util.rb
28
29
  - lib/pipedawg/version.rb
29
30
  homepage: https://github.com/liger1978/pipedawg