rops 1.3.0 → 1.4.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: 5a9aa4788d53d39e653cf9ebe46f3082962b2efecdef76f32fe4ac034fbc5699
4
- data.tar.gz: b47e1bc75453e0e60e596f33893d651ed080e605135b46c73832ebd38291072a
3
+ metadata.gz: 9453ba8aff1b2855c154642cc3f8651ded99e54f7e4ebf99d29b8d2816a52266
4
+ data.tar.gz: 595537c6ee76953ff637f9f26ee9fc8060d8df1df24643e59277663b62f5da77
5
5
  SHA512:
6
- metadata.gz: ad8c81d3214a90a5f59cf12cbdfd5457d0bb2a999bd6b6908617a4b881a6baf4f487ccbcec48de9209974f8c5bcda10fc68cfaef4b0321c3148b6cf889995202
7
- data.tar.gz: a2898286981115871142e4058a04442c79c16dfee9ccb98d2afa49613dca4db4196fdc8e0fa7cef0cbb349b2635632b5ad9e34766de3b046f69f5c68401e1db4
6
+ metadata.gz: d61760400a3b05aa2c93a45fd03970f606404f91b7d8241f6e11c6faabbd93b4f2302427ab653483e3a5a51a0e61293171c9cd05c890da636f3d71f770accbfb
7
+ data.tar.gz: fbf2bbcae3a6efa8977a1b4bd835459b0f5b183e1dbac34bf35a44ef2697ba2cb5b4c5a6d97c19896aa67bfa8c5c05ca1a4138be3a493dcf346ee0ba7b02242f
data/Gemfile CHANGED
@@ -1,3 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
3
  gemspec
4
+
5
+ group :test do
6
+ gem 'rspec'
7
+ gem 'webmock'
8
+ end
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rops (1.2.0)
4
+ rops (1.4.0)
5
5
  activesupport (~> 7.0.3)
6
6
  dry-cli (~> 0.7.0)
7
- git (~> 1.9.1)
7
+ git (>= 1.9.1, < 1.13.0)
8
8
  hashdiff (~> 1.0.1)
9
+ liquid (~> 5.4.0)
9
10
  net-ssh (~> 6.1.0)
10
11
  ptools (~> 1.4.2)
11
12
 
@@ -17,25 +18,53 @@ GEM
17
18
  i18n (>= 1.6, < 2)
18
19
  minitest (>= 5.1)
19
20
  tzinfo (~> 2.0)
21
+ addressable (2.8.1)
22
+ public_suffix (>= 2.0.2, < 6.0)
20
23
  concurrent-ruby (1.1.10)
24
+ crack (0.4.5)
25
+ rexml
26
+ diff-lcs (1.5.0)
21
27
  dry-cli (0.7.0)
22
- git (1.9.1)
28
+ git (1.12.0)
29
+ addressable (~> 2.8)
23
30
  rchardet (~> 1.8)
24
31
  hashdiff (1.0.1)
25
32
  i18n (1.12.0)
26
33
  concurrent-ruby (~> 1.0)
34
+ liquid (5.4.0)
27
35
  minitest (5.16.2)
28
36
  net-ssh (6.1.0)
29
37
  ptools (1.4.2)
38
+ public_suffix (5.0.1)
30
39
  rchardet (1.8.0)
40
+ rexml (3.2.5)
41
+ rspec (3.12.0)
42
+ rspec-core (~> 3.12.0)
43
+ rspec-expectations (~> 3.12.0)
44
+ rspec-mocks (~> 3.12.0)
45
+ rspec-core (3.12.0)
46
+ rspec-support (~> 3.12.0)
47
+ rspec-expectations (3.12.0)
48
+ diff-lcs (>= 1.2.0, < 2.0)
49
+ rspec-support (~> 3.12.0)
50
+ rspec-mocks (3.12.1)
51
+ diff-lcs (>= 1.2.0, < 2.0)
52
+ rspec-support (~> 3.12.0)
53
+ rspec-support (3.12.0)
31
54
  tzinfo (2.0.5)
32
55
  concurrent-ruby (~> 1.0)
56
+ webmock (3.18.1)
57
+ addressable (>= 2.8.0)
58
+ crack (>= 0.3.2)
59
+ hashdiff (>= 0.4.0, < 2.0.0)
33
60
 
