pipedawg 0.5.0 → 0.6.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: 53733705295ce1c9b2ae80fc1c8368e7e08e7d7a0e1fcf3727fe972dd5714fb1
4
- data.tar.gz: 10e86751592488fbb9972605892d79af662e60e3a3da070292cf4933f31b7981
3
+ metadata.gz: b2e0ba1c718b0efe498f222720490aeb2566a6f5c4e6fb1f0b56e5e9874669a5
4
+ data.tar.gz: 5545deb6f783e71bb5b35bb6633aed7939a9ac0e74aefb50200020976c1b6489
5
5
  SHA512:
6
- metadata.gz: 11584d541a5d63f54761dee9ca878e3c79ba168ee1e5e93ec9ddccd559d869672a900a6aa25d966df4ef807a56ac0c75385644baf3bce5498ac7a68a29fd8a9a
7
- data.tar.gz: 97f20d550f1cbe4bf298a2f6884f02754cd385e317d777887d11a8748d7436d8bb6db035944c6f59d2593b4e3a615db76f28c678bb392cf16ef3e6c6f92770a9
6
+ metadata.gz: 17fbfd9bb667f808c44e636d7133fa379d115b650102162d35b5e0fd7b6594466493663c7193ef8092d3e55c2480737bbf4e4bf5923260096ae7706200320d04
7
+ data.tar.gz: 338192888145922229beba1e38fa3794e2f1d7d4e197987de1b5ae7425df29f2239f47a011846b10df20723d43c93a26d26813755a33d2b193780b0812429f74
data/README.md CHANGED
@@ -42,13 +42,13 @@ gem_job = Pipedawg::Job.new(
42
42
  script: ['bundle install', 'gem build *.gemspec']
43
43
  )
44
44
 
