pipedawg 0.5.0 → 0.6.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: 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