34
61
  PLATFORMS
35
62
  x86_64-linux
36
63
 
37
64
  DEPENDENCIES
38
65
  rops!
66
+ rspec
67
+ webmock
39
68
 
40
69
  BUNDLED WITH
41
- 2.2.25
70
+ 2.3.19
data/lib/config.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'yaml'
2
+ require 'base64'
3
+ require 'liquid'
4
+ require_relative 'image'
5
+
6
+ class Config
7
+ CONFIG_LOCATIONS = %w(.rops.yaml platform/rops.yaml config/rops.yaml).freeze
8
+ CONFIG_DEFAULTS = {
9
+ 'repository' => nil,
10
+ 'default_branch' => 'master',
11
+ 'registry' => 'docker.io/r360',
12
+ 'default_context' => 'staging',
13
+ 'production_context' => 'production',
14
+ 'images' => [],
15
+ 'contexts' => {},
16
+ }.freeze
17
+
18
+ attr_reader :repository, :registry, :default_branch, :default_context, :production_context, :ssh_host
19
+ attr_reader :images, :contexts
20
+
21
+ def load(root)
22
+ conf_path = find(root)
23
+ conf = conf_path ? YAML.load_file(conf_path) : {}
24
+ conf = conf.reverse_merge(CONFIG_DEFAULTS)
25
+
26
+ @repository, @registry, @default_branch, @default_context, @production_context, @ssh_host, contexts, images =
27
+ conf.values_at('repository', 'registry', 'default_branch', 'default_context', 'production_context', 'ssh', 'contexts', 'images').map(&:presence)
28
+ @repository ||= root
29
+
30
+ images ||= [{ 'name' => File.basename(File.absolute_path(repository)) }]
31
+ @images = images.map do |image|
32
+ name = image['name']
33
+ dockerfile = image['dockerfile'].presence || 'Dockerfile'
34
+ Image.new(name: name, repository: repository, dockerfile: dockerfile, registry: registry, commit: nil, tag: nil)
35
+ end
36
+
37
+ @contexts = HashWithIndifferentAccess.new(contexts.compact)
38
+ @contexts.each_value do |context|
39
+ notify = context[:notify]
40
+ next unless notify
41
+
42
+ # base64 decode Slack URLs
43
+ if (url = notify[:url])
44
+ notify_url = URI.parse(url)
45
+ unless notify_url.is_a?(URI::HTTP)
46
+ notify_url = URI.parse(Base64.decode64(url))
47
+ end
48
+ notify[:url] = notify_url
49
+ end
50
+
51
+ # parse liquid templates
52
+ if (text = notify[:text])
53
+ notify[:text] = Liquid::Template.parse(text)
54
+ end
55
+ end
56
+
57
+ self
58
+ end
59
+
60
+ private
61
+
62
+ def find(dir)
63
+ return dir unless File.directory?(dir)
64
+ CONFIG_LOCATIONS.map { |location| File.join(dir, location) }.detect { |path| File.exist?(path) }
65
+ end
66
+ end
data/lib/deployer.rb CHANGED
@@ -1,25 +1,21 @@
1
1
  require 'yaml'
2
2
  require 'open3'
3
3
  require 'ptools'
4
+ require 'net/http'
5
+ require 'uri'
6
+
4
7
  require 'git_ext'
8
+ require 'config'
5
9
  require 'image'
6
10
 
7
11
  class Deployer
8
- CONFIG_LOCATIONS = %w(.rops.yaml platform/rops.yaml config/rops.yaml).freeze
9
- CONFIG_DEFAULTS = {
10
- 'repository' => nil,
11
- 'default_branch' => 'master',
12
- 'registry' => 'docker.io/r360',
13
- 'default_context' => 'staging',
14
- 'production_context' => 'production',
15
- 'images' => []
16
- }.freeze
17
-
18
- attr_reader :root, :repository, :registry, :ssh_host, :images
19
- attr_reader :default_branch, :default_context, :production_context
12
+ attr_reader :root, :config
20
13
  attr_reader :branch, :commit, :image_tag
21
14
  attr_accessor :spec_dir
22
15
 
