rops 1.3.0 → 1.4.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: 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