pipedawg 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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