45
- kaniko_job = Pipedawg::KanikoJob.new(
45
+ kaniko_build_job = Pipedawg::KanikoBuildJob.new(
46
46
  'build:kaniko',
47
47
  {needs: ['build:gem'], retry: 2},
48
48
  {context:'${CI_PROJECT_DIR}/docker',external_files: {'*.gem':'gems'}}
49
49
  )
50
50
 
51
- pipeline = Pipedawg::Pipeline.new 'build:image', jobs: [gem_job, kaniko_job]
51
+ pipeline = Pipedawg::Pipeline.new 'build:image', jobs: [gem_job, kaniko_build_job]
52
52
  puts pipeline.to_yaml
53
53
  ```
54
54
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pipedawg
4
- # kaniko_job class
5
- class KanikoJob < Job
4
+ # kaniko_build_job class
5
+ class KanikoBuildJob < Job
6
6
  attr_accessor :kaniko_opts
7
7
 
8
8
  def initialize(name = 'build', opts = {}, kaniko_opts = {}) # rubocop:disable Metrics/MethodLength
@@ -2,15 +2,15 @@
2
2
 
3
3
  module Pipedawg
4
4
  # qualys_scan_job class
5
- class QualysScanJob < Job
5
+ class QualysScanJob < Job # rubocop:disable Metrics/ClassLength
6
6
  attr_accessor :qualys_opts
7
7
 
8
8
  def initialize(name = 'build', opts = {}, qualys_opts = {})
9
9
  @qualys_opts = {
10
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,
11
+ artifacts: { expire_in: '1 month', paths: ['software.json', 'vulnerabilities.json'], when: 'always' },
12
+ config: { '$CI_REGISTRY': { username: '$CI_REGISTRY_USER', password: '$CI_REGISTRY_PASSWORD' } },
13
+ debug: true, gateway: '${QUALYS_GATEWAY}', image: nil, password: '${QUALYS_PASSWORD}', rules: nil,
14
14
  scan_image: '${QUALYS_IMAGE}', scan_target_prefix: 'qualys_scan_target', tags: nil, user: '${QUALYS_USERNAME}',
15
15
  variables: { GIT_STRATEGY: 'clone' }
16
16
  }.merge(qualys_opts)
@@ -25,7 +25,8 @@ module Pipedawg
25
25
  opts[:rules] = qualys_opts[:rules] if qualys_opts[:rules]
26
26
  opts[:tags] = qualys_opts[:tags] if qualys_opts[:tags]
27
27
  opts[:variables] = qualys_opts[:variables] if qualys_opts[:variables]
28
- opts[:script] = debug + image + token + scan_start + scan_complete + artifacts + severities + outputs
28
+ opts[:script] =
29
+ debug + config + image + clean_config + token + scan_start + scan_complete + artifacts + severities + outputs
29
30
  end
30
31
 
31
32
  private
@@ -33,8 +34,7 @@ module Pipedawg
33
34
  def debug # rubocop:disable Metrics/MethodLength
34
35
  if qualys_opts[:debug]
35
36
  Pipedawg::Util.echo_proxy_vars + [
36
- 'echo Qualys settings:',
37
- "echo Qualys gateway: \"#{qualys_opts[:gateway]}\"",
37
+ 'echo Qualys settings:', "echo Qualys gateway: \"#{qualys_opts[:gateway]}\"",
38
38
  "echo Qualys username: \"#{qualys_opts[:user]}\"",
39
39
  "if [ \"#{qualys_opts[:password]}\" != '' ]; then " \
40
40
  'echo Qualys password is not empty; else ' \
@@ -45,16 +45,27 @@ module Pipedawg
45
45
  end
46
46
  end
47
47
 
48
+ def config
49
+ ['export CONFIG=$(mktemp -d)', "echo #{qualys_opts[:config].to_json.inspect} > \"${CONFIG}/config.json\""]
50
+ end
51
+
48
52
  def image
49
53
  [
50
54
  "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]}\"",
55
+ "docker --config=\"${CONFIG}\" pull \"#{qualys_opts[:scan_image]}\"",
52
56
  "docker image tag \"#{qualys_opts[:scan_image]}\" \"${image_target}\"",
53
57
  "image_id=$(docker inspect --format=\"{{index .Id}}\" \"#{qualys_opts[:scan_image]}\" | cut -c8-19)",
54
58
  'echo "Image ID: ${image_id}"'
55
59
  ]
56
60
  end
57
61
 
62
+ def clean_config
63
+ [
64
+ 'rm -f "${CONFIG}/config.json"',
65
+ 'rmdir "${CONFIG}"'
66
+ ]
67
+ end
68
+
58
69
  def token
59
70
  ["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
71
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pipedawg
4
+ # skopeo_copy_job class
5
+ class SkopeoCopyJob < Job
6
+ attr_accessor :skopeo_opts
7
+
8
+ def initialize(name = 'build', opts = {}, skopeo_opts = {})
9
+ @skopeo_opts = {
10
+ config: { '$CI_REGISTRY': { username: '$CI_REGISTRY_USER', password: '$CI_REGISTRY_PASSWORD' } },
11
+ copy_image: nil, debug: true, destinations: [{ copy_image: nil, flags: [], options: {} }],
12
+ flags: [], logins: {}, options: {}, skopeo: 'skopeo', stage: '${CI_PROJECT_DIR}/stage',
13
+ image: { entrypoint: [''], name: 'quay.io/skopeo/stable:latest' },
14
+ trusted_ca_cert_source_files: [], trusted_ca_cert_target_file: '/etc/docker/certs.d/ca.crt'
15
+ }.merge(skopeo_opts)
16
+ super name, opts
17
+ update
18
+ end
19
+
20
+ def update # rubocop:disable Metrics/AbcSize
21
+ require 'json'
22
+ opts[:image] = skopeo_opts[:image] if skopeo_opts[:image]
23
+ opts[:rules] = skopeo_opts[:rules] if skopeo_opts[:rules]
24
+ opts[:script] = debug + config + cert_copies + login + mkstage + pull + (
25
+ skopeo_opts[:destinations].map { |d| push(d) }
26
+ ).flatten(1)
27
+ end
28
+
29
+ private
30
+
31
+ def debug
32
+ if skopeo_opts[:debug]
33
+ Pipedawg::Util.echo_proxy_vars
34
+ else
35
+ []
36
+ end
37
+ end
38
+
39
+ def config
40
+ ['export CONFIG=$(mktemp -d)', "echo #{skopeo_opts[:config].to_json.inspect} > \"${CONFIG}/config.json\""]
41
+ end
42
+
43
+ def cert_copies
44
+ ["mkdir -p $(dirname \"#{skopeo_opts[:trusted_ca_cert_target_file]}\")"] +
45
+ Array(skopeo_opts[:trusted_ca_cert_source_files]).map do |cert|
46
+ "cat \"#{cert}\" >> \"#{skopeo_opts[:trusted_ca_cert_target_file]}\""
47
+ end
48
+ end
49
+
50
+ def login
51
+ skopeo_opts.fetch(:logins, {}).map do |k, v|
52
+ "echo \"#{v['password']}\" | #{skopeo_opts[:skopeo]} login --authfile \"${CONFIG}/config.json\" --username \"#{v['username']}\" --password-stdin \"#{k}\"" # rubocop:disable Layout/LineLength
53
+ end
54
+ end
55
+
56
+ def mkstage
57
+ ["mkdir -p \"#{skopeo_opts[:stage]}\""]
58
+ end
59
+
60
+ def pull
61
+ copy(skopeo_opts, "docker://#{skopeo_opts[:copy_image]}", "\"dir://#{skopeo_opts[:stage]}\"")
62
+ end
63
+
64
+ def push(destination_opts)
65
+ copy(destination_opts, "\"dir://#{skopeo_opts[:stage]}\"", "docker://#{destination_opts[:copy_image]}")
66
+ end
67
+
68
+ def copy(opts, source, destination)
69
+ Array(["#{skopeo_opts[:skopeo]} copy --authfile \"${CONFIG}/config.json\"", flags(opts), options(opts), source,
70
+ destination].reject(&:empty?).join(' '))
71
+ end
72
+
73
+ def flags(opts)
74
+ opts.fetch(:flags, []).uniq.map { |f| "--#{f}" }.join(' ')
75
+ end
76
+
77
+ def options(opts)
78
+ opts.fetch(:options, {}).map { |k, v| "--#{k} \"#{v}\"" }.join(' ')
79
+ end
80
+ end
81
+ end
data/lib/pipedawg/util.rb CHANGED
@@ -9,6 +9,7 @@ module Pipedawg
9
9
  item.map { |i| expand_env_vars(i) }
10
10
  when Hash
11
11
  item.each { |k, v| item[k] = expand_env_vars(v) }
12
+ item.transform_keys! { |k| expand_env_vars(k) }
12
13
  item
13
14
  when String
14
15
  item.gsub(/\${([^} ]+)}/) do |e|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pipedawg
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/pipedawg.rb CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  require 'pipedawg/job'
4
4
  require 'pipedawg/helm_copy_job'
5
- require 'pipedawg/kaniko_job'
5
+ require 'pipedawg/kaniko_build_job'
6
6
  require 'pipedawg/pipeline'
7
7
  require 'pipedawg/qualys_scan_job'
8
+ require 'pipedawg/skopeo_copy_job'
8
9
  require 'pipedawg/util'
9
10
  require 'pipedawg/version'
10
11
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pipedawg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - harbottle
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-08 00:00:00.000000000 Z
11
+ date: 2022-02-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Generate GitLab CI pipelines.
14
14
  email:
@@ -22,9 +22,10 @@ files:
22
22
  - lib/pipedawg.rb
23
23
  - lib/pipedawg/helm_copy_job.rb
24
24
  - lib/pipedawg/job.rb
25
- - lib/pipedawg/kaniko_job.rb
25
+ - lib/pipedawg/kaniko_build_job.rb
26
26
  - lib/pipedawg/pipeline.rb
27
27
  - lib/pipedawg/qualys_scan_job.rb
28
+ - lib/pipedawg/skopeo_copy_job.rb
28
29
  - lib/pipedawg/util.rb
29
30
  - lib/pipedawg/version.rb
30
31
  homepage: https://github.com/liger1978/pipedawg