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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f1fd603c840045e6402d4eee5e82b997a3e31459b2e33f904bff8541cf4ce42
4
- data.tar.gz: b31401cfce0e729fabbc51e0aa37841a7b6e907639fc5fa572046ac4e3916924
3
+ metadata.gz: 7930f648e0b70eeb94a1413fee561b8edcdac3c28918bf003bee6c77749f9537
4
+ data.tar.gz: 5df185bd2d8cf21dbe0d520b799e8654d793400822a9d2522a760614dabf4e97
5
5
  SHA512:
6
- metadata.gz: 83b16882b97e8b5a1e2bfd13a2143955443c39d9fb3166c457457510cffd375e32b468a1d4fba608e0822425ebd61d9abd40a12a38fbcc037ea6d6707ad0abd4
7
- data.tar.gz: 8cfc7cc45cb7dbf508a97ad3c3c6ecff2d094530672a3fb38676426d25448a2d676a0e362d45507cbf89066caa06db971864cfbf26878f360446f5c117f54ca3
6
+ metadata.gz: 47f3c48b9157ca35688e8b45cee5e20c8c844c05b128e899f5cee1c15b9db60773a16f6b636fcf15c84bcbf27b78b4c66e6c4f5758397c693d277615f7b23abf
7
+ data.tar.gz: ce3221d0774d3d386c95af184798c9a98d67559f43481ea84b75a13119a6bb57fc35b5eafa9ca60a9a5d4e879805328b0dc5b47f162ff20d885d5e4aea95228c
@@ -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 cluster, using the [kubernetes-deploy](https://github.com/Shopify/kubernetes-deploy) gem and [mina-multistage](https://github.com/endoze/mina-multistage) plugin.
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 :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
+ 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
- Optional configuration (showing default values):
31
- ```ruby
32
- set :kube_config, "~/.kube/config"
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
- 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.
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
- 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.
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 `app_name-stage`.
76
+ Confirms and delete all resources on cluster under namespace.
@@ -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
- set :namespace, fetch(:app_name)
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
- set_local_config_context
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
- run_terminal_command("bash")
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
- run_terminal_command(fetch(:command), fetch(:env_hash))
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 cluster #{fetch(:kubernetes_cluster)}, are you sure?")
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)} --cluster=#{fetch(:kubernetes_cluster)}"
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
- 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)}"
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 run_terminal_command(command, env_hash = {})
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(:context)} --image #{fetch(:image_repo)}:#{fetch(:image_tag)} #{env} -- #{command}"
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
- 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)}"
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
@@ -1,5 +1,5 @@
1
1
  module Mina
2
2
  module Kubernetes
3
- VERSION = "1.0.1"
3
+ VERSION = "2.4.1"
4
4
  end
5
- end
5
+ end
@@ -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', '~> 10.0'
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 'kubernetes-deploy'
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: 1.0.1
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: 2019-05-20 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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: kubernetes-deploy
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