ndr_dev_support 6.1.6 → 6.1.7

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: 64a3efbb44c782bd62b06b12a1ccf5a8390173b7cff796141f044df5c79bf6a6
4
- data.tar.gz: 7ebfe41c07779cb4a90ad956359827f277bae624a254204b3460a99fa361b37f
3
+ metadata.gz: 5fe8e3400612fc7c12992a9ed37a1896cc2345ef9d060638776ad5f3f5f2c2e1
4
+ data.tar.gz: 229b4288c7f789407821bea03feaf6bf0512b5628d51d1a69fd8f8febdcacb6d
5
5
  SHA512:
6
- metadata.gz: 2ecc17440ed412719ea08f742c3c853401ebf06ba8ab1ec82eb143395f81ed0206ad857e300fbbb284441c248349364db12110a22511401887c007a15491800d
7
- data.tar.gz: 2e4c6023991fe8a7bdb685fce3d21eef9aa9baf89b2c491a51a5fbe65d586bf1471103ff0d57212b4fc9f8a51809138f17a482aca3f15c961aa8dd227b215838
6
+ metadata.gz: 1edfdb2328f91d2fb3707b1f6e1b8b70f48cf4bae5037a1bea01398192a079912d063842bd45a88b748fb6522e6c6b5593336584e7bad3a0e2c91e0ff539fcb5
7
+ data.tar.gz: 687c9637cc0c9d1dae203b242393f91c44fc7817719fb9e0fbe43bb8ea9b545918ee45850f0f2f2d8186858a72ef807416ef2006fd8cf7f8b2533b5987596c74
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  ## [Unreleased]
2
2
  * No unreleased changes
3
3
 
4
+ ## 6.1.7 / 2022-07-15
5
+ ### Added
6
+ * Add `cd:credentials` rake task for continuous deployment of credentials
7
+
4
8
  ## 6.1.6 / 2022-07-01
5
9
  ### Added
6
10
  * capistrano: use DEPLOYER environment variable for non-interactive deployments
@@ -0,0 +1,157 @@
1
+ require 'English'
2
+ require_relative 'stoppable'
3
+ require 'ndr_dev_support/slack_message_publisher'
4
+ require 'shellwords'
5
+ require 'with_clean_rbenv'
6
+
7
+ module NdrDevSupport
8
+ module Daemon
9
+ # Wrapper around Capistrano based Continuous Deployment of application credentials
10
+ #
11
+ # Assumes there is a capistrano task "app:update_secrets" which can be used together
12
+ # with a target name, e.g. cap target app:update_secrets
13
+ # to update a capistrano target with secrets / credentials from one or more repositories.
14
+ # To use this daemon, a number of environment variables need to be set
15
+ # including CD_TARGETS and CD_URLS.
16
+ class CDCredentials
17
+ include Stoppable
18
+
19
+ def self.from_args(env)
20
+ name = env['WORKER_NAME'].to_s
21
+ cd_targets = env['CD_TARGETS'].to_s.split
22
+ cd_urls = env['CD_URLS'].to_s.split
23
+
24
+ new(name: name, cd_targets: cd_targets, cd_urls: cd_urls)
25
+ end
26
+
27
+ def initialize(name:, cd_targets:, cd_urls:)
28
+ super
29
+
30
+ # Worker name can be used for clear logging:
31
+ @name = name
32
+ raise ArgumentError, 'No WORKER_NAME specified!' if name.blank?
33
+
34
+ # Capistrano targets to use for deployments
35
+ @cd_targets = cd_targets
36
+ raise ArgumentError, 'No CD_TARGETS specified!' unless cd_targets&.present?
37
+
38
+ # URLs to watch for continuous deployment
39
+ @cd_urls = cd_urls
40
+ raise ArgumentError, 'No CD_URLS specified!' unless cd_urls&.present?
41
+ end
42
+
43
+ private
44
+
45
+ def run_once
46
+ log('running once...')
47
+
48
+ # Keep state, watch repositories for changes, maybe save state to disk?
49
+ if (revisions = check_for_new_revisions)
50
+ log("deploying with revisions #{revisions}...")
51
+ deploy_credentials # should also notify slack if any changes deployed, but not
52
+ else
53
+ log('nothing new to deploy')
54
+ end
55
+ log('completed single run.')
56
+ rescue => e
57
+ log(<<~MSG)
58
+ Unhandled exception! #{e.class}: #{e.message}
59
+ #{(e.backtrace || []).join("\n")}
60
+ MSG
61
+
62
+ raise e
63
+ end
64
+
65
+ # Check for new revisions, and cache the latest one.
66
+ # If there are new revisions in the repositories available since the last check,
67
+ # return a hash of repo -> latest revision
68
+ # If no revisions have changed, returns nil
69
+ def check_for_new_revisions
70
+ # TODO: implement this, by checking for updates to @cd_urls
71
+ # Stub implementation, pretends things always changed
72
+ { 'dummy_repo' => '0' }
73
+ end
74
+
75
+ # Deploy credentials to all targets. Should also notify slack if any changes deployed
76
+ def deploy_credentials
77
+ log("Deploying to #{@cd_targets.join(', ')}...")
78
+ @changed_targets = []
79
+ @unchanged_targets = []
80
+ @failed_targets = []
81
+ @cd_targets.each do |target|
82
+ deploy_to_target(target)
83
+ end
84
+ publish_results
85
+ end
86
+
87
+ # Deploy credentials to a single target.
88
+ def deploy_to_target(target)
89
+ WithCleanRbenv.with_clean_rbenv do
90
+ results = `rbenv exec bundle exec cap #{Shellwords.escape(target)} \
91
+ app:update_secrets < /dev/null`.split("\n")
92
+ puts results
93
+ if $CHILD_STATUS.exitstatus.zero?
94
+ if results.include?('No changed secret files to upload')
95
+ @unchanged_targets << target
96
+ log("Unchanged target #{target}")
97
+ elsif results.grep(/^Uploaded [0-9]+ changed secret files: /).any?
98
+ @changed_targets << target
99
+ log("Changed target #{target}")
100
+ else
101
+ @failed_targets << target
102
+ log("Unparseable result deploying to target #{target}")
103
+ end
104
+ else
105
+ @failed_targets << target
106
+ log("Failed to deploy to target #{target}")
107
+ end
108
+ end
109
+ end
110
+
111
+ def publish_results
112
+ slack_publisher = NdrDevSupport::SlackMessagePublisher.new(ENV['SLACK_WEBHOOK_URL'],
113
+ username: 'Rake CI',
114
+ icon_emoji: ':robot_face:',
115
+ channel: ENV['SLACK_CHANNEL'])
116
+ slack_publisher.post(attachments: attachments)
117
+ end
118
+
119
+ # Status / warning messages for slack notifications
120
+ def attachments
121
+ attachments = []
122
+
123
+ if @failed_targets.any?
124
+ attachment = {
125
+ color: 'danger',
126
+ title: "#{@failed_targets.count} failed credential updates :rotating_light:",
127
+ text: "Failed targets: `#{@failed_targets.join(', ')}`",
128
+ footer: 'bundle exec cap target app:update_secrets',
129
+ mrkdwn_in: ['text']
130
+ }
131
+ attachments << attachment
132
+ puts attachment.inspect
133
+ end
134
+
135
+ if @changed_targets.any?
136
+ text = "Changed targets: `#{@changed_targets.join(', ')}`\n"
137
+ text << (if @unchanged_targets.any?
138
+ "Unchanged targets: `#{@unchanged_targets.join(', ')}`"
139
+ else
140
+ 'No unchanged targets'
141
+ end)
142
+ attachment = {
143
+ color: 'good',
144
+ title: "#{@changed_targets.size} successful credential updates",
145
+ text: text,
146
+ footer: 'bundle exec cap target app:update_secrets',
147
+ mrkdwn_in: ['text']
148
+ }
149
+ attachments << attachment
150
+ puts attachment.inspect
151
+ end
152
+
153
+ attachments
154
+ end
155
+ end
156
+ end
157
+ end
@@ -1,5 +1,6 @@
1
1
  load 'tasks/audit_code.rake'
