mina-kubernetes 1.0.1
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 +7 -0
- data/.gitignore +1 -0
- data/README.md +55 -0
- data/Rakefile +1 -0
- data/lib/mina/kubernetes.rb +108 -0
- data/lib/mina/kubernetes/version.rb +5 -0
- data/mina-kubernetes.gemspec +30 -0
- metadata +147 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1f1fd603c840045e6402d4eee5e82b997a3e31459b2e33f904bff8541cf4ce42
|
4
|
+
data.tar.gz: b31401cfce0e729fabbc51e0aa37841a7b6e907639fc5fa572046ac4e3916924
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 83b16882b97e8b5a1e2bfd13a2143955443c39d9fb3166c457457510cffd375e32b468a1d4fba608e0822425ebd61d9abd40a12a38fbcc037ea6d6707ad0abd4
|
7
|
+
data.tar.gz: 8cfc7cc45cb7dbf508a97ad3c3c6ecff2d094530672a3fb38676426d25448a2d676a0e362d45507cbf89066caa06db971864cfbf26878f360446f5c117f54ca3
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# mina-kubernetes
|
2
|
+
Plugin for the [mina](https://github.com/mina-deploy/mina) deployment tool to streamline deployment of resources to Kubernetes cluster, using the [kubernetes-deploy](https://github.com/Shopify/kubernetes-deploy) gem and [mina-multistage](https://github.com/endoze/mina-multistage) plugin.
|
3
|
+
|
4
|
+
Requires local Docker and [kubectl](https://cloud.google.com/kubernetes-engine/docs/quickstart) with authentication set up to connect to the destination Kubernetes cluster.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
Add `mina-kubernetes` to your local Gemfile.
|
9
|
+
|
10
|
+
Create a configuration file for mina in `config/deploy.rb` like the one below:
|
11
|
+
```ruby
|
12
|
+
require "mina/default"
|
13
|
+
require "mina/kubernetes"
|
14
|
+
|
15
|
+
task :deploy do
|
16
|
+
invoke :"kubernetes:deploy"
|
17
|
+
end
|
18
|
+
```
|
19
|
+
|
20
|
+
Add the following variables to your stage configuration i.e. `config/deploy/production.rb`:
|
21
|
+
```ruby
|
22
|
+
set :app_name, "my_app"
|
23
|
+
set :image_repository, "gcr.io/project-id/myapp"
|
24
|
+
set :kubernetes_cluster, "kubernetes_cluster_name"
|
25
|
+
set :kubernetes_user, "kubernetes_user_name"
|
26
|
+
```
|
27
|
+
|
28
|
+
If `set :image_tag, "my_image_tag"` is also defined, it'll be used to deploy the image tagged with this tag on the repository. Otherwise you'll be prompted to pick a branch from current working Git repository and the image to deploy will be assumed to be tagged with the Git commit hash, i.e. `gcr.io/project-123456/my_app:abcd1234`.
|
29
|
+
|
30
|
+
Optional configuration (showing default values):
|
31
|
+
```ruby
|
32
|
+
set :kube_config, "~/.kube/config"
|
33
|
+
```
|
34
|
+
|
35
|
+
Then create `*.yml.erb` Kubernetes resource definition files in the stage folder, i.e. `config/deploy/production/app.yml.erb`. Occurences of `<%= image_repo %>` and `<%= current_sha %>` in these files will be dynamically replaced on deploy by the image repository URL and the latest commit hash of the selected branch on its git origin.
|
36
|
+
|
37
|
+
When you run `mina production deploy`, a namespace labelled `my_app-production` will be created on the Kubernetes cluster and set as a local kubectl context. Then the resources are applied to the cluster after checking/waiting for the image to be available on the repository.
|
38
|
+
|
39
|
+
### Tasks available
|
40
|
+
|
41
|
+
#### `kubernetes:deploy`
|
42
|
+
|
43
|
+
Creates namespace on cluster and assigns it to a local kubectl context, prompts for git branch if no image tag specified, applies all resources to cluster after checking tagged image is available.
|
44
|
+
|
45
|
+
#### `kubernetes:bash`
|
46
|
+
|
47
|
+
Prompts for branch unless image tag is set, then spins up a temporary pod with the image and opens up a remote bash terminal.
|
48
|
+
|
49
|
+
#### `kubernetes:command`
|
50
|
+
|
51
|
+
Prompts for branch unless image tag is set, then spins up a temporary pod with the image and run command given by task variable `command`, for instance with `set :command, "rails console"`. Environment variables can also be given by defining`env_hash`, i.e. `set :env_hash, {"RAILS_ENV" => "production", "MY_VAR" => "abcd123"}`
|
52
|
+
|
53
|
+
#### `kubernetes:delete`
|
54
|
+
|
55
|
+
Confirms and delete all resources on cluster under namespace `app_name-stage`.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require "tty-prompt"
|
2
|
+
require "tty-spinner"
|
3
|
+
require "securerandom"
|
4
|
+
require "json"
|
5
|
+
require "base64"
|
6
|
+
|
7
|
+
# required by mina
|
8
|
+
set :execution_mode, :pretty
|
9
|
+
|
10
|
+
# default for kubernetes-deploy
|
11
|
+
set :kube_config, "~/.kube/config"
|
12
|
+
|
13
|
+
namespace :kubernetes do
|
14
|
+
|
15
|
+
set :namespace, fetch(:app_name)
|
16
|
+
set :context, "#{fetch(:namespace)}-#{fetch(:stage)}"
|
17
|
+
|
18
|
+
task :deploy do
|
19
|
+
desc "Set image tag to be latest commit of prompted branch (unless provided) then applies resources to cluster"
|
20
|
+
set_tag_from_branch_commit unless fetch(:image_tag)
|
21
|
+
wait_until_image_ready(fetch(:image_tag))
|
22
|
+
create_namespace_on_cluster
|
23
|
+
set_local_config_context
|
24
|
+
apply_kubernetes_resources
|
25
|
+
end
|
26
|
+
|
27
|
+
task :bash do
|
28
|
+
desc "Spins up temporary pod with image and opens remote interactive bash"
|
29
|
+
set_tag_from_branch_commit unless fetch(:image_tag)
|
30
|
+
wait_until_image_ready(fetch(:image_tag))
|
31
|
+
run_terminal_command("bash")
|
32
|
+
end
|
33
|
+
|
34
|
+
task :command do
|
35
|
+
desc "Spins up temporary pod with image and runs given command in interactive shell, passing given environment variable"
|
36
|
+
set_tag_from_branch_commit unless fetch(:image_tag)
|
37
|
+
wait_until_image_ready(fetch(:image_tag))
|
38
|
+
run_terminal_command(fetch(:command), fetch(:env_hash))
|
39
|
+
end
|
40
|
+
|
41
|
+
task :delete do
|
42
|
+
desc "Delete all resources in namespace on cluster"
|
43
|
+
if TTY::Prompt.new.yes?("This will delete all resources in namespace #{fetch(:namespace)} on cluster #{fetch(:kubernetes_cluster)}, are you sure?")
|
44
|
+
run :local do
|
45
|
+
comment "Deleting all resources in #{fetch(:namespace)}..."
|
46
|
+
command "kubectl delete namespace #{fetch(:namespace)} --cluster=#{fetch(:kubernetes_cluster)}"
|
47
|
+
comment "Removing local config context..."
|
48
|
+
command "kubectl config unset contexts.#{fetch(:context)}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def set_tag_from_branch_commit
|
58
|
+
run :local do
|
59
|
+
comment "Updating Git branches..."
|
60
|
+
end
|
61
|
+
remote_branches = `git fetch --prune && git branch -r --no-merged master --sort=-committerdate | grep origin`.split("\n").collect { |b| b.strip.gsub("origin/", "") }.reject { |b| b == "master" }
|
62
|
+
set :branch, TTY::Prompt.new.select("Which branch?", ["master"].concat(remote_branches))
|
63
|
+
set :image_tag, `git rev-parse origin/#{fetch(:branch)}`.split("\n")[0]
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_namespace_on_cluster
|
67
|
+
run :local do
|
68
|
+
comment "Create/update namespace on Kubernetes cluster..."
|
69
|
+
command "kubectl create namespace #{fetch(:namespace)} --dry-run -o yaml | kubectl apply -f - --cluster=#{fetch(:kubernetes_cluster)}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def set_local_config_context
|
74
|
+
run :local do
|
75
|
+
comment "Set up local Kubernetes config context..."
|
76
|
+
command "kubectl config set-context #{fetch(:context)} --namespace=#{fetch(:namespace)} --cluster=#{fetch(:kubernetes_cluster)} --user=#{fetch(:kubernetes_user)}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def wait_until_image_ready(commit)
|
81
|
+
run :local do
|
82
|
+
comment "Check image #{fetch(:image_repo)}:#{commit} is available..."
|
83
|
+
end
|
84
|
+
spinner = TTY::Spinner.new
|
85
|
+
spinner.auto_spin
|
86
|
+
while !image_available?(commit)
|
87
|
+
sleep 5
|
88
|
+
end
|
89
|
+
spinner.stop
|
90
|
+
end
|
91
|
+
|
92
|
+
def image_available?(commit)
|
93
|
+
system("docker manifest inspect #{fetch(:image_repo)}:#{commit} > /dev/null") == true
|
94
|
+
end
|
95
|
+
|
96
|
+
def run_terminal_command(command, env_hash = {})
|
97
|
+
env = env_hash.collect{|k,v| "--env #{k}=#{v}" }.join(" ")
|
98
|
+
label = command.downcase.gsub(" ", "-").gsub(":", "-")
|
99
|
+
# using system instead of mina's command so tty opens successfully
|
100
|
+
system "kubectl run #{label}-#{SecureRandom.hex(4)} --rm -i --tty --restart=Never --context=#{fetch(:context)} --image #{fetch(:image_repo)}:#{fetch(:image_tag)} #{env} -- #{command}"
|
101
|
+
end
|
102
|
+
|
103
|
+
def apply_kubernetes_resources
|
104
|
+
run :local do
|
105
|
+
comment "Apply all Kubernetes resources..."
|
106
|
+
command "REVISION=#{fetch(:image_tag)} KUBECONFIG=#{fetch(:kube_config)} ENVIRONMENT=#{fetch(:stage)} kubernetes-deploy --bindings=image_repo=#{fetch(:image_repo)},image_tag=#{fetch(:image_tag)},namespace=#{fetch(:namespace)} #{fetch(:namespace)} #{fetch(:context)}"
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mina/kubernetes/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'mina-kubernetes'
|
8
|
+
spec.version = Mina::Kubernetes::VERSION
|
9
|
+
spec.authors = ['Antoine Sabourin']
|
10
|
+
spec.email = ['antoine@streem.com.au']
|
11
|
+
|
12
|
+
spec.summary = %q{Mina plugin to streamline deployment of resources to Kubernetes cluster}
|
13
|
+
spec.description = %q{Mina plugin to streamline deployment of resources to Kubernetes cluster}
|
14
|
+
spec.homepage = 'https://github.com/streemau/mina-kubernetes'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
|
25
|
+
spec.add_runtime_dependency 'mina', '~> 1.0'
|
26
|
+
spec.add_runtime_dependency 'mina-multistage', '~> 1.0'
|
27
|
+
spec.add_runtime_dependency 'kubernetes-deploy'
|
28
|
+
spec.add_runtime_dependency 'tty-prompt'
|
29
|
+
spec.add_runtime_dependency 'tty-spinner'
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mina-kubernetes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Antoine Sabourin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-05-20 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.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
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: mina
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mina-multistage
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: kubernetes-deploy
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: tty-prompt
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: tty-spinner
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Mina plugin to streamline deployment of resources to Kubernetes cluster
|
112
|
+
email:
|
113
|
+
- antoine@streem.com.au
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- README.md
|
120
|
+
- Rakefile
|
121
|
+
- lib/mina/kubernetes.rb
|
122
|
+
- lib/mina/kubernetes/version.rb
|
123
|
+
- mina-kubernetes.gemspec
|
124
|
+
homepage: https://github.com/streemau/mina-kubernetes
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
metadata: {}
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubygems_version: 3.0.3
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Mina plugin to streamline deployment of resources to Kubernetes cluster
|
147
|
+
test_files: []
|