metatron 0.4.2 → 0.5.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: fe8d0dcac1a47b872ca203dea9ec4e816e07fdb2bb14fd01f6458ca4b7789cef
4
- data.tar.gz: 255bc8c1efdd1c173455f3b28533ceffd70e34115aad86dba1f685dfceba1318
3
+ metadata.gz: 9252f0668ef9d7bb533e87c696ee1c19968bfc2029b9c9992c2defe42360e8d7
4
+ data.tar.gz: f0570ad8ffd6ba0256316dce95f0143e5972117851f0e6080d4ff6a773fa8461
5
5
  SHA512:
6
- metadata.gz: ca1ba6ad7b4b5aa5677b6e7bbd30fe7b643f1f9459232a950d97684430fec3d3c7b710c327aa5a98e8d9324ebe457950df9acb1b50df0678eb875b2f869b6a8d
7
- data.tar.gz: 1c7bc21979e3087dd5e55a381d7fddb9ade45159a72a105ba6d306dd60a8cb34828bad8d9a3ee7db6e1025f5b839e287a3bc21daaa834cb8aa49f31ade19943d
6
+ metadata.gz: 8b80a57ab9b8deccfe861e08baedf2c220319443a89d38f3607dc20f8654243b29cb84d35c0da0a4c795f4619be6d32d1c8cb9ee799705046799456f79e5b7ba
7
+ data.tar.gz: 0d29f8ad2e9b74338ddf8ff2aaaf219541e069e5ae9cbad6cc2bc8ad6e30d65c9c723231d2cd86fc55778ae19bd9161cd60f1e5ac700a9159ebb166fe34fbf15
data/.rubocop.yml CHANGED
@@ -56,3 +56,6 @@ Style/StringLiteralsInInterpolation:
56
56
  Style/StringConcatenation:
57
57
  Exclude:
58
58
  - 'Rakefile'
