blob: 918cab218c3cd88d69f465744d25b579ec72cdba [file] [log] [blame]
Zack Williams0149cd22018-05-17 16:19:48 -07001#!/usr/bin/env bash
2
3# Copyright 2018-present Open Networking Foundation
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# service_scaffold.sh
18# creates directories and scaffolding for a service
19
20set -e -o pipefail
21
22LICENSE_TEXT=$(cat <<EOF
23# Copyright $(date +%Y)-present Open Networking Foundation
24#
25# Licensed under the Apache License, Version 2.0 (the "License");
26# you may not use this file except in compliance with the License.
27# You may obtain a copy of the License at
28#
29# http://www.apache.org/licenses/LICENSE-2.0
30#
31# Unless required by applicable law or agreed to in writing, software
32# distributed under the License is distributed on an "AS IS" BASIS,
33# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34# See the License for the specific language governing permissions and
35# limitations under the License.
36EOF
37)
38
39TPL_LICENSE_TEXT=$(cat <<EOF
40{{/*
41Copyright $(date +%Y)-present Open Networking Foundation
42
43Licensed under the Apache License, Version 2.0 (the "License");
44you may not use this file except in compliance with the License.
45You may obtain a copy of the License at
46
47http://www.apache.org/licenses/LICENSE-2.0
48
49Unless required by applicable law or agreed to in writing, software
50distributed under the License is distributed on an "AS IS" BASIS,
51WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52See the License for the specific language governing permissions and
53limitations under the License.
54*/}}
55EOF
56)
57
58if [ -z "${SERVICE_NAME}" ];
59then
60 SERVICE_NAME=$(basename "${PWD}")
61 echo "SERVICE_NAME undefined, using parent directory name: ${SERVICE_NAME}"
62fi
63
64if [ -z "${SERVICE_VERSION}" ];
65then
66 SERVICE_VERSION="0.0.1"
67 echo "SERVICE_VERSION undefined, using default: ${SERVICE_VERSION}"
68fi
69
70echo "Creating service named: ${SERVICE_NAME}, version: ${SERVICE_VERSION}"
71
72echo "${SERVICE_VERSION}" > VERSION
73
74# create uppercase version of SERVICE_NAME in a naive fashion
75UC_SERVICE_NAME=$(echo "${SERVICE_NAME}" | cut -c1 | tr '[:lower:]' '[:upper:]')$(echo "${SERVICE_NAME}" | cut -c2-)
76
77echo "Uppercase service name: ${UC_SERVICE_NAME}"
78
79echo "Creating README.md"
80echo "# ${UC_SERVICE_NAME} Service" > README.md
81
82echo "Creating directories"
83mkdir -p xos/synchronizer/model_policies/
84mkdir -p xos/synchronizer/models/
85mkdir -p xos/synchronizer/pull_steps/
86mkdir -p xos/synchronizer/steps/
87mkdir -p xos/synchronizer/tests/
88mkdir -p "helm-charts/${SERVICE_NAME}/templates"
89
90echo "Creating empty model-deps"
91echo "{}" > xos/synchronizer/model-deps
92
93echo "Creating xproto scaffold"
94cat << EOF > "xos/synchronizer/models/${SERVICE_NAME}.xproto"
95option app_label = "${SERVICE_NAME}";
96option name = "${SERVICE_NAME}";
97
98message ${UC_SERVICE_NAME}Service (Service){
99 option verbose_name = "${UC_SERVICE_NAME} Service";
100}
101
102message ${UC_SERVICE_NAME}ServiceInstance (ServiceInstance){
103 option owner_class_name = "${UC_SERVICE_NAME}Service";
104 option verbose_name = "${UC_SERVICE_NAME} Service Instance";
105}
106EOF
107
108echo "Creating unittest.cfg"
109cat << EOF > "xos/unittest.cfg"
110[unittest]
111plugins=nose2.plugins.junitxml
112code-directories=synchronizer
113 model_policies
114 steps
115 pull_steps
116 event_steps
117EOF
118
119echo "Creating service config.yaml"
120cat << EOF > "xos/synchronizer/config.yaml"
121${LICENSE_TEXT}
122
123name: ${SERVICE_NAME}
124required_models:
125 - ${UC_SERVICE_NAME}Service
126 - ${UC_SERVICE_NAME}ServiceInstance
127dependency_graph: "/opt/xos/synchronizers/${SERVICE_NAME}/model-deps"
128model_policies_dir: "/opt/xos/synchronizers/${SERVICE_NAME}/model_policies"
129models_dir: "/opt/xos/synchronizers/${SERVICE_NAME}/models"
130pull_steps_dir: "/opt/xos/synchronizers/${SERVICE_NAME}/pull_steps"
131steps_dir: "/opt/xos/synchronizers/${SERVICE_NAME}/steps"
132sys_dir: "/opt/xos/synchronizers/${SERVICE_NAME}/sys"
133EOF
134
135echo "Creating test_config.yaml"
136cat << EOF > "xos/synchronizer/test_config.yaml"
137${LICENSE_TEXT}
138
139name: ${SERVICE_NAME}-testconfig
140accessor:
141 username: xosadmin@opencord.org
142 password: "sample"
143 kind: "testframework"
144logging:
145 version: 1
146 handlers:
147 console:
148 class: logging.StreamHandler
149 loggers:
150 'multistructlog':
151 handlers:
152 - console
153EOF
154
155echo "Creating synchronizer.py"
156cat << EOF > "xos/synchronizer/${SERVICE_NAME}-synchronizer.py"
157#!/usr/bin/env python
158
159${LICENSE_TEXT}
160
161"""
162${SERVICE_NAME}-synchronizer.py
163This is the main entrypoint for the synchronizer. It loads the config file, and
164then starts the synchronizer.
165"""
166
167import importlib
168import os
169import sys
170from xosconfig import Config
171
172config_file = os.path.abspath(os.path.dirname(
173 os.path.realpath(__file__)) + '/config.yaml')
174
175base_config_file = os.path.abspath(os.path.dirname(
176 os.path.realpath(__file__)) + '/config.yaml')
177mounted_config_file = os.path.abspath(os.path.dirname(
178 os.path.realpath(__file__)) + '/mounted_config.yaml')
179
180if os.path.isfile(mounted_config_file):
181 Config.init(base_config_file, 'synchronizer-config-schema.yaml',
182 mounted_config_file)
183else:
184 Config.init(base_config_file, 'synchronizer-config-schema.yaml')
185
186synchronizer_path = os.path.join(os.path.dirname(
187 os.path.realpath(__file__)), "../../synchronizers/new_base")
188
189sys.path.append(synchronizer_path)
190mod = importlib.import_module("xos-synchronizer")
191mod.main()
192EOF
193
194chmod +x "xos/synchronizer/${SERVICE_NAME}-synchronizer.py"
195
196echo "Creating synchronizer Dockerfile"
197cat << EOF > Dockerfile.synchronizer
198${LICENSE_TEXT}
199
200# xosproject/${SERVICE_NAME}
201
202FROM xosproject/xos-synchronizer-base:2.0.0
203
204COPY xos/synchronizer /opt/xos/synchronizers/${SERVICE_NAME}
205COPY VERSION /opt/xos/synchronizers/${SERVICE_NAME}/
206
207ENTRYPOINT []
208
209WORKDIR "/opt/xos/synchronizers/${SERVICE_NAME}"
210
211# Label image
212ARG org_label_schema_schema_version=1.0
213ARG org_label_schema_name=${SERVICE_NAME}
214ARG org_label_schema_version=unknown
215ARG org_label_schema_vcs_url=unknown
216ARG org_label_schema_vcs_ref=unknown
217ARG org_label_schema_build_date=unknown
218ARG org_opencord_vcs_commit_date=unknown
219ARG org_opencord_component_chameleon_version=unknown
220ARG org_opencord_component_chameleon_vcs_url=unknown
221ARG org_opencord_component_chameleon_vcs_ref=unknown
222ARG org_opencord_component_xos_version=unknown
223ARG org_opencord_component_xos_vcs_url=unknown
224ARG org_opencord_component_xos_vcs_ref=unknown
225
226LABEL org.label-schema.schema-version=\$org_label_schema_schema_version \\
227 org.label-schema.name=\$org_label_schema_name \\
228 org.label-schema.version=\$org_label_schema_version \\
229 org.label-schema.vcs-url=\$org_label_schema_vcs_url \\
230 org.label-schema.vcs-ref=\$org_label_schema_vcs_ref \\
231 org.label-schema.build-date=\$org_label_schema_build_date \\
232 org.opencord.vcs-commit-date=\$org_opencord_vcs_commit_date \\
233 org.opencord.component.chameleon.version=\$org_opencord_component_chameleon_version \\
234 org.opencord.component.chameleon.vcs-url=\$org_opencord_component_chameleon_vcs_url \\
235 org.opencord.component.chameleon.vcs-ref=\$org_opencord_component_chameleon_vcs_ref \\
236 org.opencord.component.xos.version=\$org_opencord_component_xos_version \\
237 org.opencord.component.xos.vcs-url=\$org_opencord_component_xos_vcs_url \\
238 org.opencord.component.xos.vcs-ref=\$org_opencord_component_xos_vcs_ref
239
240CMD ["/usr/bin/python", "/opt/xos/synchronizers/${SERVICE_NAME}/${SERVICE_NAME}-synchronizer.py"]
241EOF
242
243echo "Creating sync step"
244cat << EOF > "xos/synchronizer/steps/sync_${SERVICE_NAME}_serviceinstance.py"
245${LICENSE_TEXT}
246
247from synchronizers.new_base.syncstep import SyncStep
248from synchronizers.new_base.modelaccessor import ${UC_SERVICE_NAME}ServiceInstance
249
250from xosconfig import Config
251from multistructlog import create_logger
252
253log = create_logger(Config().get('logging'))
254
255
256class Sync${UC_SERVICE_NAME}ServiceInstance(SyncStep):
257 """
258 Sync${UC_SERVICE_NAME}ServiceInstance
259 Implements sync step for syncing ${UC_SERVICE_NAME} Services
260 """
261
262 provides = [${UC_SERVICE_NAME}ServiceInstance]
263 observes = [${UC_SERVICE_NAME}ServiceInstance]
264 requested_interval = 0
265
266 def sync_record(self, model):
267 log.info("Synchronizing ${UC_SERVICE_NAME}ServiceInstance",
268 object=str(model))
269 # TODO: Implement sync step
270
271 # Verify that the name is not empty, used in tests
272 if model.name != "":
273 model.save()
274 else:
275 raise Exception("Empty names aren't allowed")
276
277 def delete_record(self, model):
278 log.info("Deleting ${UC_SERVICE_NAME}ServiceInstance",
279 object=str(model))
280 # TODO: Implement delete step
281EOF
282
283echo "Creating test for synchronizer of service instance"
284cat << EOF > "xos/synchronizer/steps/test_sync_${SERVICE_NAME}_serviceinstance.py"
285${LICENSE_TEXT}
286
287import os
288import sys
289import unittest
290from mock import Mock
291
292# Hack to load synchronizer framework
293test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
294
295xos_dir = os.path.join(test_path, "../../..")
296
297if not os.path.exists(os.path.join(test_path, "new_base")):
298 xos_dir = os.path.join(test_path, "../../../../../../orchestration/xos/xos")
299 services_dir = os.path.join(xos_dir, "../../xos_services")
300
301sys.path.append(xos_dir)
302sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
303# END Hack to load synchronizer framework
304
305
306# generate model from xproto
307def get_models_fn(service_name, xproto_name):
308 name = os.path.join(service_name, "xos", xproto_name)
309 if os.path.exists(os.path.join(services_dir, name)):
310 return name
311 else:
312 name = os.path.join(service_name, "xos", "synchronizer", "models", xproto_name)
313 if os.path.exists(os.path.join(services_dir, name)):
314 return name
315 raise Exception("Unable to find service=%s xproto=%s" % (service_name, xproto_name))
316# END generate model from xproto
317
318
319class TestSync${UC_SERVICE_NAME}ServiceInstance(unittest.TestCase):
320
321 def setUp(self):
322
323 self.sys_path_save = sys.path
324 sys.path.append(xos_dir)
325 sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
326
327 # Setting up the config module
328 from xosconfig import Config
329 config = os.path.join(test_path, "../test_config.yaml")
330 Config.clear()
331 Config.init(config, "synchronizer-config-schema.yaml")
332 # END Setting up the config module
333
334 from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
335 build_mock_modelaccessor(xos_dir, services_dir, [
336 get_models_fn("${SERVICE_NAME}", "${SERVICE_NAME}.xproto"),
337 ])
338
339 from synchronizers.new_base.modelaccessor import model_accessor
340 from sync_${SERVICE_NAME}_serviceinstance import Sync${UC_SERVICE_NAME}ServiceInstance
341 # import all class names to globals
342 for (k, v) in model_accessor.all_model_classes.items():
343 globals()[k] = v
344
345 self.sync_step = Sync${UC_SERVICE_NAME}ServiceInstance
346
347 # create a mock instance instance
348 self.model = Mock()
349 self.model.name = "Example"
350
351 def tearDown(self):
352 self.model = None
353 sys.path = self.sys_path_save
354
355 # TODO - The following two tests are very simple, replace with more meaningful ones
356
357 def test_save(self):
358 # Tests that the model can be saved
359
360 self.model.name = "${SERVICE_NAME}_test"
361 self.sync_step().sync_record(self.model)
362 self.model.save.assert_called()
363
364 def test_sync_rejected(self):
365 # Tests that an empty name raises an exception
366
367 self.model.name = ""
368 with self.assertRaises(Exception):
369 self.sync_step().sync_record(self.model)
370
371
372if __name__ == '__main__':
373 unittest.main()
374EOF
375
376echo "Creating model policy for instance"
377cat << EOF > "xos/synchronizer/model_policies/model_policy_${SERVICE_NAME}_serviceinstance.py"
378${LICENSE_TEXT}
379
380from synchronizers.new_base.policy import Policy
381
382
383class ${UC_SERVICE_NAME}ServiceInstancePolicy(Policy):
384 """
385 ${UC_SERVICE_NAME}ServiceInstancePolicy
386 Implements model policy for ${UC_SERVICE_NAME}Instance
387 """
388
389 model_name = "${UC_SERVICE_NAME}ServiceInstance"
390
391 def handle_create(self, si):
392 self.logger.debug(
393 "MODEL_POLICY: enter handle_create for ${UC_SERVICE_NAME}ServiceInstance %s" %
394 si.id)
395 self.handle_update(si)
396 # TODO: Implement creation policy, if it differs from update policy
397
398 def handle_update(self, si):
399 self.logger.debug(
400 "MODEL_POLICY: enter handle_update for ${UC_SERVICE_NAME}ServiceInstance %s, valid=%s" %
401 (si.id, si.valid))
402
403 if (si.backend_code != 1):
404 raise Exception(
405 "MODEL_POLICY: ${UC_SERVICE_NAME}ServiceInstance %s has not been synced yet" %
406 si.id)
407
408 # TODO: Implement update policy
409
410 def handle_delete(self, si):
411 self.logger.debug(
412 "MODEL_POLICY: enter handle_delete for ${UC_SERVICE_NAME}ServiceInstance %s" %
413 si.id)
414 # TODO: Implement delete policy
415EOF
416
417echo "Creating test for model policy of service instance"
418cat << EOF > "xos/synchronizer/model_policies/test_model_policy_${SERVICE_NAME}_serviceinstance.py"
419${LICENSE_TEXT}
420
421import os
422import sys
423import unittest
424from mock import Mock
425
426# Hack to load synchronizer framework
427test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
428
429xos_dir = os.path.join(test_path, "../../..")
430
431if not os.path.exists(os.path.join(test_path, "new_base")):
432 xos_dir = os.path.join(test_path, "../../../../../../orchestration/xos/xos")
433 services_dir = os.path.join(xos_dir, "../../xos_services")
434
435sys.path.append(xos_dir)
436sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
437# END Hack to load synchronizer framework
438
439
440# generate model from xproto
441def get_models_fn(service_name, xproto_name):
442 name = os.path.join(service_name, "xos", xproto_name)
443 if os.path.exists(os.path.join(services_dir, name)):
444 return name
445 else:
446 name = os.path.join(service_name, "xos", "synchronizer", "models", xproto_name)
447 if os.path.exists(os.path.join(services_dir, name)):
448 return name
449 raise Exception("Unable to find service=%s xproto=%s" % (service_name, xproto_name))
450# END generate model from xproto
451
452
453class TestModelPolicy${UC_SERVICE_NAME}ServiceInstance(unittest.TestCase):
454
455 def setUp(self):
456
457 self.sys_path_save = sys.path
458 sys.path.append(xos_dir)
459 sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
460
461 # Setting up the config module
462 from xosconfig import Config
463 config = os.path.join(test_path, "../test_config.yaml")
464 Config.clear()
465 Config.init(config, "synchronizer-config-schema.yaml")
466 # END Setting up the config module
467
468 from synchronizers.new_base.mock_modelaccessor_build import build_mock_modelaccessor
469 build_mock_modelaccessor(xos_dir, services_dir, [
470 get_models_fn("${SERVICE_NAME}", "${SERVICE_NAME}.xproto"),
471 ])
472
473 from synchronizers.new_base.modelaccessor import model_accessor
474 from model_policy_${SERVICE_NAME}_serviceinstance import ${UC_SERVICE_NAME}ServiceInstancePolicy
475 # import all class names to globals
476 for (k, v) in model_accessor.all_model_classes.items():
477 globals()[k] = v
478
479 # Some of the functions we call have side-effects, reset the world.
480 model_accessor.reset_all_object_stores()
481
482 self.policy = ${UC_SERVICE_NAME}ServiceInstancePolicy()
483 self.si = Mock()
484
485 def tearDown(self):
486 sys.path = self.sys_path_save
487 self.si = None
488
489 def test_not_synced(self):
490 self.si.valid = "awaiting"
491 self.si.backend_code = 0
492
493 with self.assertRaises(Exception) as e:
494 self.policy.handle_update(self.si)
495
496 self.assertIn("has not been synced yet", e.exception.message)
497
498 def test_skip_update(self):
499 self.si.valid = "awaiting"
500 self.si.backend_code = 1
501
502 self.policy.handle_update(self.si)
503
504
505if __name__ == '__main__':
506 unittest.main()
507EOF
508
509
510echo "Creating helm chart for service"
511cat << EOF > "helm-charts/${SERVICE_NAME}/Chart.yaml"
512---
513${LICENSE_TEXT}
514
515name: ${SERVICE_NAME}
516version: ${SERVICE_VERSION}
517EOF
518
519cat << EOF > "helm-charts/${SERVICE_NAME}/values.yaml"
520---
521${LICENSE_TEXT}
522
523nameOverride: ""
524fullnameOverride: ""
525
526${SERVICE_NAME}_synchronizerImage: "xosproject/${SERVICE_NAME}-synchronizer:{{ .Chart.Version }}"
527
528imagePullPolicy: 'IfNotPresent'
529
530xosAdminUser: "admin@opencord.org"
531xosAdminPassword: "letmein"
532
533affinity: {}
534nodeSelector: {}
535replicaCount: 1
536resources: {}
537tolerations: []
538EOF
539
540cat << EOF > "helm-charts/${SERVICE_NAME}/templates/_helpers.tpl"
541{{/* vim: set filetype=mustache: */}}
542${TPL_LICENSE_TEXT}
543{{/*
544Expand the name of the chart.
545*/}}
546{{- define "${SERVICE_NAME}.name" -}}
547{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
548{{- end -}}
549
550{{/*
551Create a default fully qualified app name.
552We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
553If release name contains chart name it will be used as a full name.
554*/}}
555{{- define "${SERVICE_NAME}.fullname" -}}
556{{- if .Values.fullnameOverride -}}
557{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
558{{- else -}}
559{{- \$name := default .Chart.Name .Values.nameOverride -}}
560{{- if contains \$name .Release.Name -}}
561{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
562{{- else -}}
563{{- printf "%s-%s" .Release.Name \$name | trunc 63 | trimSuffix "-" -}}
564{{- end -}}
565{{- end -}}
566{{- end -}}
567
568{{/*
569Create chart name and version as used by the chart label.
570*/}}
571{{- define "${SERVICE_NAME}.chart" -}}
572{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
573{{- end -}}
574
575{{- define "${SERVICE_NAME}.serviceConfig" -}}
576name: ${SERVICE_NAME}
577accessor:
578 username: {{ .Values.xosAdminUser | quote }}
579 password: {{ .Values.xosAdminPassword | quote }}
580 endpoint: xos-core:50051
581required_models:
582 - ${UC_SERVICE_NAME}Service
583 - ${UC_SERVICE_NAME}ServiceInstance
584dependency_graph: "/opt/xos/synchronizers/${SERVICE_NAME}/model-deps"
585model_policies_dir: "/opt/xos/synchronizers/${SERVICE_NAME}/model_policies"
586models_dir: "/opt/xos/synchronizers/${SERVICE_NAME}/models"
587steps_dir: "/opt/xos/synchronizers/${SERVICE_NAME}/steps"
588logging:
589 version: 1
590 handlers:
591 console:
592 class: logging.StreamHandler
593 file:
594 class: logging.handlers.RotatingFileHandler
595 filename: /var/log/xos.log
596 maxBytes: 10485760
597 backupCount: 5
598 loggers:
599 'multistructlog':
600 handlers:
601 - console
602 - file
603 level: DEBUG
604{{- end -}}
605EOF
606
607cat << EOF > "helm-charts/${SERVICE_NAME}/templates/_tosca.tpl"
608{{/* vim: set filetype=mustache: */}}
609${TPL_LICENSE_TEXT}
610{{- define "${SERVICE_NAME}.serviceTosca" -}}
611tosca_definitions_version: tosca_simple_yaml_1_0
612description: Set up ${SERVICE_NAME} service
613imports:
614 - custom_types/${SERVICE_NAME}service.yaml
615
616topology_template:
617 node_templates:
618 service#${SERVICE_NAME}:
619 type: tosca.nodes.${UC_SERVICE_NAME}Service
620 properties:
621 name: ${SERVICE_NAME}
622 kind: ${UC_SERVICE_NAME}
623{{- end -}}
624EOF
625
626cat << EOF > "helm-charts/${SERVICE_NAME}/templates/configmap.yaml"
627---
628${LICENSE_TEXT}
629
630apiVersion: v1
631kind: ConfigMap
632metadata:
633 name: ${SERVICE_NAME}
634data:
635 serviceConfig: |
636{{ include "${SERVICE_NAME}.serviceConfig" . | indent 4 }}
637EOF
638
639cat << EOF > "helm-charts/${SERVICE_NAME}/templates/deployment.yaml"
640---
641${LICENSE_TEXT}
642
643apiVersion: apps/v1beta2
644kind: Deployment
645metadata:
646 name: {{ template "${SERVICE_NAME}.fullname" . }}
647 labels:
648 app: {{ template "${SERVICE_NAME}.name" . }}
649 chart: {{ template "${SERVICE_NAME}.chart" . }}
650 release: {{ .Release.Name }}
651 heritage: {{ .Release.Service }}
652spec:
653 replicas: {{ .Values.replicaCount }}
654 selector:
655 matchLabels:
656 app: {{ template "${SERVICE_NAME}.name" . }}
657 release: {{ .Release.Name }}
658 template:
659 metadata:
660 labels:
661 app: {{ template "${SERVICE_NAME}.name" . }}
662 release: {{ .Release.Name }}
663 annotations:
664 checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
665 spec:
666 containers:
667 - name: {{ .Chart.Name }}
668 image: {{ tpl .Values.${SERVICE_NAME}_synchronizerImage . | quote }}
669 imagePullPolicy: {{ .Values.imagePullPolicy }}
670 resources:
671{{ toYaml .Values.resources | indent 12 }}
672 volumeMounts:
673 - name: ${SERVICE_NAME}-config
674 mountPath: /opt/xos/synchronizers/${SERVICE_NAME}/config.yaml
675 subPath: config.yaml
676 - name: certchain-volume
677 mountPath: /usr/local/share/ca-certificates/local_certs.crt
678 subPath: config/ca_cert_chain.pem
679 volumes:
680 - name: ${SERVICE_NAME}-config
681 configMap:
682 name: ${SERVICE_NAME}
683 items:
684 - key: serviceConfig
685 path: config.yaml
686 - name: certchain-volume
687 configMap:
688 name: ca-certificates
689 items:
690 - key: chain
691 path: config/ca_cert_chain.pem
692 {{- with .Values.nodeSelector }}
693 nodeSelector:
694{{ toYaml . | indent 8 }}
695 {{- end }}
696 {{- with .Values.affinity }}
697 affinity:
698{{ toYaml . | indent 8 }}
699 {{- end }}
700 {{- with .Values.tolerations }}
701 tolerations:
702{{ toYaml . | indent 8 }}
703 {{- end }}
704EOF
705
706echo 'Done! Check the newly created service repo with service_lint.sh'