mina-kubernetes 1.0.1 → 2.4.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 +4 -4
- data/CHANGELOG.md +45 -0
- data/README.md +34 -13
- data/lib/mina/kubernetes.rb +30 -27
- data/lib/mina/kubernetes/version.rb +2 -2
- data/mina-kubernetes.gemspec +4 -4
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7930f648e0b70eeb94a1413fee561b8edcdac3c28918bf003bee6c77749f9537
|
4
|
+
data.tar.gz: 5df185bd2d8cf21dbe0d520b799e8654d793400822a9d2522a760614dabf4e97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47f3c48b9157ca35688e8b45cee5e20c8c844c05b128e899f5cee1c15b9db60773a16f6b636fcf15c84bcbf27b78b4c66e6c4f5758397c693d277615f7b23abf
|
7
|
+
data.tar.gz: ce3221d0774d3d386c95af184798c9a98d67559f43481ea84b75a13119a6bb57fc35b5eafa9ca60a9a5d4e879805328b0dc5b47f162ff20d885d5e4aea95228c
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
## 2.4.0
|
2
|
+
|
3
|
+
*Enhancements*
|
4
|
+
|
5
|
+
- Use `secrets.ejson` if present
|
6
|
+
|
7
|
+
## 2.3.0
|
8
|
+
|
9
|
+
*Enhancements*
|
10
|
+
|
11
|
+
- Allow using a proxy to connect to a Kubernetes cluster
|
12
|
+
|
13
|
+
## 2.2.4
|
14
|
+
|
15
|
+
*Fixes*
|
16
|
+
|
17
|
+
- run custom command within given namespace instead of `default`
|
18
|
+
|
19
|
+
## 2.2.1 to 2.2.3
|
20
|
+
|
21
|
+
*Fixes*
|
22
|
+
|
23
|
+
- handle nil/undefined options passed to `krane`
|
24
|
+
|
25
|
+
## 2.2.0
|
26
|
+
|
27
|
+
*Enhancements*
|
28
|
+
|
29
|
+
- Using `krane` 1.0.0 (previously `kubernetes-deploy`)
|
30
|
+
- Allow passing of options to `krane`
|
31
|
+
|
32
|
+
## 2.1.0
|
33
|
+
|
34
|
+
Yanked release.
|
35
|
+
|
36
|
+
## 2.0.0
|
37
|
+
|
38
|
+
*Breaking*
|
39
|
+
|
40
|
+
- Using `namespace` config variable instead of `app_name`
|
41
|
+
- Using `kubernetes_context` config variable linking directly to a context set in $KUBE_CONFIG instead of creating a new context from separate `kubernetes_cluster` and `kubernetes_user` config variables
|
42
|
+
|
43
|
+
*Fixes*
|
44
|
+
|
45
|
+
- Not overriding $KUBE_CONFIG environment variable anymore
|
data/README.md
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
# mina-kubernetes
|
2
|
-
Plugin for the [mina](https://github.com/mina-deploy/mina) deployment tool to streamline deployment of resources to Kubernetes
|
2
|
+
Plugin for the [mina](https://github.com/mina-deploy/mina) deployment tool to streamline deployment of resources to Kubernetes clusters, using the [krane](https://github.com/Shopify/krane) gem and [mina-multistage](https://github.com/endoze/mina-multistage) plugin.
|
3
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.
|
4
|
+
Requires local Docker and [kubectl](https://cloud.google.com/kubernetes-engine/docs/quickstart) with local authentication set up to connect to the destination Kubernetes cluster as context in your local KUBE_CONFIG. See https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#generate_kubeconfig_entry for example with Google Kubernetes Engine.
|
5
|
+
|
6
|
+
NB: `docker manifest inspect` is used to check whether the Docker image with requested tag is available. This requires experimental features to be enabled in your local Docker config by adding `"experimental": "enabled"` to `~/.docker/config.json`.
|
7
|
+
If the image repository is not public authentication will need to be set up for your local Docker, for instance see https://cloud.google.com/container-registry/docs/advanced-authentication#gcloud_as_a_docker_credential_helper for images hosted on the Google Cloud Registry
|
5
8
|
|
6
9
|
## Usage
|
7
10
|
|
8
|
-
Add `mina-kubernetes` to your local Gemfile.
|
11
|
+
Add `mina-kubernetes` to your local Gemfile.
|
9
12
|
|
10
13
|
Create a configuration file for mina in `config/deploy.rb` like the one below:
|
11
14
|
```ruby
|
12
15
|
require "mina/default"
|
16
|
+
require "mina/multistage"
|
13
17
|
require "mina/kubernetes"
|
14
18
|
|
15
19
|
task :deploy do
|
@@ -19,22 +23,39 @@ end
|
|
19
23
|
|
20
24
|
Add the following variables to your stage configuration i.e. `config/deploy/production.rb`:
|
21
25
|
```ruby
|
22
|
-
set :
|
23
|
-
set :
|
24
|
-
set :
|
25
|
-
set :kubernetes_user, "kubernetes_user_name"
|
26
|
+
set :namespace, "my_app"
|
27
|
+
set :image_repo, "gcr.io/project-id/myapp"
|
28
|
+
set :kubernetes_context, "kubernetes_context_name"
|
26
29
|
```
|
27
30
|
|
28
31
|
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
32
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
Then add `*.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.
|
34
|
+
|
35
|
+
You can also get the RAILS_MASTER_KEY for encrypted credentials deployed as a Kubernetes secrets by adding a secrets.yml.erb like below:
|
36
|
+
```yml
|
37
|
+
apiVersion: v1
|
38
|
+
kind: Secret
|
39
|
+
metadata:
|
40
|
+
name: secrets
|
41
|
+
data:
|
42
|
+
RAILS_MASTER_KEY: <%= Base64.strict_encode64(File.read("#{Dir.pwd}/config/credentials/production.key").strip) %>
|
33
43
|
```
|
34
44
|
|
35
|
-
|
45
|
+
When running `mina production deploy`, it'll prompt for a branch and check the image tagged with current commit hash from selected branch is available on the repository. Then the `krane` executable is called to fill in the variables in the resource templates and apply them all to the cluster under the given namespace (see https://github.com/Shopify/krane#deploy-walkthrough for more details)\
|
46
|
+
|
47
|
+
### EJSON Encrypted secrets
|
48
|
+
|
49
|
+
Krane supports generating Kubernetes secrets from an encrypted EJSON file: https://github.com/Shopify/krane#deploying-kubernetes-secrets-from-ejson. As per current Krane documentation "The ejson file must be included in the resources passed to --filenames it can not be read through stdin.", so
|
50
|
+
following convention-over-configuration principles `mina-kubernetes` checks for the presence of a file named `secrets.ejson` in the stage folder and uses it if available.
|
51
|
+
|
52
|
+
### Passing options to krane
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
invoke :"kubernetes:deploy", "--no-prune"
|
56
|
+
```
|
36
57
|
|
37
|
-
|
58
|
+
Refer to https://github.com/Shopify/krane#usage for a complete set of options
|
38
59
|
|
39
60
|
### Tasks available
|
40
61
|
|
@@ -52,4 +73,4 @@ Prompts for branch unless image tag is set, then spins up a temporary pod with t
|
|
52
73
|
|
53
74
|
#### `kubernetes:delete`
|
54
75
|
|
55
|
-
Confirms and delete all resources on cluster under namespace
|
76
|
+
Confirms and delete all resources on cluster under namespace.
|
data/lib/mina/kubernetes.rb
CHANGED
@@ -7,45 +7,37 @@ require "base64"
|
|
7
7
|
# required by mina
|
8
8
|
set :execution_mode, :pretty
|
9
9
|
|
10
|
-
# default for kubernetes-deploy
|
11
|
-
set :kube_config, "~/.kube/config"
|
12
|
-
|
13
10
|
namespace :kubernetes do
|
11
|
+
set :proxy, nil
|
14
12
|
|
15
|
-
|
16
|
-
set :context, "#{fetch(:namespace)}-#{fetch(:stage)}"
|
17
|
-
|
18
|
-
task :deploy do
|
13
|
+
task :deploy, [:options] do |task, args|
|
19
14
|
desc "Set image tag to be latest commit of prompted branch (unless provided) then applies resources to cluster"
|
20
15
|
set_tag_from_branch_commit unless fetch(:image_tag)
|
21
16
|
wait_until_image_ready(fetch(:image_tag))
|
22
17
|
create_namespace_on_cluster
|
23
|
-
|
24
|
-
apply_kubernetes_resources
|
18
|
+
apply_kubernetes_resources(args[:options])
|
25
19
|
end
|
26
20
|
|
27
21
|
task :bash do
|
28
22
|
desc "Spins up temporary pod with image and opens remote interactive bash"
|
29
23
|
set_tag_from_branch_commit unless fetch(:image_tag)
|
30
24
|
wait_until_image_ready(fetch(:image_tag))
|
31
|
-
|
25
|
+
run_command("bash")
|
32
26
|
end
|
33
27
|
|
34
28
|
task :command do
|
35
29
|
desc "Spins up temporary pod with image and runs given command in interactive shell, passing given environment variable"
|
36
30
|
set_tag_from_branch_commit unless fetch(:image_tag)
|
37
31
|
wait_until_image_ready(fetch(:image_tag))
|
38
|
-
|
32
|
+
run_command(fetch(:command), env_hash_arg)
|
39
33
|
end
|
40
34
|
|
41
35
|
task :delete do
|
42
36
|
desc "Delete all resources in namespace on cluster"
|
43
|
-
if TTY::Prompt.new.yes?("This will delete all resources in namespace #{fetch(:namespace)} on
|
37
|
+
if TTY::Prompt.new.yes?("This will delete all resources in namespace #{fetch(:namespace)} on context #{fetch(:kubernetes_context)}, are you sure?")
|
44
38
|
run :local do
|
45
39
|
comment "Deleting all resources in #{fetch(:namespace)}..."
|
46
|
-
command "kubectl delete namespace #{fetch(:namespace)} --
|
47
|
-
comment "Removing local config context..."
|
48
|
-
command "kubectl config unset contexts.#{fetch(:context)}"
|
40
|
+
command "kubectl delete namespace #{fetch(:namespace)} --context=#{fetch(:kubernetes_context)}"
|
49
41
|
end
|
50
42
|
end
|
51
43
|
end
|
@@ -54,6 +46,10 @@ end
|
|
54
46
|
|
55
47
|
private
|
56
48
|
|
49
|
+
def env_hash_arg
|
50
|
+
@env_hash_arg ||= (fetch(:env_hash).is_a?(String) ? JSON.parse(fetch(:env_hash)) : fetch(:env_hash)) || {}
|
51
|
+
end
|
52
|
+
|
57
53
|
def set_tag_from_branch_commit
|
58
54
|
run :local do
|
59
55
|
comment "Updating Git branches..."
|
@@ -66,14 +62,8 @@ end
|
|
66
62
|
def create_namespace_on_cluster
|
67
63
|
run :local do
|
68
64
|
comment "Create/update namespace on Kubernetes cluster..."
|
69
|
-
|
70
|
-
|
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)}"
|
65
|
+
proxy_env = "HTTPS_PROXY=#{fetch(:proxy)}" if fetch(:proxy)
|
66
|
+
command "kubectl create namespace #{fetch(:namespace)} --dry-run -o yaml | #{proxy_env} kubectl apply -f - --context=#{fetch(:kubernetes_context)}"
|
77
67
|
end
|
78
68
|
end
|
79
69
|
|
@@ -93,16 +83,29 @@ def image_available?(commit)
|
|
93
83
|
system("docker manifest inspect #{fetch(:image_repo)}:#{commit} > /dev/null") == true
|
94
84
|
end
|
95
85
|
|
96
|
-
def
|
86
|
+
def run_command(command, env_hash = {})
|
97
87
|
env = env_hash.collect{|k,v| "--env #{k}=#{v}" }.join(" ")
|
98
88
|
label = command.downcase.gsub(" ", "-").gsub(":", "-")
|
89
|
+
proxy_env = "HTTPS_PROXY=#{fetch(:proxy)}" if fetch(:proxy)
|
90
|
+
|
99
91
|
# 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(:
|
92
|
+
system "#{proxy_env} kubectl run #{label}-#{SecureRandom.hex(4)} --rm -i --tty --restart=Never --context=#{fetch(:kubernetes_context)} --namespace=#{fetch(:namespace)} --image #{fetch(:image_repo)}:#{fetch(:image_tag)} #{env} -- #{command}"
|
101
93
|
end
|
102
94
|
|
103
|
-
def apply_kubernetes_resources
|
95
|
+
def apply_kubernetes_resources(options)
|
104
96
|
run :local do
|
105
97
|
comment "Apply all Kubernetes resources..."
|
106
|
-
|
98
|
+
|
99
|
+
proxy_env = "HTTPS_PROXY=#{fetch(:proxy)}" if fetch(:proxy)
|
100
|
+
filepaths = options&.[](:filepaths) || "config/deploy/#{fetch(:stage)}"
|
101
|
+
|
102
|
+
render_cmd = "#{proxy_env} krane render --bindings=image_repo=#{fetch(:image_repo)},image_tag=#{fetch(:image_tag)},namespace=#{fetch(:namespace)} --current_sha #{fetch(:image_tag)} -f #{filepaths}"
|
103
|
+
deploy_cmd = "#{proxy_env} krane deploy #{fetch(:namespace)} #{fetch(:kubernetes_context)} --stdin "
|
104
|
+
deploy_cmd += options[:deployment_options] if options&.[](:deployment_options)
|
105
|
+
|
106
|
+
ejson_secrets_path = "#{filepaths}/secrets.ejson"
|
107
|
+
deploy_cmd += " --filenames #{ejson_secrets_path}" if File.exists?(ejson_secrets_path)
|
108
|
+
|
109
|
+
command "#{render_cmd} | #{deploy_cmd}"
|
107
110
|
end
|
108
111
|
end
|
data/mina-kubernetes.gemspec
CHANGED
@@ -20,11 +20,11 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
22
|
spec.add_development_dependency 'bundler', '~> 1.11'
|
23
|
-
spec.add_development_dependency 'rake', '
|
24
|
-
|
23
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
24
|
+
|
25
25
|
spec.add_runtime_dependency 'mina', '~> 1.0'
|
26
26
|
spec.add_runtime_dependency 'mina-multistage', '~> 1.0'
|
27
|
-
spec.add_runtime_dependency '
|
27
|
+
spec.add_runtime_dependency 'krane', '~> 1.0'
|
28
28
|
spec.add_runtime_dependency 'tty-prompt'
|
29
29
|
spec.add_runtime_dependency 'tty-spinner'
|
30
|
-
end
|
30
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mina-kubernetes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Antoine Sabourin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 12.3.3
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 12.3.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: mina
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,19 +67,19 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: krane
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
75
|
+
version: '1.0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
82
|
+
version: '1.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: tty-prompt
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,6 +116,7 @@ extensions: []
|
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
118
|
- ".gitignore"
|
119
|
+
- CHANGELOG.md
|
119
120
|
- README.md
|
120
121
|
- Rakefile
|
121
122
|
- lib/mina/kubernetes.rb
|