59
+
60
+ RSpec/ExampleLength:
61
+ Max: 10
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,47 @@
1
+ # Contributing
2
+
3
+ ## How to Contribute Code
4
+
5
+ I'm so glad you're reading this, because we need volunteer developers to help this project grow and thrive!
6
+
7
+ Before you begin, ensure that your contribution is associated with a [GitHub issue](https://github.com/jgnagy/metatron/issues). If there isn't an existing issue, please create one.
8
+
9
+ 1. Fork the repository
10
+ 2. Create a new branch (`git checkout -b feature-branch`)
11
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
12
+ 4. Push to the branch (`git push origin feature-branch`)
13
+ 5. Create a new [Pull Request](http://help.github.com/pull-requests/)
14
+
15
+ ### Testing
16
+
17
+ Please make sure that your code passes the existing tests and add tests for any new functionality. Please write [RSpec](https://rspec.info/) examples for new features you add or modify.
18
+
19
+ To execute the tests, run `bundle exec rake spec`.
20
+
21
+ ### Coding Style
22
+
23
+ This project uses [Rubocop](https://rubocop.org/) to enforce a consistent coding style. Please make sure that your code passes the Rubocop checks.
24
+
25
+ To execute Rubocop, run `bundle exec rake rubocop`.
26
+
27
+ ### Documentation
28
+
29
+ Please make sure that your code is well documented. If you add new features, please add documentation for them. This project uses [YARD](https://yardoc.org/) for documentation, so please add YARD tags to your code when appropriate.
30
+
31
+ ### License
32
+
33
+ By contributing your code, you agree to license your contribution under the terms of the [MIT License](LICENSE.txt).
34
+
35
+ ## Code of Conduct
36
+
37
+ By participating in this project, you agree to abide by our [Code of Conduct](CODE_OF_CONDUCT.md).
38
+
39
+ ## Reporting Bugs
40
+
41
+ Please use the [GitHub issue tracker](https://github.com/jgnagy/metatron/issues) to report any bugs.
42
+
43
+ ## Suggesting Enhancements
44
+
45
+ If you have ideas for enhancements or improvements please use the [GitHub issue tracker](https://github.com/jgnagy/metatron/issues) to suggest them.
46
+
47
+ Thank you for your interest in contributing!
data/Gemfile.lock CHANGED
@@ -1,9 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- metatron (0.4.2)
4
+ metatron (0.5.0)
5
5
  json (~> 2.6)
6
- puma (~> 6.3)
7
6
  sinatra (~> 3.1)
8
7
  sinatra-contrib (~> 3.1)
9
8
 
@@ -27,7 +26,6 @@ GEM
27
26
  multi_json (1.15.0)
28
27
  mustermann (3.0.0)
29
28
  ruby2_keywords (~> 0.0.1)
30
- nio4r (2.6.0)
31
29
  nokogiri (1.15.4-arm64-darwin)
32
30
  racc (~> 1.4)
33
31
  nokogiri (1.15.4-x86_64-linux)
@@ -36,8 +34,6 @@ GEM
36
34
  parser (3.2.2.4)
37
35
  ast (~> 2.4.1)
38
36
  racc
39
- puma (6.4.0)
40
- nio4r (~> 2.0)
41
37
  racc (1.7.3)
42
38
  rack (2.2.8)
43
39
  rack-protection (3.1.0)
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Metatron is a Ruby library for creating [Metacontroller](https://metacontroller.github.io/metacontroller/)-based custom Kubernetes controllers.
4
4
 
5
- The intention is to make it as easy as possible to use Ruby to manage [custom resources](https://kubernetes.io/docs/concepts/api-extension/custom-resources/) within your Kubernetes infrastructure. No Golang required to listen for and respond to resources based on your own [CustomResourceDefinition](https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/) or to modify existing kubernetes resources via a [DecoratorController](https://metacontroller.github.io/metacontroller/api/decoratorcontroller.html).
5
+ The intention is to make it as easy as possible to use Ruby to manage [custom resources](https://kubernetes.io/docs/concepts/api-extension/custom-resources/) within your Kubernetes infrastructure. No Golang required!
6
6
 
7
- Your Ruby code doesn't have to have any _real_ knowledge of the Kubernetes environment in which it operates; Metacontroller takes care of all the Kubernetes interactions and Metatron handles providing the JSON interface. Just write a `sync` method that can receive and respond with the appropriate Hashes and you're on your way!
7
+ For more information, see the [Metatron Wiki on GitHub](https://github.com/jgnagy/metatron/wiki)!
8
8
 
9
9
  ## Usage
10
10
 
@@ -107,7 +107,7 @@ spec:
107
107
  namespace: blog-controller
108
108
  port: 9292
109
109
  protocol: http
110
- path: /sync
110
+ path: /blogs/sync
111
111
  ```
112
112
 
113
113
  Before applying the above though, we'll need to actually create a service that can response to sync requests. That's where Metatron comes in!
@@ -120,7 +120,8 @@ As Metatron is a tool for creating Ruby projects, you'll need a few prerequistes
120
120
  $ git init blog_controller && cd blog_controller
121
121
  ```
122
122
 
123
- We'll need a `Gemfile` to ensure we have Metatron installed:
123
+ We'll need a `Gemfile` to ensure we have installed both Metatron and a
124
+ [`rack`][] compatible server:
124
125
 
125
126
  ```ruby
126
127
  # frozen_string_literal: true
@@ -128,9 +129,12 @@ We'll need a `Gemfile` to ensure we have Metatron installed:
128
129
  source "https://rubygems.org"
129
130
 
130
131
  gem "metatron"
132
+ gem "puma"
131
133
  ```
132
134
 
133
- We'll also need a `config.ru` file to instruct [`rack`](https://github.com/rack/rack) how to route requests:
135
+ [`rack`]: https://github.com/rack/rack
136
+
137
+ We'll also need a `config.ru` file to instruct [`rack`][] how to route requests:
134
138
 
135
139
  ```ruby
136
140
  # frozen_string_literal: true
@@ -138,7 +142,7 @@ We'll also need a `config.ru` file to instruct [`rack`](https://github.com/rack/
138
142
  # \ -s puma
139
143
 
140
144
  require "metatron"
141
- require_relative "./lib/blog_controller/sync"
145
+ require_relative "./lib/blog_controller/composite_controller"
142
146
 
143
147
  use Rack::ShowExceptions
144
148
  use Rack::Deflater
@@ -147,7 +151,7 @@ mappings = {
147
151
  # This one is built-in to Metatron and is useful for monitoring
148
152
  "/ping" => Metatron::Controllers::Ping.new,
149
153
  # We'll need to make this one
150
- "/sync" => BlogController::Sync.new
154
+ "/blogs" => BlogController::CompositeController.new
151
155
  }
152
156
 
153
157
  run Rack::URLMap.new(mappings)
@@ -177,13 +181,13 @@ ENTRYPOINT ["bundle", "exec"]
177
181
  CMD ["puma"]
178
182
  ```
179
183
 
180
- *Phew*, ok, with all that out of the way, we can get started with our development. We'll need to create a `Metatron::SyncController` subclass with a `sync` method. We'll put this in `lib/blog_controller/sync.rb`:
184
+ *Phew*, ok, with all that out of the way, we can get started with our development. We'll need to create a `Metatron::CompositeController` subclass with a `sync` method. We'll put this in `lib/blog_controller/composite_controller.rb`:
181
185
 
182
186
  ```ruby
183
187
  # frozen_string_literal: true
184
188
 
185
189
  module BlogController
186
- class Sync < Metatron::SyncController
190
+ class CompositeController < Metatron::CompositeController
187
191
  # This method needs to return a Hash which will be converted to JSON
188
192
  # It should have the keys "status" (a Hash) and "children" (an Array)
189
193
  def sync
@@ -326,7 +330,7 @@ Try POSTing a request via `curl` and inspecting the JSON response to see what yo
326
330
  $ curl \
327
331
  -H "Content-Type: application/json" \
328
332
  --data '{"parent": {"metadata": {"name": "foo"}, "spec": {"replicas": 1, "image": "nginx:latest"}}}' \
329
- http://localhost:9292/sync
333
+ http://localhost:9292/blogs/sync
330
334
  ```
331
335
 
332
336
  Once we've confirmed this works, we'll need to publish our image somewhere and run it. Make sure you update the Service details in `blog-controller.yaml` to reflect its actual location.
data/Rakefile CHANGED
@@ -16,4 +16,36 @@ task :demo do
16
16
  system("rackup --host 0.0.0.0 -P #{File.expand_path(".")}/tmp/daemon.pid")
17
17
  end
18
18
 
19
+ desc "automatically bump the gem's version"
20
+ task :bump, [:type] do |_t, args|
21
+ type = args[:type] || ENV["TYPE"] || "patch"
22
+ current_version = Metatron::VERSION
23
+ new_version = calculate_new_version(type)
24
+ puts "Bumping gem version from #{current_version} to #{new_version}"
25
+ update_version(new_version)
26
+ end
27
+
19
28
  task default: %i[spec rubocop yard]
29
+
30
+ def calculate_new_version(type)
31
+ version = Metatron::VERSION.split(".").map(&:to_i)
32
+ case type
33
+ when "patch"
34
+ version[2] += 1
35
+ when "minor"
36
+ version[1] += 1
37
+ version[2] = 0
38
+ when "major"
39
+ version[0] += 1
40
+ version[1] = 0
41
+ version[2] = 0
42
+ end
43
+
44
+ version.join(".")
45
+ end
46
+
47
+ def update_version(new_version)
48
+ file = File.read("lib/metatron/version.rb")
49
+ new_contents = file.gsub(/VERSION = "(.+)"/, %(VERSION = "#{new_version}"))
50
+ File.write("lib/metatron/version.rb", new_contents)
51
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metatron
4
+ # Implementes a Metacontroller CompositeController
5
+ # @see https://metacontroller.github.io/metacontroller/api/compositecontroller.html
6
+ class CompositeController < Controller
7
+ options "/sync" do
8
+ headers "Access-Control-Allow-Methods" => ["POST"]
9
+ halt 200
10
+ end
11
+
12
+ post "/sync" do
13
+ if (provided_etag = calculate_sync_etag)
14
+ etag provided_etag
15
+ end
16
+
17
+ data = sync
18
+ data[:children] = data[:children]&.map { |c| c.respond_to?(:render) ? c.render : c }
19
+ halt(data.to_json)
20
+ end
21
+
22
+ options "/finalize" do
23
+ headers "Access-Control-Allow-Methods" => ["POST"]
24
+ halt 200
25
+ end
26
+
27
+ post "/finalize" do
28
+ # finalize calls should be rare and unique enough that we don't need to worry about ETags
29
+
30
+ data = finalize
31
+ data[:children] = data[:children]&.map { |c| c.respond_to?(:render) ? c.render : c }
32
+ halt(data.to_json)
33
+ end
34
+
35
+ options "/customize" do
36
+ headers "Access-Control-Allow-Methods" => ["POST"]
37
+ halt 200
38
+ end
39
+
40
+ post "/customize" do
41
+ if (provided_etag = calculate_customize_etag)
42
+ etag provided_etag
43
+ end
44
+
45
+ halt(customize.to_json)
46
+ end
47
+
48
+ def calculate_customize_etag = nil
49
+ def calculate_sync_etag = nil
50
+ def customize = raise NotImplementedError
51
+ def finalize = raise NotImplementedError
52
+ def sync = raise NotImplementedError
53
+ end
54
+ end
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Metatron
4
- VERSION = [
5
- 0, # major
6
- 4, # minor
7
- 2 # patch
8
- ].join(".")
4
+ VERSION = "0.5.0"
9
5
  end
data/lib/metatron.rb CHANGED
@@ -46,6 +46,6 @@ require "metatron/templates/service"
46
46
  require "metatron/templates/service_account"
47
47
  require "metatron/templates/stateful_set"
48
48
  require "metatron/controller"
49
- require "metatron/sync_controller"
49
+ require "metatron/composite_controller"
50
50
  require "metatron/controllers/ping"
51
51
  require "metatron/railtie" if defined? Rails::Railtie
data/metatron.gemspec CHANGED
@@ -27,7 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.required_ruby_version = "~> 3.1"
28
28
 
29
29
  spec.add_runtime_dependency "json", "~> 2.6"
30
- spec.add_runtime_dependency "puma", "~> 6.3"
31
30
  spec.add_runtime_dependency "sinatra", "~> 3.1"
32
31
  spec.add_runtime_dependency "sinatra-contrib", "~> 3.1"
33
32
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metatron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Gnagy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-16 00:00:00.000000000 Z
11
+ date: 2023-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.6'
27
- - !ruby/object:Gem::Dependency
28
- name: puma
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '6.3'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '6.3'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: sinatra
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -246,6 +232,8 @@ files:
246
232
  - ".rspec"
247
233
  - ".rubocop.yml"
248
234
  - ".ruby-version"
235
+ - CODE_OF_CONDUCT.md
236
+ - CONTRIBUTING.md
249
237
  - Gemfile
250
238
  - Gemfile.lock
251
239
  - LICENSE.txt
@@ -253,10 +241,10 @@ files:
253
241
  - Rakefile
254
242
  - bin/console
255
243
  - lib/metatron.rb
244
+ - lib/metatron/composite_controller.rb
256
245
  - lib/metatron/controller.rb
257
246
  - lib/metatron/controllers/ping.rb
258
247
  - lib/metatron/railtie.rb
259
- - lib/metatron/sync_controller.rb
260
248
  - lib/metatron/template.rb
261
249
  - lib/metatron/templates/cluster_role.rb
262
250
  - lib/metatron/templates/cluster_role_binding.rb
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Metatron
4
- # Used for "normal" sync requests
5
- class SyncController < Controller
6
- options "/" do
7
- headers "Access-Control-Allow-Methods" => ["POST"]
8
- halt 200
9
- end
10
-
11
- post "/" do
12
- if (provided_etag = calculate_etag)
13
- etag provided_etag
14
- end
15
-
16
- data = sync
17
- data[:children] = data[:children]&.map { |c| c.respond_to?(:render) ? c.render : c }
18
- halt(data.to_json)
19
- end
20
-
21
- def calculate_etag = nil
22
- def sync = raise NotImplementedError
23
- end
24
- end