16
+ delegate :repository, :registry, :ssh_host, :images, to: :config
17
+ delegate :default_branch, :default_context, :production_context, to: :config
18
+
23
19
  def self.docker
24
20
  @docker_path ||= File.which('docker') || File.which('podman')
25
21
  end
@@ -29,9 +25,7 @@ class Deployer
29
25
  end
30
26
 
31
27
  def initialize(root = nil)
32
- @images = []
33
28
  @specs = {}
34
-
35
29
  @root = root || Dir.pwd
36
30
  load_config
37
31
  self.branch = default_branch
@@ -94,6 +88,7 @@ class Deployer
94
88
  stdout, stderr, _success = kubectl(context, 'apply -f -', YAML.dump_stream(*specs))
95
89
  puts stdout if stdout.present?
96
90
  puts stderr if stderr.present?
91
+ notify!(context)
97
92
  end
98
93
 
99
94
  def deploy_specs(context = nil)
@@ -161,24 +156,27 @@ private
161
156
  end
162
157
 
163
158
  def load_config
164
- conf_path = find_config(root)
165
- conf = conf_path ? YAML.load_file(conf_path) : {}
166
- conf = conf.reverse_merge(CONFIG_DEFAULTS)
167
-
168
- @repository, @registry, @default_branch, @default_context, @production_context, @ssh_host, images =
169
- conf.values_at('repository', 'registry', 'default_branch', 'default_context', 'production_context', 'ssh', 'images').map(&:presence)
170
- @repository ||= root
171
-
172
- images ||= [{ 'name' => File.basename(File.absolute_path(repository)) }]
173
- @images = images.map do |image|
174
- name = image['name']
175
- dockerfile = image['dockerfile'].presence || 'Dockerfile'
176
- Image.new(name: name, repository: repository, dockerfile: dockerfile, registry: registry, commit: nil, tag: nil)
177
- end
159
+ @config ||= ::Config.new.load(root)
178
160
  end
179
161
 
180
- def find_config(dir_or_path)
181
- return dir_or_path unless File.directory?(dir_or_path)
182
- CONFIG_LOCATIONS.map { |location| File.join(dir_or_path, location) }.detect { |path| File.exist?(path) }
162
+ def notify!(context)
163
+ if (notify = config.contexts[context]&.dig(:notify))
164
+ text = notify[:text].render(
165
+ 'repository' => repository,
166
+ 'registry' => registry,
167
+ 'ssh_host' => ssh_host,
168
+ 'branch' => branch,
169
+ 'commit' => commit,
170
+ 'image_tag' => image_tag,
171
+ )
172
+ url = notify[:url]
173
+ msg = notify.without(:url).symbolize_keys.merge(text: text).compact
174
+
175
+ http = Net::HTTP.new(url.host, url.port)
176
+ http.use_ssl = url.instance_of?(URI::HTTPS)
177
+ request = Net::HTTP::Post.new(url.request_uri, content_type: 'application/json')
178
+ request.body = msg.to_json
179
+ response = http.request(request)
180
+ end
183
181
  end
184
182
  end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Record360
2
2
  module Operations
3
- VERSION = '1.3.0'
3
+ VERSION = '1.4.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rops
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Sloan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-10 00:00:00.000000000 Z
11
+ date: 2022-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-cli
@@ -42,16 +42,22 @@ dependencies:
42
42
  name: git
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.9.1
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: 1.13.0
48
51
  type: :runtime
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
- - - "~>"
55
+ - - ">="
53
56
  - !ruby/object:Gem::Version
54
57
  version: 1.9.1
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: 1.13.0
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: ptools
57
63
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +100,20 @@ dependencies:
94
100
  - - "~>"
95
101
  - !ruby/object:Gem::Version
96
102
  version: 6.1.0
103
+ - !ruby/object:Gem::Dependency
104
+ name: liquid
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 5.4.0
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 5.4.0
97
117
  description: A tool to checkout, build, and deploy projects using Git, Docker, and
98
118
  Kubernetes
99
119
  email: steve@record360.com
@@ -108,6 +128,7 @@ files:
108
128
  - README.md
109
129
  - bin/rops
110
130
  - lib/buildable.rb
131
+ - lib/config.rb
111
132
  - lib/core_ext.rb
112
133
  - lib/deployer.rb
113
134
  - lib/git_ext.rb