metatron 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.roxanne.yml +14 -0
- data/.rspec +3 -0
- data/.rubocop.yml +55 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +144 -0
- data/LICENSE.txt +21 -0
- data/README.md +11 -0
- data/Rakefile +19 -0
- data/lib/metatron/controller.rb +38 -0
- data/lib/metatron/controllers/ping.rb +36 -0
- data/lib/metatron/sync_controller.rb +15 -0
- data/lib/metatron/template.rb +33 -0
- data/lib/metatron/templates/concerns/annotated.rb +27 -0
- data/lib/metatron/templates/concerns/pod_producer.rb +85 -0
- data/lib/metatron/templates/deployment.rb +71 -0
- data/lib/metatron/templates/ingress.rb +148 -0
- data/lib/metatron/templates/pod.rb +46 -0
- data/lib/metatron/templates/secret.rb +33 -0
- data/lib/metatron/templates/service.rb +55 -0
- data/lib/metatron/templates/stateful_set.rb +85 -0
- data/lib/metatron/version.rb +9 -0
- data/lib/metatron.rb +39 -0
- data/metatron.gemspec +46 -0
- data/scripts/build.sh +3 -0
- data/scripts/release.sh +7 -0
- data/scripts/test.sh +6 -0
- metadata +297 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5e862a2cda63cf2dba7bf6016c6d03bd2f1e21bae464da3425285c0741b6ddbb
|
4
|
+
data.tar.gz: e77e818e65755a7db7d4c72e096fe849bd3a099f7534c531a89f1f106d6c89a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9d89f4c380b31d8b957ee25ab6859704dfaf113c158fcfe69d794dcd4b2d300be498494befed03cd4fce8c23459ad2fcebb9d31ab826519c86969d2e9a4e16ba
|
7
|
+
data.tar.gz: 3958c107c80854470f790741242caa846c9109a138347f6793a037bcabd16a6e7dfac8bf52f91b957d16b74828a629e30f402ca5e9ffadb616aa904c012f6463
|
data/.gitignore
ADDED
data/.roxanne.yml
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rake
|
3
|
+
- rubocop-rspec
|
4
|
+
|
5
|
+
Layout/LineLength:
|
6
|
+
Max: 100
|
7
|
+
|
8
|
+
AllCops:
|
9
|
+
Exclude:
|
10
|
+
- 'db/schema.rb'
|
11
|
+
- 'vendor/**/*'
|
12
|
+
TargetRubyVersion: 3.1
|
13
|
+
NewCops: enable
|
14
|
+
|
15
|
+
Metrics/AbcSize:
|
16
|
+
Max: 21
|
17
|
+
|
18
|
+
Metrics/BlockLength:
|
19
|
+
Max: 35
|
20
|
+
Exclude:
|
21
|
+
- 'spec/**/*_spec.rb'
|
22
|
+
- 'Rakefile'
|
23
|
+
- '*.gemspec'
|
24
|
+
|
25
|
+
Metrics/MethodLength:
|
26
|
+
Max: 25
|
27
|
+
|
28
|
+
Metrics/ModuleLength:
|
29
|
+
Max: 160
|
30
|
+
Exclude:
|
31
|
+
- 'spec/**/*_spec.rb'
|
32
|
+
|
33
|
+
Metrics/ClassLength:
|
34
|
+
Max: 300
|
35
|
+
Exclude:
|
36
|
+
- 'spec/**/*_spec.rb'
|
37
|
+
|
38
|
+
Gemspec/RequireMFA:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Style/MixinUsage:
|
42
|
+
Exclude:
|
43
|
+
- "bin/console"
|
44
|
+
|
45
|
+
Style/StringLiterals:
|
46
|
+
Enabled: true
|
47
|
+
EnforcedStyle: double_quotes
|
48
|
+
|
49
|
+
Style/StringLiteralsInInterpolation:
|
50
|
+
Enabled: true
|
51
|
+
EnforcedStyle: double_quotes
|
52
|
+
|
53
|
+
Style/StringConcatenation:
|
54
|
+
Exclude:
|
55
|
+
- 'Rakefile'
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.1.2
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
metatron (0.1.0)
|
5
|
+
json (~> 2.6)
|
6
|
+
puma (~> 5.6)
|
7
|
+
sinatra (~> 2.2)
|
8
|
+
sinatra-contrib (~> 2.2)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
ast (2.4.2)
|
14
|
+
backport (1.2.0)
|
15
|
+
benchmark (0.2.0)
|
16
|
+
byebug (11.1.3)
|
17
|
+
diff-lcs (1.5.0)
|
18
|
+
docile (1.4.0)
|
19
|
+
e2mmap (0.1.0)
|
20
|
+
jaro_winkler (1.5.4)
|
21
|
+
json (2.6.2)
|
22
|
+
kramdown (2.4.0)
|
23
|
+
rexml
|
24
|
+
kramdown-parser-gfm (1.1.0)
|
25
|
+
kramdown (~> 2.0)
|
26
|
+
multi_json (1.15.0)
|
27
|
+
mustermann (1.1.2)
|
28
|
+
ruby2_keywords (~> 0.0.1)
|
29
|
+
nio4r (2.5.8)
|
30
|
+
nokogiri (1.13.8-arm64-darwin)
|
31
|
+
racc (~> 1.4)
|
32
|
+
nokogiri (1.13.8-x86_64-linux)
|
33
|
+
racc (~> 1.4)
|
34
|
+
parallel (1.22.1)
|
35
|
+
parser (3.1.2.1)
|
36
|
+
ast (~> 2.4.1)
|
37
|
+
puma (5.6.5)
|
38
|
+
nio4r (~> 2.0)
|
39
|
+
racc (1.6.0)
|
40
|
+
rack (2.2.4)
|
41
|
+
rack-protection (2.2.1)
|
42
|
+
rack
|
43
|
+
rack-test (2.0.2)
|
44
|
+
rack (>= 1.3)
|
45
|
+
rainbow (3.1.1)
|
46
|
+
rake (12.3.3)
|
47
|
+
regexp_parser (2.5.0)
|
48
|
+
reverse_markdown (2.1.1)
|
49
|
+
nokogiri
|
50
|
+
rexml (3.2.5)
|
51
|
+
rspec (3.11.0)
|
52
|
+
rspec-core (~> 3.11.0)
|
53
|
+
rspec-expectations (~> 3.11.0)
|
54
|
+
rspec-mocks (~> 3.11.0)
|
55
|
+
rspec-core (3.11.0)
|
56
|
+
rspec-support (~> 3.11.0)
|
57
|
+
rspec-expectations (3.11.0)
|
58
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
59
|
+
rspec-support (~> 3.11.0)
|
60
|
+
rspec-mocks (3.11.1)
|
61
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
62
|
+
rspec-support (~> 3.11.0)
|
63
|
+
rspec-support (3.11.0)
|
64
|
+
rubocop (1.36.0)
|
65
|
+
json (~> 2.3)
|
66
|
+
parallel (~> 1.10)
|
67
|
+
parser (>= 3.1.2.1)
|
68
|
+
rainbow (>= 2.2.2, < 4.0)
|
69
|
+
regexp_parser (>= 1.8, < 3.0)
|
70
|
+
rexml (>= 3.2.5, < 4.0)
|
71
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
72
|
+
ruby-progressbar (~> 1.7)
|
73
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
74
|
+
rubocop-ast (1.21.0)
|
75
|
+
parser (>= 3.1.1.0)
|
76
|
+
rubocop-rake (0.6.0)
|
77
|
+
rubocop (~> 1.0)
|
78
|
+
rubocop-rspec (2.12.1)
|
79
|
+
rubocop (~> 1.31)
|
80
|
+
ruby-progressbar (1.11.0)
|
81
|
+
ruby2_keywords (0.0.5)
|
82
|
+
simplecov (0.21.2)
|
83
|
+
docile (~> 1.1)
|
84
|
+
simplecov-html (~> 0.11)
|
85
|
+
simplecov_json_formatter (~> 0.1)
|
86
|
+
simplecov-cobertura (2.1.0)
|
87
|
+
rexml
|
88
|
+
simplecov (~> 0.19)
|
89
|
+
simplecov-html (0.12.3)
|
90
|
+
simplecov_json_formatter (0.1.4)
|
91
|
+
sinatra (2.2.1)
|
92
|
+
mustermann (~> 1.0)
|
93
|
+
rack (~> 2.2)
|
94
|
+
rack-protection (= 2.2.1)
|
95
|
+
tilt (~> 2.0)
|
96
|
+
sinatra-contrib (2.2.1)
|
97
|
+
multi_json
|
98
|
+
mustermann (~> 1.0)
|
99
|
+
rack-protection (= 2.2.1)
|
100
|
+
sinatra (= 2.2.1)
|
101
|
+
tilt (~> 2.0)
|
102
|
+
solargraph (0.46.0)
|
103
|
+
backport (~> 1.2)
|
104
|
+
benchmark
|
105
|
+
bundler (>= 1.17.2)
|
106
|
+
diff-lcs (~> 1.4)
|
107
|
+
e2mmap
|
108
|
+
jaro_winkler (~> 1.5)
|
109
|
+
kramdown (~> 2.3)
|
110
|
+
kramdown-parser-gfm (~> 1.1)
|
111
|
+
parser (~> 3.0)
|
112
|
+
reverse_markdown (>= 1.0.5, < 3)
|
113
|
+
rubocop (>= 0.52)
|
114
|
+
thor (~> 1.0)
|
115
|
+
tilt (~> 2.0)
|
116
|
+
yard (~> 0.9, >= 0.9.24)
|
117
|
+
thor (1.2.1)
|
118
|
+
tilt (2.0.11)
|
119
|
+
unicode-display_width (2.2.0)
|
120
|
+
webrick (1.7.0)
|
121
|
+
yard (0.9.28)
|
122
|
+
webrick (~> 1.7.0)
|
123
|
+
|
124
|
+
PLATFORMS
|
125
|
+
arm64-darwin-21
|
126
|
+
x86_64-linux
|
127
|
+
|
128
|
+
DEPENDENCIES
|
129
|
+
bundler (~> 2.3)
|
130
|
+
byebug (~> 11)
|
131
|
+
metatron!
|
132
|
+
rack-test (~> 2.0)
|
133
|
+
rake (~> 12.3)
|
134
|
+
rspec (~> 3.10)
|
135
|
+
rubocop (~> 1.31)
|
136
|
+
rubocop-rake (~> 0.6)
|
137
|
+
rubocop-rspec (~> 2.11)
|
138
|
+
simplecov (~> 0.21)
|
139
|
+
simplecov-cobertura (~> 2.1)
|
140
|
+
solargraph (~> 0.45)
|
141
|
+
yard (~> 0.9)
|
142
|
+
|
143
|
+
BUNDLED WITH
|
144
|
+
2.3.18
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2022 Jonathan Gnagy
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Metatron
|
2
|
+
|
3
|
+
Metatron in a Ruby library for creating [Metacontroller](https://metacontroller.github.io/metacontroller/)-based custom Kubernetes controllers.
|
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).
|
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 can receive and respond with the appropriate Hashes and you're on your way!
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
TODO (still a very early draft)
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ENV["RACK_ENV"] ||= "development"
|
4
|
+
|
5
|
+
require "bundler/gem_tasks"
|
6
|
+
require "rspec/core/rake_task"
|
7
|
+
require "rubocop/rake_task"
|
8
|
+
require "yard"
|
9
|
+
|
10
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
|
+
RuboCop::RakeTask.new(:rubocop)
|
12
|
+
YARD::Rake::YardocTask.new
|
13
|
+
|
14
|
+
desc "allows running a demo controller"
|
15
|
+
task :demo do
|
16
|
+
system("rackup --host 0.0.0.0 -P #{File.expand_path(".")}/tmp/daemon.pid")
|
17
|
+
end
|
18
|
+
|
19
|
+
task default: %i[spec rubocop yard]
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metatron
|
4
|
+
# Base class for API services
|
5
|
+
class Controller < Sinatra::Base
|
6
|
+
helpers Sinatra::CustomLogger
|
7
|
+
|
8
|
+
configure do
|
9
|
+
set :protection, except: :http_origin
|
10
|
+
set :logging, true
|
11
|
+
set :logger, Metatron::LOGGER
|
12
|
+
set :show_exceptions, false
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
# Sets up a useful variable (@json_body) for accessing a parsed request body
|
17
|
+
if request.content_type&.include?("json") && !request.body.read.empty?
|
18
|
+
request.body.rewind
|
19
|
+
@json_body = JSON.parse(request.body.read)
|
20
|
+
end
|
21
|
+
rescue StandardError => e
|
22
|
+
halt(400, { error: "Request must be JSON: #{e.message}}" }.to_json)
|
23
|
+
end
|
24
|
+
|
25
|
+
error do
|
26
|
+
content_type :json
|
27
|
+
|
28
|
+
e = env["sinatra.error"]
|
29
|
+
resp = { result: "error", message: e.message }
|
30
|
+
resp[:trace] = e.full_message if settings.environment.to_s != "production"
|
31
|
+
resp.to_json
|
32
|
+
end
|
33
|
+
|
34
|
+
def request_body
|
35
|
+
@json_body
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metatron
|
4
|
+
module Controllers
|
5
|
+
# Healthcheck service
|
6
|
+
class Ping < Sinatra::Application
|
7
|
+
configure do
|
8
|
+
set :logging, true
|
9
|
+
set :logger, Metatron::LOGGER
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
content_type "application/json"
|
14
|
+
|
15
|
+
halt 403 unless request.get? || request.options?
|
16
|
+
|
17
|
+
if request.get?
|
18
|
+
headers "X-Frame-Options" => "SAMEORIGIN"
|
19
|
+
headers "X-XSS-Protection" => "1; mode=block"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
after do
|
24
|
+
headers "Access-Control-Allow-Methods" => %w[GET] if request.options?
|
25
|
+
end
|
26
|
+
|
27
|
+
get "/" do
|
28
|
+
'{ "status": "up" }'
|
29
|
+
end
|
30
|
+
|
31
|
+
options "/" do
|
32
|
+
halt 200
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
halt(sync.to_json)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metatron
|
4
|
+
# Base class for templating Kubernetes resources
|
5
|
+
class Template
|
6
|
+
attr_accessor :api_version, :label_namespace, :name
|
7
|
+
attr_reader :kind
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name
|
11
|
+
@label_namespace = "metatron.therubyist.org"
|
12
|
+
@api_version = "v1"
|
13
|
+
run_initializers
|
14
|
+
end
|
15
|
+
|
16
|
+
alias apiVersion api_version
|
17
|
+
|
18
|
+
def self.initializer(*args)
|
19
|
+
@initializers ||= []
|
20
|
+
@initializers += args
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.initializers
|
24
|
+
@initializers ||= []
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def run_initializers
|
30
|
+
self.class.initializers.each { |initializer| send(initializer.to_sym) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metatron
|
4
|
+
module Templates
|
5
|
+
module Concerns
|
6
|
+
# Makes supporting annotated resources easier
|
7
|
+
module Annotated
|
8
|
+
def self.included(base)
|
9
|
+
# base.extend ClassMethods
|
10
|
+
base.class_eval do
|
11
|
+
attr_accessor :annotations
|
12
|
+
|
13
|
+
initializer :annotated_initialize
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def annotated_initialize
|
18
|
+
@annotations = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def formatted_annotations
|
22
|
+
annotations && !annotations.empty? ? { annotations: } : {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metatron
|
4
|
+
module Templates
|
5
|
+
module Concerns
|
6
|
+
# A mixin to assist with templating Kubernetes resources that create Pods
|
7
|
+
module PodProducer
|
8
|
+
def self.included(base)
|
9
|
+
# base.extend ClassMethods
|
10
|
+
base.class_eval do
|
11
|
+
attr_accessor :image, :image_pull_policy, :additional_labels, :env, :envfrom,
|
12
|
+
:resource_limits, :resource_requests, :probes, :ports, :security_context,
|
13
|
+
:volume_mounts, :volumes, :additional_containers,
|
14
|
+
:container_security_context, :affinity
|
15
|
+
|
16
|
+
initializer :pod_producer_initialize
|
17
|
+
|
18
|
+
alias_method :imagePullPolicy, :image_pull_policy
|
19
|
+
alias_method :volumeMounts, :volume_mounts
|
20
|
+
alias_method :securityContext, :security_context
|
21
|
+
alias_method :environment, :env
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def pod_producer_initialize
|
26
|
+
@image = "gcr.io/google_containers/pause"
|
27
|
+
@image_pull_policy = "IfNotPresent"
|
28
|
+
@resource_limits = { memory: "512Mi", cpu: "500m" }
|
29
|
+
@resource_requests = { memory: "64Mi", cpu: "10m" }
|
30
|
+
@affinity = {}
|
31
|
+
@env = {}
|
32
|
+
@envfrom = []
|
33
|
+
@probes = {}
|
34
|
+
@ports = []
|
35
|
+
@volume_mounts = []
|
36
|
+
@volumes = []
|
37
|
+
@security_context = {}
|
38
|
+
@container_security_context = {}
|
39
|
+
@additional_containers = []
|
40
|
+
@additional_labels = {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def formatted_affinity
|
44
|
+
affinity && !affinity.empty? ? { affinity: } : {}
|
45
|
+
end
|
46
|
+
|
47
|
+
def formatted_environment
|
48
|
+
env && !env.empty? ? { env: env.map { |k, v| { name: k, value: v } } } : {}
|
49
|
+
end
|
50
|
+
|
51
|
+
def formatted_envfrom
|
52
|
+
if envfrom && !envfrom.empty?
|
53
|
+
{ envFrom: envfrom.map { |secret| { secretRef: { name: secret } } } }
|
54
|
+
else
|
55
|
+
{}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def formatted_ports
|
60
|
+
ports&.any? ? { ports: } : {}
|
61
|
+
end
|
62
|
+
|
63
|
+
def formatted_security_context
|
64
|
+
security_context && !security_context.empty? ? { securityContext: } : {}
|
65
|
+
end
|
66
|
+
|
67
|
+
def formatted_container_security_context
|
68
|
+
if container_security_context && !container_security_context.empty?
|
69
|
+
{ securityContext: container_security_context }
|
70
|
+
else
|
71
|
+
{}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def formatted_volume_mounts
|
76
|
+
volume_mounts&.any? ? { volumeMounts: } : {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def formatted_volumes
|
80
|
+
volumes&.any? ? { volumes: } : {}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metatron
|
4
|
+
module Templates
|
5
|
+
# The Deployment Kubernetes resource
|
6
|
+
class Deployment < Template
|
7
|
+
include Concerns::Annotated
|
8
|
+
include Concerns::PodProducer
|
9
|
+
|
10
|
+
attr_accessor :replicas, :pod_annotations,
|
11
|
+
:additional_labels, :additional_pod_labels
|
12
|
+
|
13
|
+
def initialize(name, replicas: 2)
|
14
|
+
super(name)
|
15
|
+
@api_version = "apps/v1"
|
16
|
+
@kind = "Deployment"
|
17
|
+
@replicas = replicas
|
18
|
+
@pod_annotations = {}
|
19
|
+
@additional_pod_labels = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def formatted_pod_annotations
|
23
|
+
pod_annotations && !pod_annotations.empty? ? { annotations: pod_annotations } : {}
|
24
|
+
end
|
25
|
+
|
26
|
+
# rubocop:disable Metrics/MethodLength
|
27
|
+
# rubocop:disable Metrics/AbcSize
|
28
|
+
def render
|
29
|
+
{
|
30
|
+
apiVersion:,
|
31
|
+
kind:,
|
32
|
+
metadata: {
|
33
|
+
name:,
|
34
|
+
labels: { "#{label_namespace}/name": name }.merge(additional_labels)
|
35
|
+
}.merge(formatted_annotations),
|
36
|
+
spec: {
|
37
|
+
replicas:,
|
38
|
+
strategy: { type: "RollingUpdate", rollingUpdate: { maxSurge: 2, maxUnavailable: 0 } },
|
39
|
+
selector: {
|
40
|
+
matchLabels: { "#{label_namespace}/name": name }.merge(additional_pod_labels)
|
41
|
+
},
|
42
|
+
template: {
|
43
|
+
metadata: {
|
44
|
+
labels: { "#{label_namespace}/name": name }.merge(additional_pod_labels)
|
45
|
+
}.merge(formatted_pod_annotations),
|
46
|
+
spec: {
|
47
|
+
containers: [
|
48
|
+
{
|
49
|
+
name: "app",
|
50
|
+
image:,
|
51
|
+
imagePullPolicy:,
|
52
|
+
stdin: true,
|
53
|
+
tty: true,
|
54
|
+
resources: { limits: resource_limits, requests: resource_requests }
|
55
|
+
}.merge(probes)
|
56
|
+
.merge(formatted_environment)
|
57
|
+
.merge(formatted_envfrom)
|
58
|
+
.merge(formatted_ports)
|
59
|
+
.merge(formatted_volume_mounts)
|
60
|
+
.merge(formatted_container_security_context)
|
61
|
+
] + additional_containers
|
62
|
+
}.merge(formatted_volumes).merge(formatted_security_context)
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
end
|
67
|
+
# rubocop:enable Metrics/AbcSize
|
68
|
+
# rubocop:enable Metrics/MethodLength
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|