kubernetes_helper 1.15.2 → 1.18.0

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: 6b09fe0251ca84cfc1251acbf3f4079d02b5830abe77d3dc34c49b71ae2813ef
4
- data.tar.gz: fff66310d7051331a334eb1e3a250c92413348f17818dda5426fcaca0581a3b1
3
+ metadata.gz: 2dbeb51cb4e066084e681ea3a15c69b56780641bfbf38efa9dc8595b785de68c
4
+ data.tar.gz: 11c03302e5c59638b3fb0fa64602be15cfc24ddd41e7818c65afc5ac4df2cf2b
5
5
  SHA512:
6
- metadata.gz: ae4c26493643bc9fd8897ef362a476457e801868d8c3b12202889a1e7276fc8148b6bc247caec5a891985a81855296d142253b46517c7edd0f0e823fc4b2f77e
7
- data.tar.gz: ee94f2b9c13ecae82253900502e3c00c20f0cc72fbf2e9046a31bbc2a56391f4098819b7725f404f220a8a38898398658f0dfc1d2524093350dd47c02ea81435
6
+ metadata.gz: addb118b0d1d53ccc36843b1ca108d449aba773382ea54dbff665131a8282d9173d57b81a4b95d87a5ffa27f8dbce039fac989a36afd1d579aa48260f823515e
7
+ data.tar.gz: 17b845c6b15502d98294a82b33d08ddf6109aa2b0e49685ac1f299722980ae17f1d8fb07dc2f4242e093703a0448f20f4556fc2016bc8afdabf3b5088c7eba7d
data/README.md CHANGED
@@ -22,7 +22,7 @@ Configuration and customization can be done for multiple environments and at any
22
22
  Note: The local template will be used instead of the default one.
23
23
 
24
24
  3. Install/setup the application on kubernetes
25
- Open [.kubernetes/README.md](lib/templates/README.md) to see the instructions (customize the file according to your project and keep it updated)
25
+ Open [.kubernetes/README.md](lib/templates/README.md) to see the instructions (customize the file according to your project and keep it updated in your repository)
26
26
 
27
27
 
28
28
  ## Settings API
@@ -49,20 +49,25 @@ 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
- - `deployment.job_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
- - `deployment.job_command` (String, optional): Bash command to be used for job container. Sample: `bundle exec sidekiq`
54
- - `deployment.job_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
- - `deployment.job_services` (Array, Optional, only `job_sidekiq_alive_gem` or `job_services` is allowed): List of linux service names that are required for a healthy job container. Sample: `['sidekiq', 'cron']`
56
- - `deployment.job_resources` (Hash, optional): Configure depending on the job app requirements. Sample: `{ cpu: { max: '1', min: '500m' }, mem: { max: '1Gi', min: '500Mi' } }`
52
+ - `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
+ - `deployment.job_apps[].command` (String, optional): Bash command to be used for job container. Sample: `bundle exec sidekiq`
54
+ - `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
+ - `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
+ - `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
57
 
58
58
  ### Applications secrets.yml (Optional)
59
59
  - `secrets.name` (String): K8s secrets name where env vars will be saved and fetched from. Sample: `my-app-secrets`
60
-
60
+ - `secrets.import_all_secrets` (Boolean, default false):
61
+ - `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)
62
+ - `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)
63
+
61
64
  ### Application service.yml (Optional)
62
65
  - `service.name`: K8s service name. Sample: `my-app-service`
63
66
  - `service.port_name` (String, default `http-port`): Http port name to connect between k8s ingress and service. Sample: `http-port`. Note: max 15 characters
64
67
  - `service.backend_port_name` (String, default `b-port`): Web backend port name to be connected between k8s service and web deployments. Sample: `b-port`. Note: max 15 characters
65
68
  - `service.type`: K8s service type. By default `NodePort`
69
+ - `service.do_certificate_id`: Digital Ocean certificate ID to be used for the loadbalancer to auto redirect http to https.
70
+ Note: This value can be fetched via `doctl compute certificate list`. If there are no certificates available, you can generate a new one using digital ocean dashboard -> networking -> certificates.
66
71
 
67
72
  ### Application ingress.yml (Optional)
68
73
  - `ingress.name`: Name of k8s ingress for the app: Sample: `my-app-ingress`
@@ -71,7 +76,7 @@ Configuration and customization can be done for multiple environments and at any
71
76
  - `ingress.certificate_domain` (Optional): Domain name for the certificate. Sample: `myapp.com`. Note: does not support for willcard domains
