kube-templates 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0414a2f5df5fc9f4f45536cd46731f74e62482bd
4
+ data.tar.gz: 317e628839d7664bc34b5800d7caaa60e3ee2439
5
+ SHA512:
6
+ metadata.gz: 8e39d263917b785ec37b589811735477d409245a7582d1e169a733b2da87369d71800351f2f6c222f37fd6cb36d886ee35a41086f1a550c502fdab711e44350f
7
+ data.tar.gz: 290430c9754af9fc61211c3a2b541f32cda9d7a7e388bf56742794065a7e1743466396134d407ca64eccf95da3d2beab03b843398f21e41ec210745e9c7a758c
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+
14
+ ## Environment normalization:
15
+ /.bundle/
16
+ /vendor/bundle
17
+ /lib/bundler/man/
18
+
19
+ Gemfile.lock
20
+ .ruby-version
21
+ .ruby-gemset
22
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ kube-templates
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby 2.3.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in kube-templates.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Keylime Toolbox
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # Kube::Templates
2
+
3
+ Simple template system for Kubernetes deployments.
4
+
5
+ We built this to handle deploying resque workers as containers. For each of our Rails
6
+ apps we may have 50 or more resque workers running that code base, listening to different
7
+ queues. This simplified the deployment by allowing us to provide a single Deployment template
8
+ and then generate lots of deployment configurations with the right settings for the queues
9
+ for the workers to listen to and the number of replicas.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem "kube-templates"
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install kube-templates
26
+
27
+ ## Usage
28
+
29
+ `Kube::Templates::Builder` takes a template file and a configuration file, assigning values from the
30
+ configuration file and emitting a collection of deployments for kubernetes to run.
31
+
32
+ ### Example
33
+
34
+ Create a deployment template. In this file you can have template variables (e.g. `${QUEUES}`) that
35
+ will be replaced with values from your configuration. In the following we use three variables,
36
+ `${NAME}`, `${REPLICAS}`, and `${QUEUES}`.
37
+
38
+ # resque-template.yaml
39
+ apiVersion: extensions/v1beta1
40
+ kind: Deployment
41
+ metadata:
42
+ name: resque-${NAME}
43
+ spec:
44
+ replicas: ${REPLICAS}
45
+ template:
46
+ metadata:
47
+ labels:
48
+ service: rails
49
+ app: my-app
50
+ purpose: worker
51
+ queues: ${QUEUES}
52
+ spec:
53
+ containers:
54
+ - name: my-app
55
+ image: us.gcr.io/project-id-1138/my-app-resque:latest
56
+ env:
57
+ - name: QUEUE
58
+ value: ${QUEUES}
59
+
60
+ Create a configuration file that defines your workers. In the following file we define two types
61
+ of workers. One, with four replicas, listens onthe "reports" queue. A second listens on the
62
+ "process_priority" and "process" queues. This second worker will have two replicas set as that
63
+ values it defined in the "defaults" section and it doesn't change it.
64
+
65
+ # resque-workers.yml
66
+ defaults:
67
+ replicas: 2
68
+ workers:
69
+ - queues: reports
70
+ replicas: 4
71
+ name: builder
72
+ - queues: process_priority,process
73
+
74
+ Note that while we can define the `NAME` variable, as we did for the first worker, we don't
75
+ need to and the `Builder` will automatically generate a name from the values provided for
76
+ the worker. So the second worker would have a name "process-priority-process"
77
+
78
+ Use the `resque-k8s` command to create a series of YAML deployments
79
+ for kubernetes to consume. You can pipe the output to less to see what it produces.
80
+
81
+ $ resque-k8s | less
82
+
83
+ To apply this run the `kubectl apply` command with the value from the configuration.
84
+
85
+ $ resque-k8s | kubectl apply -f -
86
+
87
+
88
+ ## Other options
89
+
90
+ This is a very simple implementation. There are a number of solutions out there that propose to
91
+ do something similar in the scope of larger efforts.
92
+
93
+ - There is currently a proposal to
94
+ [support this in Kubernetes](https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/templates.md).
95
+
96
+ - [kb8or](https://github.com/UKHomeOffice/kb8or) includes something like this with many more continuous deployment
97
+ features
98
+
99
+ - Kubernetes [Helm](https://helm.sh/) does this with its [charts](https://github.com/kubernetes/helm/tree/master/docs/examples/alpine).
100
+
101
+ ## Development
102
+
103
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
104
+ also run `bin/console` for an interactive prompt that will allow you to experiment.
105
+
106
+ To install this gem onto your local machine, run `bundle exec rake install`.
107
+
108
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
109
+ which will create a git tag for the version, push git commits and tags, and push the `.gem` file to
110
+ [rubygems.org](https://rubygems.org).
111
+
112
+ ## Contributing
113
+
114
+ Bug reports and pull requests are welcome on GitHub at https://github.com/keylimetoolbox/kube-templates.
115
+
116
+
117
+ ## License
118
+
119
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "kube/templates"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "kube/templates/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kube-templates"
8
+ spec.version = Kube::Templates::VERSION
9
+ spec.authors = ["Jeremy Wadsack"]
10
+ spec.email = ["jeremy.wadsack@gmail.com"]
11
+
12
+ spec.summary = %q{Simple template system for Kubernetes deployments.}
13
+ spec.description = %q{Rapidly generate many Kubernetes deployments from a template and a simple YAML configuration file.}
14
+ spec.homepage = "https://github.com/keylimetoolbox/kube-templates"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.12"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.0"
25
+ end
@@ -0,0 +1,152 @@
1
+ require "yaml"
2
+
3
+ module Kube
4
+ module Templates
5
+ # Applies a template of a kubernetes configuration with options for resque
6
+ # workers and builds out deployments for all workers
7
+ #
8
+ # Example
9
+ #
10
+ # Given a kubernetes deployment configuration template:
11
+ #
12
+ # # resque-template.yaml
13
+ # apiVersion: extensions/v1beta1
14
+ # kind: Deployment
15
+ # metadata:
16
+ # name: resque-${NAME}
17
+ # spec:
18
+ # replicas: ${REPLICAS}
19
+ # template:
20
+ # metadata:
21
+ # labels:
22
+ # service: rails
23
+ # app: my-app
24
+ # purpose: worker
25
+ # queues: ${QUEUES}
26
+ # spec:
27
+ # containers:
28
+ # - name: my-app
29
+ # image: us.gcr.io/project-id-1138/my-app-resque:latest
30
+ # env:
31
+ # - name: QUEUE
32
+ # value: ${QUEUES}
33
+ #
34
+ # And the following worker configuration
35
+ #
36
+ # # resque-workers.yml
37
+ # defaults:
38
+ # replicas: 2
39
+ # workers:
40
+ # - queues: reports
41
+ # replicas: 4
42
+ # name: builder
43
+ # - queues: process_priority,process
44
+ #
45
+ # Use the `resque-k8s` command to create a series of YAML deployments
46
+ # for kubernetes to consume. Then use `kubectl apply` command to configure
47
+ # the cluster.
48
+ #
49
+ # $ resque-k8s | kubectl apply -f -
50
+ class Builder
51
+
52
+ # Create a template handler for the template and configuration.
53
+ #
54
+ # template_file The name or IO of the file that has the kubernetes deployment template.
55
+ # config_file The name or IO of the file that has the resque configuration.
56
+ #
57
+ # For either argument you can provide the path to the template file or
58
+ # you can provide an `IO` object for the `Builder` to read. With an `IO`
59
+ # object you are responsible for closing the stream.
60
+ #
61
+ # Examples:
62
+ # Kube::Templates::Builder.new("resque-template.yml", "resque-workers.yml")
63
+ #
64
+ # File.open("resque-template.yml") do |template|
65
+ # File.open("resque-workers.yml") do |config|
66
+ # Kube::Templates::Builder.new(template, config))
67
+ # end
68
+ # end
69
+ #
70
+ # Note that if you want to provide a string value to the `Builder` you can
71
+ # just use a `StringIO` instance.
72
+ #
73
+ # Kube::Templates::Builder.new(StringIO.new(template), StringIO.new(config))
74
+ def initialize(template_file, config_file)
75
+ @template = readfile(template_file)
76
+ @config = YAML.load(readfile(config_file))
77
+ end
78
+
79
+ # Returns a string of YAML configurations, concatenated with "---" line,
80
+ # for each configuration defined.
81
+ #
82
+ # The `config_file` must have a "workers" property which is a collection
83
+ # of properties that are applied to the template. Template variables are
84
+ # case insensitive, but configuration keys must all be lower case.
85
+ #
86
+ # You can also provide a "defaults" section that applies default values
87
+ # for any worker that does not have a specific value defined.
88
+ #
89
+ # There is a special ${NAME} property that you can use in your template. If
90
+ # not provided as a value, it will default to, roughly, the values for
91
+ # the worker concatenated with "-".
92
+ #
93
+ # Example:
94
+ # # resque-workers.yml
95
+ # defaults:
96
+ # replicas: 2
97
+ # workers:
98
+ # - queues: reports
99
+ # replicas: 4
100
+ # name: builder
101
+ # - queues: process_priority,process
102
+ #
103
+ # For this configuration, `#build` would create two YAML configurations.
104
+ # The first assigns these values in the template:
105
+ # ${QUEUES} = "reports"
106
+ # ${REPLICAS} = 4
107
+ # ${NAME} = "builder"
108
+ # The second assigns these values in the template:
109
+ # ${QUEUES} = "process_priority,process"
110
+ # ${REPLICAS} = 2
111
+ # ${NAME} = "process-priority-process"
112
+ #
113
+ # Configurations are returned in the order defined in the `config_file`.
114
+ def build
115
+ defaults = @config["defaults"] || {}
116
+ configs = @config["workers"].map do |worker|
117
+ # TODO: We should #downcase the keys for the variables as well
118
+ variables = defaults.merge(worker)
119
+ @template.gsub(/\$\{([^}]+)\}/) do |match|
120
+ key = Regexp.last_match[1].downcase
121
+ if variables.key? key
122
+ variables[key]
123
+ elsif key == "name"
124
+ # NB This doesn't handle utf-8 characters at all
125
+ name_from_values(worker.values)
126
+ else
127
+ match
128
+ end
129
+ end
130
+ end
131
+
132
+ configs.join("---\n")
133
+ end
134
+
135
+ private
136
+
137
+ def readfile(file)
138
+ if file.is_a? String
139
+ File.read(file)
140
+ elsif file.respond_to?(:read)
141
+ file.read
142
+ else
143
+ raise ArgumentError.new("Don't know how to read #{file.class}")
144
+ end
145
+ end
146
+
147
+ def name_from_values(values)
148
+ values.join("-").gsub(/[^-a-zA-Z0-9]/, "-").gsub(/--+/, "-").gsub(/\A-|-\Z/, "")
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,5 @@
1
+ module Kube
2
+ module Templates
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require "kube/templates/version"
2
+ require "kube/templates/builder"
3
+
4
+ module Kube
5
+ module Templates
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kube-templates
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Wadsack
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-08-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Rapidly generate many Kubernetes deployments from a template and a simple
56
+ YAML configuration file.
57
+ email:
58
+ - jeremy.wadsack@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".ruby-gemset"
66
+ - ".ruby-version"
67
+ - Gemfile
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - bin/console
72
+ - bin/setup
73
+ - kube-templates.gemspec
74
+ - lib/kube/templates.rb
75
+ - lib/kube/templates/builder.rb
76
+ - lib/kube/templates/version.rb
77
+ homepage: https://github.com/keylimetoolbox/kube-templates
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.5.1
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Simple template system for Kubernetes deployments.
101
+ test_files: []