kubernetes_helper 1.17.0 → 1.19.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: 304a3005e0ef0280b53a2d108a0880a5406354a135027fb57cefff5e0ed5c437
4
- data.tar.gz: dfb38b6b47866ca50ba1c88d11dcad20101827f93a8f617dca95b3b3e225b31d
3
+ metadata.gz: e72fcd92010ce2e1144a926d617c13985b39941ff58e177f24eb8b68828bd572
4
+ data.tar.gz: f0798e685be4fde2efefd86e3869e05449c871a766686537db3085f7d6cb40d9
5
5
  SHA512:
6
- metadata.gz: d02d6bfefa1404a9a906c964c0ebb2e3979835fbcf539aeb99179cf850e08d87d1aa1c75f878ffb051fa0769a5ea19cf4ff73707bffc8aa5031eed59ee1081fa
7
- data.tar.gz: 3b40bf03b9498aed70c286170536764bd4ebe3ee8840b197584e831cbd4e5965e27671802dc30a4481de99093e18e9d9f8066728d4e95dbbed58c61032aa61b5
6
+ metadata.gz: fe823997d5ea50090e1389b1224cd78d9819f2c3f9c64e34451d1902aa1985b0a563f6768be1c873fcc63cc89ef06ea7494f756e2042984eb8d431f9fced8f16
7
+ data.tar.gz: ed8f9612237443578f3c6f862107e1e23639458290e2389409014f001734e6e71198c5b0abde07990d53ed6c4ee408ba3ea9abf4b409669103080cddded2eda1
data/README.md CHANGED
@@ -49,15 +49,26 @@ Configuration and customization can be done for multiple environments and at any
49
49
  - `deployment.logs_resources` (Hash, optional): Configure depending on the app requirements. Default: `{ cpu: { max: '200m', min: '50m' }, mem: { max: '200Mi', min: '50Mi' } }`
50
50
 
51
51
  ### Application deployment.yml for jobs or services without internet interaction (Optional)
52
+ Ideal to run sidekiq or similar jobs without internet connection. (TODO)
52
53
  - `deployment.job_apps[].name` (String, optional): Job deployment name (Note: Underscores are not accepted). Sample: `my-app-job`. Note: This deployment is created only if this value is present
53
54
  - `deployment.job_apps[].command` (String, optional): Bash command to be used for job container. Sample: `bundle exec sidekiq`
54
55
  - `deployment.job_apps[].sidekiq_alive_gem` (Boolean, default false): If true will add liveness checker settings using `sidekiq_alive_gem` (`sidekiq_alive` gem needs to be present in your Gemfile)
55
56
  - `deployment.job_apps[].services` (Array, Optional): List of linux service names that are required for a healthy job container. Sample: `['sidekiq', 'cron']`. Note: This will be ignored if `sidekiq_alive_gem` was defined.
56
57
  - `deployment.job_apps[].resources` (Hash, optional): Configure depending on the job app requirements. Sample: `{ cpu: { max: '1', min: '500m' }, mem: { max: '1Gi', min: '500Mi' } }`
57
58
 