72
77
  To register multiple domains (Certificate names will be auto-generated like `mysite-com-lets-encrypt`): `certificate_domain: ['mysite.com', 'mysite.de', 'mysite.uk']`
73
78
 
74
- - `cloud.name` (String, optional): Cloud service name. Default `gcloud`.
79
+ - `cloud.name` (String, optional): Cloud service name: `gcloud | digital_ocean`. Default `gcloud`.
75
80
 
76
81
  ### Application CD (continuous deployment)
77
82
  - `continuous_deployment.image_name` (String): Partial docker image url. Sample: `gcr.io/my-account/my_app_name`
@@ -86,7 +91,7 @@ Configuration and customization can be done for multiple environments and at any
86
91
  - `continuous_deployment.update_deployment` (Boolean, default: false): If true permits to re-generate and update the k8s deployment(s) before applying the new version (new docker image)
87
92
 
88
93
  ### Gem templating partials
89
- - `_container_extra_settings.yml` Partial template to add custom container settings. Receives `pod` as local variable (`web` | `job` | `cloudsql` | `logs`). Sample:
94
+ - `_container_extra_settings.yml` Partial template to add custom container settings. Receives `pod` as local variable (`web` | `job` | `cloudsql` | `logs`) and `pod_name`. Sample:
90
95
  ```yaml
91
96
  <% if locals[:pod] == 'job' %>
92
97
  resources:
@@ -98,7 +103,7 @@ Configuration and customization can be done for multiple environments and at any
98
103
  memory: 1Gi
99
104
  <% end %>
100
105
  ```