2
2
  load 'tasks/audit_bundle.rake'
3
+ load 'tasks/cd/credentials.rake'
3
4
  load 'tasks/ci/brakeman.rake'
4
5
  load 'tasks/ci/bundle_audit.rake'
5
6
  load 'tasks/ci/commit_cop.rake'
@@ -2,5 +2,5 @@
2
2
  # This defines the NdrDevSupport version. If you change it, rebuild and commit the gem.
3
3
  # Use "rake build" to build the gem, see rake -T for all bundler rake tasks (and our own).
4
4
  module NdrDevSupport
5
- VERSION = '6.1.6'
5
+ VERSION = '6.1.7'
6
6
  end
@@ -0,0 +1,9 @@
1
+ namespace :cd do
2
+ desc 'Run Capistrano Continuous Deployment credentials server'
3
+ task :credentials do
4
+ require 'ndr_dev_support/daemon/cd_credentials'
5
+
6
+ worker = NdrDevSupport::Daemon::CDCredentials.from_args(ENV)
7
+ worker.run
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ndr_dev_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.6
4
+ version: 6.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - NCRS Development Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-01 00:00:00.000000000 Z
11
+ date: 2022-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -422,6 +422,7 @@ files:
422
422
  - lib/ndr_dev_support/capistrano/standalone_gems.rb
423
423
  - lib/ndr_dev_support/capistrano/svn_cache.rb
424
424
  - lib/ndr_dev_support/capistrano/sysadmin_scripts.rb
425
+ - lib/ndr_dev_support/daemon/cd_credentials.rb
425
426
  - lib/ndr_dev_support/daemon/ci_server.rb
426
427
  - lib/ndr_dev_support/daemon/stoppable.rb
427
428
  - lib/ndr_dev_support/integration_testing.rb
@@ -452,6 +453,7 @@ files:
452
453
  - lib/ndr_dev_support/version.rb
453
454
  - lib/tasks/audit_bundle.rake
454
455
  - lib/tasks/audit_code.rake
456
+ - lib/tasks/cd/credentials.rake
455
457
  - lib/tasks/ci/brakeman.rake
456
458
  - lib/tasks/ci/bundle_audit.rake
457
459
  - lib/tasks/ci/commit_cop.rake