kubernetes_helper 1.17.0 → 1.19.1

Sign up to get free protection for your applications and to get access to all the features.
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