101
- - `_custom_containers.yml` Partial template to add extra containers (Receives `pod` as local variable: `web` | `job`). Sample:
106
+ - `_custom_containers.yml` Partial template to add extra containers (Receives `pod` as local variable: `web` | `job`) and `pod_name`. Sample:
102
107
  ```yaml
103
108
  <% if locals[:pod] == 'job' %>
104
109
  - name: scraper
@@ -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 } }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KubernetesHelper
4
- VERSION = '1.15.2'
4
+ VERSION = '1.18.0'
5
5
  end
@@ -25,7 +25,8 @@ module KubernetesHelper
25
25
  deployment: {
26
26
  log_container: true,
27
27
  log_folder: '/app/log',
28
- external_secrets: {}
28
+ external_secrets: {},
29
+ job_apps: settings[:job_apps] || job_apps_from_old_settings(settings)
29
30
  },
30
31
  service: {
31
32
  port_name: 'http-port',
@@ -75,4 +76,18 @@ module KubernetesHelper
75
76
  FileUtils.cp(templates_path(name), path) unless File.exist?(path)
76
77
  end
77
78
  end
79
+
80
+ def self.job_apps_from_old_settings(settings)
81
+ return [] unless settings[:deployment][:job_name]
82
+
83
+ [
84
+ {
85
+ name: settings[:deployment][:job_name],
86
+ command: settings[:deployment][:job_command],
87
+ services: settings[:deployment][:job_services],
88
+ resources: settings[:deployment][:job_resources],
89
+ sidekiq_alive_gem: settings[:deployment][:job_sidekiq_alive_gem]
90
+ }
91
+ ]
92
+ end
78
93
  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
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
@@ -12,8 +12,8 @@ documents:
12
12
  type: RollingUpdate
13
13
  rollingUpdate:
14
14
  maxSurge: 1
15
- maxUnavailable: 1
16
- minReadySeconds: 5
15
+ maxUnavailable: 0
16
+ minReadySeconds: 10
17
17
  template:
18
18
  metadata:
19
19
  labels:
@@ -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'%>'
@@ -98,18 +106,19 @@ documents:
98
106
  volumes:
99
107
  <%= include_template "_volumes.yml", { pod: 'web' } %>
100
108
 
101
-
102
- <% if deployment.job_name %>
109
+ <% deployment.job_apps.each do |job_app| %>
103
110
  - apiVersion: apps/v1
104
111
  kind: Deployment
105
112
  metadata:
106
- name: &job_app_name <%=deployment.job_name%>
113
+ name: &job_app_name <%= job_app[:name] %>
107
114
  spec:
108
115
  <<: *default_spec
109
116
  replicas: 1
110
117
  selector:
111
118
  matchLabels:
112
119
  name: *job_app_name
120
+ strategy:
121
+ type: Recreate
113
122
  template:
114
123
  metadata:
115
124
  labels:
@@ -119,18 +128,18 @@ documents:
119
128
  containers:
120
129
  - <<: *app_container
121
130
  name: *job_app_name
122
- <% if deployment.job_command %>
123
- command: [ "/bin/bash", "-c", "<%= deployment.job_command %>" ]
131
+ <% if job_app[:command] %>
132
+ command: [ "/bin/bash", "-c", "<%= job_app[:command] %>" ]
124
133
  <% end %>
125
- <% if deployment.job_resources %>
126
- <%= include_template "_resources.yml", deployment.job_resources %>
134
+ <% if job_app[:resources] %>
135
+ <%= include_template "_resources.yml", job_app[:resources] %>
127
136
  <% end %>
128
- <%= include_template "_container_extra_settings.yml", { pod: 'job' } %>
137
+ <%= include_template "_container_extra_settings.yml", { pod: 'job', pod_name: job_app[:name] } %>
129
138
 
130
- <% if deployment.job_sidekiq_alive_gem %>
131
- <%= include_template "_sidekiq_alive_gem.yml" %>
139
+ <% if job_app[:sidekiq_alive_gem] %>
140
+ <%= include_template "_sidekiq_alive_gem.yml" %>
132
141
  <% else %>
133
- <%= include_template "_job_liveness.yml" %>
142
+ <%= include_template "_job_liveness.yml" %>
134
143
  <% end %>
135
144
 
136
145
  <% if deployment.cloud_secret_name %>
@@ -141,10 +150,10 @@ documents:
141
150
  - <<: *logs_container
142
151
  <% end %>
143
152
 
144
- <%= include_template "_custom_containers.yml", { pod: 'job' } %>
153
+ <%= include_template "_custom_containers.yml", { pod: 'job', pod_name: job_app[:name] } %>
145
154
 
146
155
  volumes:
147
- <%= include_template "_volumes.yml", { pod: 'job' } %>
156
+ <%= include_template "_volumes.yml", { pod: 'job', pod_name: job_app[:name] } %>
148
157
  <% end %>
149
158
 
150
159
  <% 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"
@@ -15,6 +15,11 @@ apiVersion: v1
15
15
  metadata:
16
16
  name: '<%=service.name%>'
17
17
  annotations:
18
+ <% if cloud.name == 'digital_ocean' && service.do_certificate_id %>
19
+ service.beta.kubernetes.io/do-loadbalancer-protocol: "https"
20
+ service.beta.kubernetes.io/do-loadbalancer-certificate-id: <%= service.do_certificate_id %>
21
+ service.beta.kubernetes.io/do-loadbalancer-redirect-http-to-https: "true"
22
+ <% end %>
18
23
  <% if cloud.name == 'gcloud' %>
19
24
  beta.cloud.google.com/backend-config: '{"ports": {"80":"<%=service.name%>-bconfig"}}'
20
25
  <% end %>
@@ -27,3 +32,10 @@ spec:
27
32
  protocol: TCP
28
33
  name: '<%=service.port_name%>'
29
34
  targetPort: '<%=service.backend_port_name%>'
35
+
36
+ <% if cloud.name == 'digital_ocean' && service.do_certificate_id %>
37
+ - name: https
38
+ protocol: TCP
39
+ port: 443
40
+ targetPort: '<%=service.backend_port_name%>'
41
+ <% end %>
@@ -12,13 +12,18 @@ settings = {
12
12
  env_vars: {}, # Sample: { 'CUSTOM_VAR' => 'value' }
13
13
  # command: '', # custom container command (default empty to be managed by Dockerfile)
14
14
  # liveness_path: '/check_liveness', # nil if not exist
15
- # job_name: "#{app_name}-job", # enable if there is any background service
16
- # job_command: 'bundle exec sidekiq -C config/sidekiq.yml',
17
- # job_services: ['sidekiq', 'cron'] # list of linux services needed.
18
15
  # custom_volumes: { my_volume: { kind: 'hostPath', mount_path: '/', settings: { path: '..', type: 'Directory' } } }
16
+ job_apps: [
17
+ # {
18
+ # name: "#{app_name}-job", # enable if there is any background service
19
+ # command: 'bundle exec sidekiq -C config/sidekiq.yml',
20
+ # services: ['sidekiq', 'cron'] # list of linux services needed.
21
+ # }
22
+ ]
19
23
  },
20
24
  secrets: {
21
- name: "#{app_name}-secrets"
25
+ name: "#{app_name}-secrets",
26
+ import_all_secrets: true
22
27
  },
23
28
  service: {
24
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.15.2
4
+ version: 1.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - owen2345
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-21 00:00:00.000000000 Z
11
+ date: 2022-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erb