59
+ ### Required settings for Cronjob apps (Note: Cronjobs do not support `sidekiq_alive_gem` and `services`)
60
+ Ideal to asasas (TODO)
61
+ - `deployment.job_apps[].schedule` (String): Cron schedule. Sample: `*/5 * * * *`
62
+ - `deployment.job_apps[].kind` (String, default `Deployment`): Kind of job application [`Deployment` or `CronJob`]
63
+ - `deployment.job_apps[].concurrency_policy` (String, default `Forbid`): [Documentation](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#concurrency-policy)
64
+ - `deployment.job_apps[].suspend` (String, default `false`): If `true` then marks as finished the job application (stops creating new pods).
65
+
58
66
  ### Applications secrets.yml (Optional)
59
67
  - `secrets.name` (String): K8s secrets name where env vars will be saved and fetched from. Sample: `my-app-secrets`
60
-
68
+ - `secrets.import_all_secrets` (Boolean, default false):
69
+ - `true`: Allows k8s to auto import all secrets from `secrets.yml` as env values for the apps (No longer needed to update `deployment.yml` everytime there is a new env var)
70
+ - `false`: Permits to the gem to auto include each secret from `secrets.yml -> data` as env value for the apps (base64 encoded values. Requires to update `deployment.yml` everytime there is a new env var)
71
+
61
72
  ### Application service.yml (Optional)
62
73
  - `service.name`: K8s service name. Sample: `my-app-service`
63
74
  - `service.port_name` (String, default `http-port`): Http port name to connect between k8s ingress and service. Sample: `http-port`. Note: max 15 characters
@@ -67,7 +67,7 @@ module KubernetesHelper
67
67
  def import_secrets(path, secrets_name)
68
68
  path = KubernetesHelper.settings_path(path)
69
69
  data = YAML.load(File.read(path)) # rubocop:disable Security/YAMLLoad
70
- data['data'].keys.map do |secret|
70
+ (data['data'] || {}).keys.map do |secret|
71
71
  {
72
72
  'name' => secret.upcase,
73
73
  'valueFrom' => { 'secretKeyRef' => { 'name' => secrets_name, 'key' => secret } }
@@ -78,6 +78,7 @@ module KubernetesHelper
78
78
  def render_template(template_name, locals = {})
79
79
  path = KubernetesHelper.settings_path(template_name, use_template: true)
80
80
  text = "\n#{File.read(path)}"
81
+ text = text.gsub("\n", "\n#{' ' * locals[:tab]}") if locals[:tab]
81
82
  replace_config_variables(text, locals)
82
83
  end
83
84
 
@@ -94,12 +95,13 @@ module KubernetesHelper
94
95
 
95
96
  # parse secrets auto importer
96
97
  def parse_import_secrets(document) # rubocop:disable Metrics/AbcSize
97
- containers = document.dig('spec', 'template', 'spec', 'containers') || []
98
+ cronjob_containers = document.dig('spec', 'jobTemplate', 'spec', 'template', 'spec', 'containers')
99
+ containers = document.dig('spec', 'template', 'spec', 'containers') || cronjob_containers || []
98
100
  containers.each do |container|
99
101
  container['env'] = (container['env'] || [])
100
- container['env'] = container['env'] + static_env_vars if container.delete('static_env')
102
+ container['env'] = (container['env'] + static_env_vars).uniq if container.delete('static_env')
101
103
  if container['import_secrets']
102
- container['env'] = container['env'] + import_secrets(*container['import_secrets'])
104
+ container['env'] = (container['env'] + import_secrets(*container['import_secrets'])).uniq
103
105
  container.delete('import_secrets')
104
106
  end
105
107
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KubernetesHelper
4
- VERSION = '1.17.0'
4
+ VERSION = '1.19.1'
5
5
  end
@@ -25,9 +25,8 @@
25
25
  DEPLOY_ENV=beta kubernetes_helper run_command "kubectl create secret generic <%=deployment.cloud_secret_name%> --from-file=credentials.json=<path-to-downloaded/credentials.json>"
26
26
  ```
27
27
 
28
- - Register manually env vars (values must be encrypted using base64)
28
+ - Register manually env vars
29
29
  Open and register secret values in `.kubernetes/secrets.yml`
30
- Note: Enter base64 encoded values
31
30
  ```bash
32
31
  DEPLOY_ENV=beta kubernetes_helper run_yml 'secrets.yml' 'kubectl create'
33
32
  # kubectl get secrets # to list all secrets registered
@@ -0,0 +1,41 @@
1
+ - apiVersion: batch/v1
2
+ kind: CronJob
3
+ metadata:
4
+ name: &cronjob_name <%= locals[:job_app][:name] %>
5
+ spec:
6
+ schedule: "<%= locals[:job_app][:schedule] %>"
7
+ concurrencyPolicy: "<%= locals[:job_app][:concurrency_policy] || 'Forbid' %>"
8
+ suspend: <%= locals[:job_app][:suspend] || false %>
9
+ # startingDeadlineSeconds: 200
10
+ jobTemplate:
11
+ spec:
12
+ template:
13
+ spec:
14
+ <<: *template_spec
15
+ restartPolicy: OnFailure
16
+ containers:
17
+ - <<: *app_container
18
+ name: *cronjob_name
19
+ <% if locals[:job_app][:command] %>
20
+ command: [ "/bin/bash", "-c", "<%= locals[:job_app][:command] %>" ]
21
+ <% end %>
22
+ <% if locals[:job_app][:resources] %>
23
+ <%= include_template "_resources.yml", locals[:job_app][:resources].merge(tab: 2) %>
24
+ <% end %>
25
+ ports: [ ]
26
+ livenessProbe: null
27
+ readinessProbe: null
28
+ <%= include_template "_container_extra_settings.yml", { pod: 'job', pod_name: locals[:job_app][:name], tab: 2 } %>
29
+
30
+ <% if deployment.cloud_secret_name %>
31
+ - *cloudsql_container
32
+ <% end %>
33
+
34
+ <% if deployment.log_container %>
35
+ - <<: *logs_container
36
+ <% end %>
37
+
38
+ <%= include_template "_custom_containers.yml", { pod: 'job', pod_name: locals[:job_app][:name], tab: 2 } %>
39
+
40
+ volumes:
41
+ <%= include_template "_volumes.yml", { pod: 'job', pod_name: locals[:job_app][:name], tab: 2 } %>
@@ -1,12 +1,15 @@
1
1
  ports: [ ]
2
- <% if (deployment.job_services || []).any? %>
2
+ <% if (locals[:services] || []).any? %>
3
3
  livenessProbe: &liveness_probe
4
4
  exec:
5
5
  command: [ /bin/sh, -c,
6
- 'if [ $(ps -ef | grep "<%= deployment.job_services.join("\\|") %>" | grep -v "grep" | wc -l) -lt <%= deployment.job_services.count %> ]; then
6
+ 'if [ $(ps -ef | grep "<%= locals[:services].join("\\|") %>" | grep -v "grep" | wc -l) -lt <%= locals[:services].count %> ]; then
7
7
  echo "Some required services are not running"; exit 1;
8
8
  fi' ]
9
9
  initialDelaySeconds: 120
10
10
  periodSeconds: 30
11
11
  readinessProbe: *liveness_probe
12
+ <% else %>
13
+ livenessProbe: null
14
+ readinessProbe: null
12
15
  <% end %>
@@ -0,0 +1,47 @@
1
+ - apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: &job_app_name <%= locals[:job_app][:name] %>
5
+ spec:
6
+ replicas: 1
7
+ selector:
8
+ matchLabels:
9
+ name: *job_app_name
10
+ strategy:
11
+ type: Recreate
12
+ minReadySeconds: 10
13
+ template:
14
+ metadata:
15
+ labels:
16
+ name: *job_app_name
17
+ spec:
18
+ <<: *template_spec
19
+ containers:
20
+ - <<: *app_container
21
+ name: *job_app_name
22
+ <% if locals[:job_app][:command] %>
23
+ command: [ "/bin/bash", "-c", "<%= locals[:job_app][:command] %>" ]
24
+ <% end %>
25
+ <% if locals[:job_app][:resources] %>
26
+ <%= include_template "_resources.yml", locals[:job_app][:resources] %>
27
+ <% end %>
28
+ <%= include_template "_container_extra_settings.yml", { pod: 'job', pod_name: locals[:job_app][:name] } %>
29
+
30
+ <% if locals[:job_app][:sidekiq_alive_gem] %>
31
+ <%= include_template "_sidekiq_alive_gem.yml" %>
32
+ <% else %>
33
+ <%= include_template "_job_liveness.yml", { services: locals[:job_app][:services] } %>
34
+ <% end %>
35
+
36
+ <% if deployment.cloud_secret_name %>
37
+ - *cloudsql_container
38
+ <% end %>
39
+
40
+ <% if deployment.log_container %>
41
+ - <<: *logs_container
42
+ <% end %>
43
+
44
+ <%= include_template "_custom_containers.yml", { pod: 'job', pod_name: locals[:job_app][:name] } %>
45
+
46
+ volumes:
47
+ <%= include_template "_volumes.yml", { pod: 'job', pod_name: locals[:job_app][:name] } %>
@@ -18,4 +18,4 @@
18
18
  <% end %>
19
19
  <% end %>
20
20
 
21
- <%= include_template "_custom_volumes.yml", { pod: locals[:pod] } %>
21
+ <%= include_template "_custom_volumes.yml", { pod: locals[:pod], tab: locals[:tab] } %>
data/lib/templates/cd.sh CHANGED
@@ -5,7 +5,7 @@ set -e
5
5
  SCRIPT_DIR=`dirname "$(realpath -s "$0")"` # app_dir/.kubernetes/
6
6
  cd "$SCRIPT_DIR/../" # project directory
7
7
 
8
- DEPLOYMENTS="<%=[deployment.job_name, deployment.name].join(',')%>"
8
+ DEPLOYMENTS="<%=(deployment.job_apps.map { |a| a[:name] } + [deployment.name]).join(',')%>"
9
9
  IMAGE_NAME="<%=continuous_deployment.image_name%>"
10
10
  CLUSTER_NAME="<%=continuous_deployment.cluster_name%>"
11
11
  PROJECT_NAME="<%=continuous_deployment.project_name%>"
@@ -21,7 +21,7 @@ LATEST_NAME="${IMAGE_NAME}:<%= continuous_deployment.image_tag || 'latest' %>"
21
21
 
22
22
  ## Update new secrets defined in secrets.yml as ENV vars for deployments
23
23
  <% if continuous_deployment.update_deployment %>
24
- kubernetes_helper run_yml 'deployment.yml' 'kubectl apply'
24
+ DEPLOY_IMAGE_TAG=$CI_COMMIT_SHA kubernetes_helper run_yml 'deployment.yml' 'kubectl apply'
25
25
  <% end %>
26
26
 
27
27
  ## Apply deployments
@@ -3,7 +3,7 @@ documents:
3
3
  kind: Deployment
4
4
  metadata:
5
5
  name: &app_name <%=deployment.name%>
6
- spec: &default_spec
6
+ spec:
7
7
  replicas: <%=deployment.replicas%>
8
8
  selector:
9
9
  matchLabels:
@@ -12,7 +12,7 @@ documents:
12
12
  type: RollingUpdate
13
13
  rollingUpdate:
14
14
  maxSurge: 1
15
- maxUnavailable: 1
15
+ maxUnavailable: 0
16
16
  minReadySeconds: 10
17
17
  template:
18
18
  metadata:
@@ -21,13 +21,21 @@ documents:
21
21
  spec: &template_spec
22
22
  containers:
23
23
  - &app_container
24
- image: '<%= continuous_deployment.image_name %>:<%= continuous_deployment.image_tag || "latest" %>'
24
+ image: '<%= continuous_deployment.image_name %>:<%= ENV['DEPLOY_IMAGE_TAG'] || continuous_deployment.image_tag || "latest" %>'
25
25
  <% if deployment.command %>
26
26
  command: ["/bin/bash", "-c", "<%= deployment.command %>"]
27
27
  <% end %>
28
28
  name: *app_name
29
+
29
30
  static_env: true
31
+ <% if secrets.import_all_secrets %>
32
+ envFrom:
33
+ - secretRef:
34
+ name: <%= secrets.name %>
35
+ <% else %>
30
36
  import_secrets: ['secrets.yml', '<%=secrets.name%>']
37
+ <% end %>
38
+
31
39
  ports:
32
40
  - containerPort: &port <%= deployment.app_port || 3000 %>
33
41
  name: '<%=service.backend_port_name || 'b-port'%>'
@@ -99,53 +107,8 @@ documents:
99
107
  <%= include_template "_volumes.yml", { pod: 'web' } %>
100
108
 
101
109
  <% deployment.job_apps.each do |job_app| %>
102
- - apiVersion: apps/v1
103
- kind: Deployment
104
- metadata:
105
- name: &job_app_name <%= job_app[:name] %>
106
- spec:
107
- <<: *default_spec
108
- replicas: 1
109
- selector:
110
- matchLabels:
111
- name: *job_app_name
112
- strategy:
113
- type: Recreate
114
- template:
115
- metadata:
116
- labels:
117
- name: *job_app_name
118
- spec:
119
- <<: *template_spec
120
- containers:
121
- - <<: *app_container
122
- name: *job_app_name
123
- <% if job_app[:command] %>
124
- command: [ "/bin/bash", "-c", "<%= job_app[:command] %>" ]
125
- <% end %>
126
- <% if job_app[:resources] %>
127
- <%= include_template "_resources.yml", job_app[:resources] %>
128
- <% end %>
129
- <%= include_template "_container_extra_settings.yml", { pod: 'job', pod_name: job_app[:name] } %>
130
-
131
- <% if job_app[:sidekiq_alive_gem] %>
132
- <%= include_template "_sidekiq_alive_gem.yml" %>
133
- <% else %>
134
- <%= include_template "_job_liveness.yml" %>
135
- <% end %>
136
-
137
- <% if deployment.cloud_secret_name %>
138
- - *cloudsql_container
139
- <% end %>
140
-
141
- <% if deployment.log_container %>
142
- - <<: *logs_container
143
- <% end %>
144
-
145
- <%= include_template "_custom_containers.yml", { pod: 'job', pod_name: job_app[:name] } %>
146
-
147
- volumes:
148
- <%= include_template "_volumes.yml", { pod: 'job', pod_name: job_app[:name] } %>
110
+ <%= include_template '_jobs_pod.yml', job_app: job_app if job_app[:kind] != 'CronJob' %>
111
+ <%= include_template '_cronjobs_pod.yml', job_app: job_app if job_app[:kind] == 'CronJob' %>
149
112
  <% end %>
150
113
 
151
114
  <% if deployment.replicas_range %>
@@ -1,4 +1,3 @@
1
- # Every Value has to be base64 encoded
2
1
  # IMPORTANT: For security reason, never ever commit secret values, only keys
3
2
 
4
3
  apiVersion: v1
@@ -6,6 +5,6 @@ kind: Secret
6
5
  metadata:
7
6
  name: '<%=secrets.name%>'
8
7
  type: Opaque
9
- data:
10
- my_key1: "based_64_value_encoded"
11
- my_key2: "based_64_value_encoded"
8
+ stringData:
9
+ MY_KEY1: "my value1"
10
+ MY_KEY2: "my value2"
@@ -22,7 +22,8 @@ settings = {
22
22
  ]
23
23
  },
24
24
  secrets: {
25
- name: "#{app_name}-secrets"
25
+ name: "#{app_name}-secrets",
26
+ import_all_secrets: true
26
27
  },
27
28
  service: {
28
29
  name: app_name,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kubernetes_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.17.0
4
+ version: 1.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - owen2345
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-04 00:00:00.000000000 Z
11
+ date: 2022-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erb
@@ -44,9 +44,11 @@ files:
44
44
  - lib/templates/_cd_digital.sh
45
45
  - lib/templates/_cd_google.sh
46
46
  - lib/templates/_container_extra_settings.yml
47
+ - lib/templates/_cronjobs_pod.yml
47
48
  - lib/templates/_custom_containers.yml
48
49
  - lib/templates/_custom_volumes.yml
49
50
  - lib/templates/_job_liveness.yml
51
+ - lib/templates/_jobs_pod.yml
50
52
  - lib/templates/_replicas.yml
51
53
  - lib/templates/_resources.yml
52
54
  - lib/templates/_sidekiq_alive_gem.yml