Exemplo n.º 1
0
    def internal_build_config(self) -> Sequence[ObjectItem]:
        ret = [
            Object(
                {
                    'apiVersion': 'v1',
                    'kind': 'ConfigMap',
                    'metadata': {
                        'name': self.object_name('config'),
                        'namespace': self.namespace(),
                    },
                    'data': {
                        'enabled_plugins':
                        LiteralStr('[{}].'.format(', '.join(
                            self.option_get('config.enabled_plugins')))),
                        'rabbitmq.conf':
                        LiteralStr(self.configfile_get()),
                    }
                },
                name=self.BUILDITEM_CONFIG,
                source=self.SOURCE_NAME,
                instance=self.basename())
        ]

        config_secret = {}
        if not IsKData(self.option_get('config.erlang_cookie')):
            config_secret.update({
                'erlang_cookie':
                self.kubragen.secret_data_encode(
                    self.option_get('config.erlang_cookie')),
            })

        if not IsKData(self.option_get('config.load_definitions')):
            if self.option_get('config.load_definitions') is not None:
                config_secret.update({
                    'load_definition.json':
                    self.kubragen.secret_data_encode(
                        self.option_get('config.load_definitions')),
                })

        if len(config_secret) > 0:
            ret.append(
                Object(
                    {
                        'apiVersion': 'v1',
                        'kind': 'Secret',
                        'metadata': {
                            'name': self.object_name('config-secret'),
                            'namespace': self.namespace(),
                        },
                        'type': 'Opaque',
                        'data': config_secret,
                    },
                    name=self.BUILDITEM_CONFIG_SECRET,
                    source=self.SOURCE_NAME,
                    instance=self.basename()))

        return ret
Exemplo n.º 2
0
    def test_merge(self):
        data = [
            Object({
                'foo': 'bar',
                'shin': {
                    'gami': 'hai',
                    'shami': 'nai',
                },
            },
                   name='x')
        ]

        ret = FilterJSONPatches_Apply(items=data,
                                      jsonpatches=[
                                          FilterJSONPatch(
                                              filters={'names': ['x']},
                                              patches=[{
                                                  'op': 'add',
                                                  'path': '/shin/tari',
                                                  'value': 'bai'
                                              }])
                                      ])

        self.assertEqual(ret, [{
            'foo': 'bar',
            'shin': {
                'gami': 'hai',
                'shami': 'nai',
                'tari': 'bai'
            }
        }])
Exemplo n.º 3
0
    def internal_build_accesscontrol(self) -> Sequence[ObjectItem]:
        ret: List[ObjectItem] = []

        if self.option_get(
                'config.authorization.serviceaccount_create') is not False:
            ret.extend([
                Object(
                    {
                        'apiVersion': 'v1',
                        'kind': 'ServiceAccount',
                        'metadata': {
                            'name': self.object_name('service-account'),
                            'namespace': self.namespace(),
                        }
                    },
                    name=self.BUILDITEM_SERVICE_ACCOUNT,
                    source=self.SOURCE_NAME,
                    instance=self.basename()),
            ])

        ret.extend(
            self._build_result_change(
                self._create_prometheus_config().build(
                    PrometheusBuilder.BUILD_ACCESSCONTROL), 'prometheus'))

        if self.option_get('enable.kube-state-metrics') is not False:
            ret.extend(
                self._build_result_change(
                    self._create_kubestatemetrics_config().build(
                        KubeStateMetricsBuilder.BUILD_ACCESSCONTROL),
                    'kube-state-metrics'))

        return ret
Exemplo n.º 4
0
    def test_merge_filters_4(self):
        data = [
            Object({
                'foo': 'bar',
                'shin': 'gami',
            },
                   name='x',
                   source='y',
                   instance='z')
        ]

        ret = FilterJSONPatches_Apply(items=data,
                                      jsonpatches=[
                                          FilterJSONPatch(filters=[
                                              lambda o: o.name == 'a',
                                              lambda o: o.name == 'x'
                                          ],
                                                          patches=[{
                                                              'op':
                                                              'add',
                                                              'path':
                                                              '/tari',
                                                              'value':
                                                              'bai'
                                                          }])
                                      ])
        self.assertEqual(ret, [{'foo': 'bar', 'shin': 'gami', 'tari': 'bai'}])
Exemplo n.º 5
0
    def test_merge_str_to_helperstr(self):
        data = [Object({
            'foo': 'bar',
            'shin': QuotedStr('gami'),
        }, name='x')]

        ret = FilterJSONPatches_Apply(items=data,
                                      jsonpatches=[
                                          FilterJSONPatch(
                                              filters={'names': ['x']},
                                              patches=[{
                                                  'op': 'replace',
                                                  'path': '/shin',
                                                  'value': 'bai'
                                              }])
                                      ])

        self.assertEqual(ret, [{'foo': 'bar', 'shin': 'bai'}])
        self.assertNotIsInstance(ret[0]['shin'], HelperStr)
Exemplo n.º 6
0
    def internal_build_config(self) -> Sequence[ObjectItem]:
        ret = []

        ret.append(
            Object(
                {
                    'apiVersion': 'v1',
                    'kind': 'ConfigMap',
                    'metadata': {
                        'name': self.object_name('config'),
                        'namespace': self.namespace(),
                    },
                    'data': {
                        'promtail.yaml':
                        LiteralStr(self.promtail_configfile_get()),
                    }
                },
                name=self.BUILDITEM_CONFIG,
                source=self.SOURCE_NAME,
                instance=self.basename()))

        return ret
Exemplo n.º 7
0
    def internal_build_config(self) -> Sequence[ObjectItem]:
        ret = []

        ret.append(
            Object(
                {
                    'apiVersion': 'v1',
                    'kind': 'Secret',
                    'metadata': {
                        'name': self.object_name('config-secret'),
                        'namespace': self.namespace(),
                    },
                    'type': 'Opaque',
                    'data': {
                        'loki.yaml':
                        self.kubragen.secret_data_encode(
                            self.loki_configfile_get()),
                    }
                },
                name=self.BUILDITEM_CONFIG_SECRET,
                source=self.SOURCE_NAME,
                instance=self.basename()))

        return ret
Exemplo n.º 8
0
out.append(shell_script)

shell_script.append('set -e')

#
# OUTPUTFILE: app-namespace.yaml
#
file = OutputFile_Kubernetes('app-namespace.yaml')

file.append([
    Object(
        {
            'apiVersion': 'v1',
            'kind': 'Namespace',
            'metadata': {
                'name': 'app-monitoring',
            },
        },
        name='ns-monitoring',
        source='app',
        instance='app')
])

out.append(file)
shell_script.append(
    OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

shell_script.append(
    f'kubectl config set-context --current --namespace=app-monitoring')

#
Exemplo n.º 9
0
 def internal_build_service(self) -> Sequence[ObjectItem]:
     ret = []
     ret.extend([
         Object(
             {
                 'apiVersion': 'v1',
                 'kind': 'Service',
                 'metadata': {
                     'name': self.object_name('service-headless'),
                     'namespace': self.namespace(),
                 },
                 'spec': {
                     'clusterIP':
                     'None',
                     'ports': [{
                         'name': 'epmd',
                         'port': 4369,
                         'protocol': 'TCP',
                         'targetPort': 4369
                     }, {
                         'name': 'cluster-links',
                         'port': 25672,
                         'protocol': 'TCP',
                         'targetPort': 25672
                     }],
                     'selector': {
                         'app': self.object_name('pod-label-app'),
                     },
                     'type':
                     'ClusterIP',
                     'sessionAffinity':
                     'None'
                 }
             },
             name=self.BUILDITEM_SERVICE_HEADLESS,
             source=self.SOURCE_NAME,
             instance=self.basename()),
         Object(
             {
                 'apiVersion': 'apps/v1',
                 'kind': 'StatefulSet',
                 'metadata': {
                     'name': self.object_name('statefulset'),
                     'namespace': self.namespace(),
                     'labels': {
                         'app': self.object_name('pod-label-app'),
                     },
                 },
                 'spec': {
                     'selector': {
                         'matchLabels': {
                             'app': self.object_name('pod-label-app'),
                         }
                     },
                     'serviceName': self.object_name('service-headless'),
                     'replicas': 1,
                     'template': {
                         'metadata': {
                             'name':
                             self.object_name('pod-label-app'),
                             'namespace':
                             self.namespace(),
                             'labels': {
                                 'app': self.object_name('pod-label-app'),
                             },
                             'annotations':
                             ValueData(
                                 {
                                     'prometheus.io/scrape':
                                     QuotedStr('true'),
                                     'prometheus.io/path':
                                     QuotedStr('/metrics'),
                                     'prometheus.io/port':
                                     QuotedStr('15692'),
                                 },
                                 enabled=self.option_get(
                                     'config.enable_prometheus')
                                 is not False and self.option_get(
                                     'config.prometheus_annotation')
                                 is not False),
                         },
                         'spec': {
                             'initContainers': [{
                                 'name':
                                 'rabbitmq-config',
                                 'image':
                                 self.option_get('container.busybox'),
                                 'securityContext': {
                                     'runAsUser': 0,
                                     'runAsGroup': 0
                                 },
                                 'volumeMounts': [
                                     {
                                         'name': 'rabbitmq-config',
                                         'mountPath': '/tmp/rabbitmq'
                                     }, {
                                         'name': 'rabbitmq-config-rw',
                                         'mountPath': '/etc/rabbitmq'
                                     }, {
                                         'name':
                                         'rabbitmq-config-erlang-cookie',
                                         'mountPath': '/tmp/rabbitmq-cookie'
                                     }
                                 ],
                                 'command': [
                                     'sh', '-c', 'cp '
                                     '/tmp/rabbitmq/rabbitmq.conf '
                                     '/etc/rabbitmq/rabbitmq.conf '
                                     "&& echo '' "
                                     '>> '
                                     '/etc/rabbitmq/rabbitmq.conf; '
                                     'cp '
                                     '/tmp/rabbitmq/enabled_plugins '
                                     '/etc/rabbitmq/enabled_plugins; '
                                     'mkdir -p '
                                     '/var/lib/rabbitmq; '
                                     'cp '
                                     '/tmp/rabbitmq-cookie/erlang_cookie '
                                     '/var/lib/rabbitmq/.erlang.cookie; '
                                     'chmod 600 '
                                     '/var/lib/rabbitmq/.erlang.cookie; '
                                     'chown '
                                     '999.999 '
                                     '/etc/rabbitmq/rabbitmq.conf '
                                     '/etc/rabbitmq/enabled_plugins '
                                     '/var/lib/rabbitmq '
                                     '/var/lib/rabbitmq/.erlang.cookie'
                                 ]
                             }],
                             'volumes': [
                                 {
                                     'name': 'rabbitmq-config',
                                     'configMap': {
                                         'name':
                                         self.object_name('config'),
                                         'optional':
                                         False,
                                         'items': [{
                                             'key': 'enabled_plugins',
                                             'path': 'enabled_plugins'
                                         }, {
                                             'key': 'rabbitmq.conf',
                                             'path': 'rabbitmq.conf'
                                         }]
                                     }
                                 },
                                 {
                                     'name': 'rabbitmq-config-rw',
                                     'emptyDir': {}
                                 },
                                 KDataHelper_Volume.info(
                                     base_value={
                                         'name':
                                         'rabbitmq-config-erlang-cookie',
                                     },
                                     value_if_kdata=self.option_get(
                                         'config.erlang_cookie'),
                                     default_value={
                                         'secret': {
                                             'secretName':
                                             self.object_name(
                                                 'config-secret'),
                                             'items': [{
                                                 'key':
                                                 'erlang_cookie',
                                                 'path':
                                                 'erlang_cookie',
                                             }]
                                         },
                                     },
                                     key_path='erlang_cookie'),
                                 KDataHelper_Volume.info(
                                     base_value={
                                         'name':
                                         'rabbitmq-config-load-definition',
                                     },
                                     value_if_kdata=self.option_get(
                                         'config.load_definitions'),
                                     default_value={
                                         'secret': {
                                             'secretName':
                                             self.object_name(
                                                 'config-secret'),
                                             'items': [{
                                                 'key':
                                                 'load_definition.json',
                                                 'path':
                                                 'load_definition.json',
                                             }]
                                         }
                                     },
                                     key_path='load_definition.json',
                                     enabled=self.option_get(
                                         'config.load_definitions')
                                     is not None),
                                 KDataHelper_Volume.info(
                                     base_value={
                                         'name': 'rabbitmq-data',
                                     },
                                     value=self.option_get(
                                         'kubernetes.volumes.data')),
                             ],
                             'serviceAccountName':
                             ValueData(
                                 value=self.object_name('service-account'),
                                 enabled=self.object_name('service-account')
                                 is not None),
                             'securityContext': {
                                 'fsGroup': 999,
                                 'runAsUser': 999,
                                 'runAsGroup': 999
                             },
                             'containers': [{
                                 'name':
                                 'rabbitmq',
                                 'image':
                                 self.option_get('container.rabbitmq'),
                                 'volumeMounts': [
                                     {
                                         'name': 'rabbitmq-config-rw',
                                         'mountPath': '/etc/rabbitmq'
                                     }, {
                                         'name': 'rabbitmq-data',
                                         'mountPath':
                                         '/var/lib/rabbitmq/mnesia'
                                     },
                                     ValueData(value={
                                         'name':
                                         'rabbitmq-config-load-definition',
                                         'mountPath':
                                         '/etc/rabbitmq-load-definition',
                                         'readOnly': True,
                                     },
                                               enabled=self.option_get(
                                                   'config.load_definitions'
                                               ) is not None)
                                 ],
                                 'ports': [
                                     {
                                         'name': 'amqp',
                                         'containerPort': 5672,
                                         'protocol': 'TCP'
                                     }, {
                                         'name': 'management',
                                         'containerPort': 15672,
                                         'protocol': 'TCP'
                                     },
                                     ValueData(
                                         value={
                                             'name': 'prometheus',
                                             'containerPort': 15692,
                                             'protocol': 'TCP'
                                         },
                                         enabled=self.option_get(
                                             'config.enable_prometheus')
                                         is not False), {
                                             'name': 'epmd',
                                             'containerPort': 4369,
                                             'protocol': 'TCP'
                                         }
                                 ],
                                 'livenessProbe': {
                                     'exec': {
                                         'command':
                                         ['rabbitmq-diagnostics', 'status']
                                     },
                                     'initialDelaySeconds': 60,
                                     'periodSeconds': 60,
                                     'timeoutSeconds': 15
                                 },
                                 'readinessProbe': {
                                     'exec': {
                                         'command':
                                         ['rabbitmq-diagnostics', 'ping']
                                     },
                                     'initialDelaySeconds': 20,
                                     'periodSeconds': 60,
                                     'timeoutSeconds': 10
                                 },
                                 'resources':
                                 ValueData(value=self.option_get(
                                     'kubernetes.resources.statefulset'),
                                           disabled_if_none=True),
                             }]
                         }
                     }
                 }
             },
             name=self.BUILDITEM_STATEFULSET,
             source=self.SOURCE_NAME,
             instance=self.basename()),
         Object(
             {
                 'kind': 'Service',
                 'apiVersion': 'v1',
                 'metadata': {
                     'name': self.object_name('service'),
                     'namespace': self.namespace(),
                     'labels': {
                         'app': self.object_name('pod-label-app')
                     },
                 },
                 'spec': {
                     'type':
                     'ClusterIP',
                     'ports': [{
                         'name': 'http',
                         'protocol': 'TCP',
                         'port': 15672,
                     },
                               ValueData(value={
                                   'name': 'prometheus',
                                   'protocol': 'TCP',
                                   'port': 15692
                               },
                                         enabled=self.option_get(
                                             'config.enable_prometheus')
                                         is not False), {
                                             'name': 'amqp',
                                             'protocol': 'TCP',
                                             'port': 5672
                                         }],
                     'selector': {
                         'app': self.object_name('pod-label-app')
                     }
                 }
             },
             name=self.BUILDITEM_SERVICE,
             source=self.SOURCE_NAME,
             instance=self.basename())
     ])
     return ret
Exemplo n.º 10
0
#
# OUTPUTFILE: app-namespace.yaml
#
file = OutputFile_Kubernetes('app-namespace.yaml')
out.append(file)

file.append(
    FilterJSONPatches_Apply(
        [
            Object(
                {
                    'apiVersion': 'v1',
                    'kind': 'Namespace',
                    'metadata': {
                        'name': 'app-default',
                        'annotations': {
                            'will-not-output':
                            ValueData(value='anything', enabled=False),
                        }
                    },
                },
                name='ns-default',
                source='app'),
            Object(
                {
                    'apiVersion': 'v1',
                    'kind': 'Namespace',
                    'metadata': {
                        'name': 'app-monitoring',
                    },
                },
                name='ns-monitoring',
Exemplo n.º 11
0
    def internal_build_accesscontrol(self) -> Sequence[ObjectItem]:
        ret = []

        if self.option_get(
                'config.authorization.serviceaccount_create') is not False:
            ret.extend([
                Object(
                    {
                        'apiVersion': 'v1',
                        'kind': 'ServiceAccount',
                        'metadata': {
                            'name': self.object_name('service-account'),
                            'namespace': self.namespace(),
                        }
                    },
                    name=self.BUILDITEM_SERVICE_ACCOUNT,
                    source=self.SOURCE_NAME,
                    instance=self.basename()),
            ])

        if self.option_get('config.authorization.roles_create') is not False:
            ret.extend([
                Object(
                    {
                        'kind':
                        'Role',
                        'apiVersion':
                        'rbac.authorization.k8s.io/v1beta1',
                        'metadata': {
                            'name': self.object_name('role'),
                            'namespace': self.namespace(),
                        },
                        'rules': [{
                            'apiGroups': [''],
                            'resources': ['endpoints'],
                            'verbs': ['get']
                        }, {
                            'apiGroups': [''],
                            'resources': ['events'],
                            'verbs': ['create']
                        }]
                    },
                    name=self.BUILDITEM_ROLE,
                    source=self.SOURCE_NAME,
                    instance=self.basename()),
            ])

        if self.option_get('config.authorization.roles_bind') is not False:
            ret.extend([
                Object(
                    {
                        'kind':
                        'RoleBinding',
                        'apiVersion':
                        'rbac.authorization.k8s.io/v1beta1',
                        'metadata': {
                            'name': self.object_name('role-binding'),
                            'namespace': self.namespace(),
                        },
                        'subjects':
                        [{
                            'kind': 'ServiceAccount',
                            'name': self.object_name('service-account'),
                        }],
                        'roleRef': {
                            'apiGroup': 'rbac.authorization.k8s.io',
                            'kind': 'Role',
                            'name': self.object_name('role'),
                        }
                    },
                    name=self.BUILDITEM_ROLE_BINDING,
                    source=self.SOURCE_NAME,
                    instance=self.basename())
            ])

        return ret
Exemplo n.º 12
0
    def test_no_merge(self):
        data = [
            Object({
                'foo': 'bar',
                'shin': {
                    'gami': 'hai',
                    'shami': 'nai',
                },
            },
                   name='x',
                   source='y',
                   instance='z')
        ]

        ret = FilterJSONPatches_Apply(items=data,
                                      jsonpatches=[
                                          FilterJSONPatch(
                                              filters={'names': ['a']},
                                              patches=[{
                                                  'op': 'add',
                                                  'path': '/shin/tari',
                                                  'value': 'bai'
                                              }])
                                      ])
        self.assertEqual(ret, [{
            'foo': 'bar',
            'shin': {
                'gami': 'hai',
                'shami': 'nai'
            }
        }])

        ret = FilterJSONPatches_Apply(items=data,
                                      jsonpatches=[
                                          FilterJSONPatch(
                                              filters={'sources': ['b']},
                                              patches=[{
                                                  'op': 'add',
                                                  'path': '/shin/tari',
                                                  'value': 'bai'
                                              }])
                                      ])
        self.assertEqual(ret, [{
            'foo': 'bar',
            'shin': {
                'gami': 'hai',
                'shami': 'nai'
            }
        }])

        ret = FilterJSONPatches_Apply(items=data,
                                      jsonpatches=[
                                          FilterJSONPatch(
                                              filters={'instances': ['c']},
                                              patches=[{
                                                  'op': 'add',
                                                  'path': '/shin/tari',
                                                  'value': 'bai'
                                              }])
                                      ])
        self.assertEqual(ret, [{
            'foo': 'bar',
            'shin': {
                'gami': 'hai',
                'shami': 'nai'
            }
        }])

        ret = FilterJSONPatches_Apply(items=data,
                                      jsonpatches=[
                                          FilterJSONPatch(filters=ObjectFilter(
                                              names='a',
                                              sources='y',
                                              instances='z'),
                                                          patches=[{
                                                              'op':
                                                              'add',
                                                              'path':
                                                              '/shin/tari',
                                                              'value':
                                                              'bai'
                                                          }])
                                      ])
        self.assertEqual(ret, [{
            'foo': 'bar',
            'shin': {
                'gami': 'hai',
                'shami': 'nai'
            }
        }])

        ret = FilterJSONPatches_Apply(items=data,
                                      jsonpatches=[
                                          FilterJSONPatch(filters=[
                                              ObjectFilter(sources='h',
                                                           instances='j'),
                                              lambda o: o.name == 'i'
                                          ],
                                                          patches=[{
                                                              'op':
                                                              'add',
                                                              'path':
                                                              '/shin/tari',
                                                              'value':
                                                              'bai'
                                                          }])
                                      ])
        self.assertEqual(ret, [{
            'foo': 'bar',
            'shin': {
                'gami': 'hai',
                'shami': 'nai'
            }
        }])
Exemplo n.º 13
0
    def internal_build_service(self) -> Sequence[ObjectItem]:
        self._checkdownloaded()

        ret = []

        if self._downloadedfiles is not None:
            for item in self._downloadedfiles['headless-service.yaml']:
                ritem = item
                if ritem['kind'] == 'Service':
                    ritem = Object(jsonpatchext.apply_patch(ritem, [
                        {
                            'op': 'check',
                            'path': '/metadata/name',
                            'cmp': 'equals',
                            'value': 'rabbitmq-headless'
                        },
                        {
                            'op': 'check',
                            'path': '/metadata/namespace',
                            'cmp': 'equals',
                            'value': 'test-rabbitmq'
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/name',
                            'value': self.object_name('service-headless')
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/namespace',
                            'value': self.namespace()
                        },
                        {
                            'op': 'replace',
                            'path': '/spec/selector/app',
                            'value': self.object_name('pod-label-app')
                        },
                    ],
                                                            in_place=False),
                                   name=self.BUILDITEM_SERVICE_HEADLESS,
                                   source=self.SOURCE_NAME,
                                   instance=self.basename())
                ret.append(ritem)

            for item in self._downloadedfiles['statefulset.yaml']:
                ritem = item
                if ritem['kind'] == 'StatefulSet':
                    ritempatch = [
                        {
                            'op': 'check',
                            'path': '/metadata/name',
                            'cmp': 'equals',
                            'value': 'rabbitmq'
                        },
                        {
                            'op': 'check',
                            'path': '/metadata/namespace',
                            'cmp': 'equals',
                            'value': 'test-rabbitmq'
                        },
                        {
                            'op': 'check',
                            'path':
                            '/spec/template/spec/initContainers/0/image',
                            'cmp': 'startswith',
                            'value': 'busybox'
                        },
                        {
                            'op': 'check',
                            'path': '/spec/template/spec/volumes/2/name',
                            'cmp': 'equals',
                            'value': 'rabbitmq-data'
                        },
                        {
                            'op': 'check',
                            'path': '/spec/template/spec/containers/0/image',
                            'cmp': 'startswith',
                            'value': 'rabbitmq'
                        },
                        {
                            'op': 'check',
                            'path':
                            '/spec/template/spec/containers/0/env/0/name',
                            'cmp': 'equals',
                            'value': 'RABBITMQ_DEFAULT_PASS'
                        },
                        {
                            'op': 'check',
                            'path':
                            '/spec/template/spec/containers/0/env/1/name',
                            'cmp': 'equals',
                            'value': 'RABBITMQ_DEFAULT_USER'
                        },
                        {
                            'op': 'check',
                            'path':
                            '/spec/template/spec/containers/0/env/2/name',
                            'cmp': 'equals',
                            'value': 'RABBITMQ_ERLANG_COOKIE'
                        },
                        {
                            'op': 'check',
                            'path':
                            '/spec/template/spec/containers/0/ports/2/name',
                            'cmp': 'equals',
                            'value': 'prometheus'
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/name',
                            'value': self.object_name('statefulset')
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/namespace',
                            'value': self.namespace()
                        },
                        {
                            'op': 'merge',
                            'path': '/metadata',
                            'value': {
                                'labels': {}
                            }
                        },
                        {
                            'op': 'merge',
                            'path': '/metadata/labels',
                            'value': {
                                'app': self.object_name('pod-label-app')
                            }
                        },
                        {
                            'op': 'replace',
                            'path': '/spec/selector/matchLabels/app',
                            'value': self.object_name('pod-label-app')
                        },
                        {
                            'op': 'replace',
                            'path': '/spec/serviceName',
                            'value': self.object_name('service-headless')
                        },
                        {
                            'op': 'remove',
                            'path': '/spec/volumeClaimTemplates'
                        },
                        {
                            'op': 'replace',
                            'path': '/spec/template/metadata/name',
                            'value': self.object_name('pod-label-app')
                        },
                        {
                            'op': 'replace',
                            'path': '/spec/template/metadata/namespace',
                            'value': self.namespace()
                        },
                        {
                            'op': 'replace',
                            'path': '/spec/template/metadata/labels/app',
                            'value': self.object_name('pod-label-app')
                        },
                        {
                            'op':
                            'replace',
                            'path':
                            '/spec/template/spec/serviceAccount',
                            'value':
                            ValueData(
                                value=self.object_name('service-account'),
                                enabled=self.object_name('service-account')
                                is not None)
                        },
                        {
                            'op':
                            'replace',
                            'path':
                            '/spec/template/spec/volumes/2',
                            'value':
                            KDataHelper_Volume.info(
                                base_value={
                                    'name': 'rabbitmq-data',
                                },
                                value=self.option_get(
                                    'kubernetes.volumes.data'))
                        },
                        {
                            'op':
                            'replace',
                            'path':
                            '/spec/template/spec/containers/0/env/0',
                            'value':
                            KDataHelper_Env.info(
                                base_value={'name': 'RABBITMQ_DEFAULT_PASS'},
                                value=self.option_get('config.admin.password'),
                                default_value={
                                    'valueFrom': {
                                        'secretKeyRef': {
                                            'name':
                                            self.object_name('config-secret'),
                                            'key':
                                            'admin.password'
                                        }
                                    },
                                })
                        },
                        {
                            'op':
                            'replace',
                            'path':
                            '/spec/template/spec/containers/0/env/1',
                            'value':
                            KDataHelper_Env.info(
                                base_value={'name': 'RABBITMQ_DEFAULT_USER'},
                                value=self.option_get('config.admin.username'),
                                default_value={
                                    'valueFrom': {
                                        'secretKeyRef': {
                                            'name':
                                            self.object_name('config-secret'),
                                            'key':
                                            'admin.username'
                                        }
                                    },
                                })
                        },
                        {
                            'op':
                            'replace',
                            'path':
                            '/spec/template/spec/containers/0/env/2',
                            'value':
                            KDataHelper_Env.info(
                                base_value={'name': 'RABBITMQ_ERLANG_COOKIE'},
                                value=self.option_get('config.erlang_cookie'),
                                default_value={
                                    'valueFrom': {
                                        'secretKeyRef': {
                                            'name':
                                            self.object_name('config-secret'),
                                            'key':
                                            'erlang_cookie'
                                        }
                                    },
                                })
                        },
                        {
                            'op':
                            'add',
                            'path':
                            '/spec/template/spec/containers/0/resources',
                            'value':
                            ValueData(value=self.option_get(
                                'kubernetes.resources.statefulset'),
                                      disabled_if_none=True),
                        },
                    ]

                    if self.option_get('container.busybox') is not None:
                        ritempatch.append({
                            'op':
                            'replace',
                            'path':
                            '/spec/template/spec/initContainers/0/image',
                            'value':
                            self.option_get('container.busybox')
                        })
                    if self.option_get('container.rabbitmq') is not None:
                        ritempatch.append({
                            'op':
                            'replace',
                            'path':
                            '/spec/template/spec/containers/0/image',
                            'value':
                            self.option_get('container.rabbitmq')
                        })
                    if self.option_get('config.enable_prometheus') is False:
                        ritempatch.append({
                            'op':
                            'remove',
                            'path':
                            '/spec/template/spec/containers/0/ports/2'
                        })
                    if self.option_get(
                            'config.enable_prometheus'
                    ) is not False and self.option_get(
                            'config.prometheus_annotation') is not False:
                        ritempatch.append({
                            'op': 'merge',
                            'path': '/spec/template/metadata',
                            'value': {
                                'annotations': {
                                    'prometheus.io/scrape': QuotedStr('true'),
                                    'prometheus.io/path':
                                    QuotedStr('/metrics'),
                                    'prometheus.io/port': QuotedStr('15692'),
                                }
                            }
                        })
                    if self.option_get('config.load_definitions') is not None:
                        ritempatch.append({
                            'op':
                            'add',
                            'path':
                            '/spec/template/spec/volumes',
                            'value':
                            KDataHelper_Volume.info(
                                base_value={
                                    'name': 'rabbitmq-config-load-definition',
                                },
                                value_if_kdata=self.option_get(
                                    'config.load_definitions'),
                                default_value={
                                    'secret': {
                                        'secretName':
                                        self.object_name('config-secret'),
                                        'items': [{
                                            'key':
                                            'load_definition.json',
                                            'path':
                                            'load_definition.json',
                                        }]
                                    }
                                },
                                key_path='load_definition.json')
                        })
                        ritempatch.append({
                            'op': 'add',
                            'path':
                            '/spec/template/spec/containers/0/volumeMounts',
                            'value': {
                                'name': 'rabbitmq-config-load-definition',
                                'mountPath': '/etc/rabbitmq-load-definition',
                                'readOnly': True,
                            }
                        })

                    ritem = Object(jsonpatchext.apply_patch(ritem,
                                                            ritempatch,
                                                            in_place=False),
                                   name=self.BUILDITEM_STATEFULSET,
                                   source=self.SOURCE_NAME,
                                   instance=self.basename())
                ret.append(ritem)

            for item in self._downloadedfiles['client-service.yaml']:
                ritem = item
                if ritem['kind'] == 'Service':
                    ritempatch = [
                        {
                            'op': 'check',
                            'path': '/metadata/name',
                            'cmp': 'equals',
                            'value': 'rabbitmq-client'
                        },
                        {
                            'op': 'check',
                            'path': '/metadata/namespace',
                            'cmp': 'equals',
                            'value': 'test-rabbitmq'
                        },
                        {
                            'op': 'check',
                            'path': '/spec/ports/1/name',
                            'cmp': 'equals',
                            'value': 'prometheus'
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/name',
                            'value': self.object_name('service')
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/namespace',
                            'value': self.namespace()
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/labels/app',
                            'value': self.object_name('pod-label-app')
                        },
                        {
                            'op': 'replace',
                            'path': '/spec/type',
                            'value': self.option_get('config.servicetype')
                        },
                        {
                            'op': 'replace',
                            'path': '/spec/selector/app',
                            'value': self.object_name('pod-label-app')
                        },
                    ]
                    if self.option_get('config.enable_prometheus') is False:
                        ritempatch.append({
                            'op': 'remove',
                            'path': '/spec/ports/1'
                        })
                    ritem = Object(jsonpatchext.apply_patch(ritem,
                                                            ritempatch,
                                                            in_place=False),
                                   name=self.BUILDITEM_SERVICE,
                                   source=self.SOURCE_NAME,
                                   instance=self.basename())
                ret.append(ritem)

        self._check_object_must_have(
            ret, [
                self.BUILDITEM_SERVICE_HEADLESS, self.BUILDITEM_STATEFULSET,
                self.BUILDITEM_SERVICE
            ], 'headless-service.yaml, statefulset.yaml, client-service.yaml')

        return ret
Exemplo n.º 14
0
def main():
    parser = argparse.ArgumentParser(description='Kube Creator')
    parser.add_argument('-p', '--provider', help='provider', required=True, choices=[
        'google-gke',
        'amazon-eks',
        'digitalocean-kubernetes',
        'k3d',
    ])
    parser.add_argument('-o', '--output-path', help='output path', default='output')
    args = parser.parse_args()

    if args.provider == 'k3d':
        kgprovider = ProviderK3DGeneric()
    elif args.provider == 'google-gke':
        kgprovider = ProviderGoogleGKE()
    elif args.provider == 'digitalocean-kubernetes':
        kgprovider = ProviderDigitalOceanKubernetes()
    elif args.provider == 'amazon-eks':
        kgprovider = ProviderAmazonEKS()
    else:
        raise Exception('Unknown target')

    kg = KubraGen(provider=kgprovider, options=Options({
        'namespaces': {
            'default': 'default',
            'mon': 'monitoring',
        },
    }))

    if kgprovider.provider == PROVIDER_K3D:
        kg.resources().persistentvolumeprofile_add('default', KRPersistentVolumeProfile_HostPath())
    elif kgprovider.provider == PROVIDER_GOOGLE:
        kg.resources().persistentvolumeprofile_add('default', KRPersistentVolumeProfile_GCEPersistentDisk())
    elif kgprovider.provider == PROVIDER_DIGITALOCEAN:
        kg.resources().persistentvolumeprofile_add('default', KRPersistentVolumeProfile_CSI_DOBS())
    elif kgprovider.provider == PROVIDER_AMAZON:
        kg.resources().persistentvolumeprofile_add('default', KRPersistentVolumeProfile_AWSElasticBlockStore())

    if kgprovider.provider == PROVIDER_K3D:
        kg.resources().persistentvolumeclaimprofile_add('default', KRPersistentVolumeClaimProfile_Basic(allow_selector=False))
    else:
        kg.resources().persistentvolumeclaimprofile_add('default', KRPersistentVolumeClaimProfile_Basic())

    kg.resources().persistentvolume_add('elasticsearch-storage', 'default', {
        'hostPath': {
            'path': '/var/storage/elasticsearch'
        },
        'csi': {
            'fsType': 'ext4',
        },
    }, {
        'metadata': {
            'labels': {
                'pv.role': 'elasticsearch',
            },
        },
        'spec': {
            'persistentVolumeReclaimPolicy': 'Retain',
            'capacity': {
                'storage': '50Gi'
            },
            'accessModes': ['ReadWriteOnce'],
        },
    })

    kg.resources().persistentvolumeclaim_add('elasticsearch-storage-claim', 'default', {
        'namespace': 'monitoring',
        'persistentVolume': 'elasticsearch-storage',
    }, {
        'spec': {
            'selector': {
                'matchLabels': {
                    'pv.role': 'elasticsearch',
                }
            },
        }
    })

    out = OutputProject(kg)

    shell_script = OutputFile_ShellScript('create_{}.sh'.format(args.provider))
    out.append(shell_script)

    shell_script.append('set -e')

    #
    # Provider setup
    #
    if kgprovider.provider == PROVIDER_K3D:
        storage_directory = os.path.join(os.getcwd(), 'output', 'storage')
        if not os.path.exists(storage_directory):
            os.makedirs(storage_directory)
        shell_script.append(f'# k3d cluster create kgsample-efk-stack --port 5051:80@loadbalancer --port 5052:443@loadbalancer -v {storage_directory}:/var/storage')

    #
    # OUTPUTFILE: namespace.yaml
    #
    file = OutputFile_Kubernetes('namespace.yaml')
    file.append([{
        'apiVersion': 'v1',
        'kind': 'Namespace',
        'metadata': {
            'name': 'monitoring',
        },
    }])
    out.append(file)
    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # OUTPUTFILE: storage.yaml
    #
    file = OutputFile_Kubernetes('storage.yaml')

    file.append(kg.persistentvolume_build())
    file.append(kg.persistentvolumeclaim_build())

    out.append(file)
    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # SETUP: Traefik 2
    #
    traefik2_config = Traefik2Builder(kubragen=kg, options=Traefik2Options({
            'namespace': OptionRoot('namespaces.default'),
            'config': {
                'traefik_args': [
                    '--api.dashboard=true',
                    '--api.insecure=false',
                    '--entrypoints.web.Address=:80',
                    '--entrypoints.api.Address=:8080',
                    '--providers.kubernetescrd',
                    f'--providers.kubernetescrd.namespaces=default,monitoring'
                ],
                'ports': [
                    Traefik2OptionsPort(name='web', port_container=80, port_service=80),
                    Traefik2OptionsPort(name='api', port_container=8080, port_service=8080),
                ],
                'create_traefik_crd': True,
            },
        })
    )

    traefik2_config.ensure_build_names(traefik2_config.BUILD_CRD, traefik2_config.BUILD_ACCESSCONTROL,
                                       traefik2_config.BUILD_SERVICE)

    #
    # OUTPUTFILE: traefik-config-crd.yaml
    #
    file = OutputFile_Kubernetes('traefik-config-crd.yaml')

    file.append(traefik2_config.build(traefik2_config.BUILD_CRD))

    out.append(file)
    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # OUTPUTFILE: traefik-config.yaml
    #
    file = OutputFile_Kubernetes('traefik-config.yaml')

    file.append(traefik2_config.build(traefik2_config.BUILD_ACCESSCONTROL))

    file.append([{
        'apiVersion': 'traefik.containo.us/v1alpha1',
        'kind': 'IngressRoute',
        'metadata': {
            'name': 'traefik-api',
            'namespace': kg.option_get('namespaces.default'),
        },
        'spec': {
            'entryPoints': ['api'],
            'routes': [{
                'match': 'Method(`GET`)',
                'kind': 'Rule',
                'services': [{
                    'name': 'api@internal',
                    'kind': 'TraefikService'
                }]
            }]
        }
    }])

    out.append(file)
    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # OUTPUTFILE: traefik.yaml
    #
    file = OutputFile_Kubernetes('traefik.yaml')

    file.append(traefik2_config.build(traefik2_config.BUILDITEM_SERVICE))

    file.append({
        'apiVersion': 'traefik.containo.us/v1alpha1',
        'kind': 'IngressRoute',
        'metadata': {
            'name': 'admin-traefik',
            'namespace': kg.option_get('namespaces.default'),
        },
        'spec': {
            'entryPoints': ['web'],
            'routes': [{
                'match': f'Host(`admin-traefik.localdomain`)',
                'kind': 'Rule',
                'services': [{
                    'name': traefik2_config.object_name('service'),
                    'port': 8080
                }],
            }]
        }
    })

    out.append(file)
    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # SETUP: efk
    #
    efk_config = EFKBuilder(kubragen=kg, options=EFKOptions({
        'namespace': OptionRoot('namespaces.mon'),
        'config': {
            'probes': False,
            'elasticsearch': {
                'replicas': 1 if kgprovider.provider == PROVIDER_K3D else 3,
            },
            'kibana': {
                'service_port': 80,
            },
        },
        'enable': {
            'kibana': True,
        },
        'kubernetes': {
            'volumes': {
                'elasticsearch-data': {
                    'persistentVolumeClaim': {
                        'claimName': 'elasticsearch-storage-claim'
                    }
                }
            },
        },
    }))

    efk_config.ensure_build_names(efk_config.BUILD_ACCESSCONTROL, efk_config.BUILD_CONFIG,
                                  efk_config.BUILD_SERVICE)

    #
    # OUTPUTFILE: efk-config.yaml
    #
    file = OutputFile_Kubernetes('efk-config.yaml')
    out.append(file)

    file.append(efk_config.build(efk_config.BUILD_ACCESSCONTROL, efk_config.BUILD_CONFIG))

    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # OUTPUTFILE: efk.yaml
    #
    file = OutputFile_Kubernetes('efk.yaml')
    out.append(file)

    file.append(efk_config.build(efk_config.BUILD_SERVICE))

    file.append([{
        'apiVersion': 'traefik.containo.us/v1alpha1',
        'kind': 'IngressRoute',
        'metadata': {
            'name': 'admin-kibana',
            'namespace': kg.option_get('namespaces.mon'),
        },
        'spec': {
            'entryPoints': ['web'],
            'routes': [{
                'match': f'Host(`admin-kibana.localdomain`)',
                'kind': 'Rule',
                'services': [{
                    'name': efk_config.object_name('kibana-service'),
                    'namespace': efk_config.namespace(),
                    'port': efk_config.option_get('config.kibana.service_port'),
                }],
            }]
        }
    }])

    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # OUTPUTFILE: http-echo.yaml
    #
    file = OutputFile_Kubernetes('http-echo.yaml')
    out.append(file)

    file.append([{
        'apiVersion': 'apps/v1',
        'kind': 'Deployment',
        'metadata': {
            'name': 'echo-deployment',
            'namespace': kg.option_get('namespaces.default'),
            'labels': {
                'app': 'echo'
            }
        },
        'spec': {
            'replicas': 1,
            'selector': {
                'matchLabels': {
                    'app': 'echo'
                }
            },
            'template': {
                'metadata': {
                    'labels': {
                        'app': 'echo'
                    }
                },
                'spec': {
                    'containers': [{
                        'name': 'echo',
                        'image': 'mendhak/http-https-echo',
                        'ports': [{
                            'containerPort': 80
                        },
                        {
                            'containerPort': 443
                        }],
                    }]
                }
            }
        }
    },
    {
        'apiVersion': 'v1',
        'kind': 'Service',
        'metadata': {
            'name': 'echo-service',
            'namespace': kg.option_get('namespaces.default'),
        },
        'spec': {
            'selector': {
                'app': 'echo'
            },
            'ports': [{
                'name': 'http',
                'port': 80,
                'targetPort': 80,
                'protocol': 'TCP'
            }]
        }
    }, {
        'apiVersion': 'traefik.containo.us/v1alpha1',
        'kind': 'IngressRoute',
        'metadata': {
            'name': 'http-echo',
            'namespace': kg.option_get('namespaces.default'),
        },
        'spec': {
            'entryPoints': ['web'],
            'routes': [{
                # 'match': f'Host(`http-echo.localdomain`)',
                'match': f'PathPrefix(`/`)',
                'kind': 'Rule',
                'services': [{
                    'name': 'echo-service',
                    'port': 80,
                }],
            }]
        }
    }])

    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # OUTPUTFILE: ingress.yaml
    #
    file = OutputFile_Kubernetes('ingress.yaml')
    http_path = '/'
    if kgprovider.provider == PROVIDER_GOOGLE or kgprovider.provider == PROVIDER_AMAZON:
        http_path = '/*'

    file_data = [
        Object({
            'apiVersion': 'extensions/v1beta1',
            'kind': 'Ingress',
            'metadata': {
                'name': 'ingress',
                'namespace': kg.option_get('namespaces.default'),
            },
            'spec': {
                'rules': [{
                    'http': {
                        'paths': [{
                            'path': http_path,
                            'backend': {
                                'serviceName': traefik2_config.object_name('service'),
                                'servicePort': 80,
                            }
                        }]
                    }
                }]
            }
        }, name='ingress', source='app', instance='ingress')
    ]

    if kgprovider.provider == PROVIDER_AMAZON:
        FilterJSONPatches_Apply(file_data, jsonpatches=[
            FilterJSONPatch(filters={'names': ['ingress']}, patches=[
                {'op': 'merge', 'path': '/metadata', 'value': {'annotations': {
                    'kubernetes.io/ingress.class': 'alb',
                    'alb.ingress.kubernetes.io/scheme': 'internet-facing',
                    'alb.ingress.kubernetes.io/listen-ports': QuotedStr('[{"HTTP": 80}]'),
                }}}
            ])
        ])

    file.append(file_data)
    out.append(file)
    shell_script.append(OD_FileTemplate(f'kubectl apply -f ${{FILE_{file.fileid}}}'))

    #
    # OUTPUT
    #
    output_path = os.path.join(args.output_path, '{}-{}'.format(
        args.provider, datetime.datetime.today().strftime("%Y%m%d-%H%M%S")))
    print('Saving files to {}'.format(output_path))
    if not os.path.exists(output_path):
        os.makedirs(output_path)

    out.output(OutputDriver_Directory(output_path))
Exemplo n.º 15
0
    def internal_build_accesscontrol(self) -> Sequence[ObjectItem]:
        self._checkdownloaded()

        ret = []
        must_have = []

        if self.option_get(
                'config.authorization.serviceaccount_create') is not False:
            must_have.append(self.BUILDITEM_SERVICE_ACCOUNT)
        if self.option_get('config.authorization.roles_create') is not False:
            must_have.append(self.BUILDITEM_ROLE)
        if self.option_get('config.authorization.roles_bind') is not False:
            must_have.append(self.BUILDITEM_ROLE_BINDING)

        if self._downloadedfiles is not None:
            for item in self._downloadedfiles['rbac.yaml']:
                ritem = item
                if ritem['kind'] == 'ServiceAccount':
                    if self.option_get(
                            'config.authorization.serviceaccount_create'
                    ) is not False:
                        ritem = Object(jsonpatchext.apply_patch(
                            ritem, [
                                {
                                    'op': 'check',
                                    'path': '/metadata/name',
                                    'cmp': 'equals',
                                    'value': 'rabbitmq'
                                },
                                {
                                    'op': 'check',
                                    'path': '/metadata/namespace',
                                    'cmp': 'equals',
                                    'value': 'test-rabbitmq'
                                },
                                {
                                    'op': 'replace',
                                    'path': '/metadata/name',
                                    'value':
                                    self.object_name('service-account')
                                },
                                {
                                    'op': 'replace',
                                    'path': '/metadata/namespace',
                                    'value': self.namespace()
                                },
                            ],
                            in_place=False),
                                       name=self.BUILDITEM_SERVICE_ACCOUNT,
                                       source=self.SOURCE_NAME,
                                       instance=self.basename())
                        ret.append(ritem)
                elif ritem['kind'] == 'Role':
                    if self.option_get(
                            'config.authorization.roles_create') is not False:
                        ritem = Object(jsonpatchext.apply_patch(
                            ritem, [
                                {
                                    'op': 'replace',
                                    'path': '/metadata/name',
                                    'value': self.object_name('role')
                                },
                                {
                                    'op': 'replace',
                                    'path': '/metadata/namespace',
                                    'value': self.namespace()
                                },
                            ],
                            in_place=False),
                                       name=self.BUILDITEM_ROLE,
                                       source=self.SOURCE_NAME,
                                       instance=self.basename())
                        ret.append(ritem)
                elif ritem['kind'] == 'RoleBinding':
                    if self.option_get(
                            'config.authorization.roles_bind') is not False:
                        ritem = Object(jsonpatchext.apply_patch(
                            ritem, [
                                {
                                    'op': 'replace',
                                    'path': '/metadata/name',
                                    'value': self.object_name('role-binding')
                                },
                                {
                                    'op': 'replace',
                                    'path': '/metadata/namespace',
                                    'value': self.namespace()
                                },
                                {
                                    'op': 'replace',
                                    'path': '/subjects/0/name',
                                    'value':
                                    self.object_name('service-account')
                                },
                                {
                                    'op': 'replace',
                                    'path': '/roleRef/name',
                                    'value': self.object_name('role')
                                },
                            ],
                            in_place=False),
                                       name=self.BUILDITEM_ROLE_BINDING,
                                       source=self.SOURCE_NAME,
                                       instance=self.basename())
                        ret.append(ritem)
                else:
                    raise InvalidNameError(
                        'Unknown item kind in rbac.yaml: "{}"'.format(
                            ritem['kind']))

        self._check_object_must_have(ret, must_have, 'rbac.yaml')
        return ret
Exemplo n.º 16
0
    def internal_build_config(self) -> Sequence[ObjectItem]:
        self._checkdownloaded()

        ret = []

        if self._downloadedfiles is not None:
            for item in self._downloadedfiles['configmap.yaml']:
                ritem = item
                if ritem['kind'] == 'ConfigMap':
                    ritem = Object(jsonpatchext.apply_patch(ritem, [
                        {
                            'op': 'check',
                            'path': '/metadata/name',
                            'cmp': 'equals',
                            'value': 'rabbitmq-config'
                        },
                        {
                            'op': 'check',
                            'path': '/metadata/namespace',
                            'cmp': 'equals',
                            'value': 'test-rabbitmq'
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/name',
                            'value': self.object_name('config')
                        },
                        {
                            'op': 'replace',
                            'path': '/metadata/namespace',
                            'value': self.namespace()
                        },
                        {
                            'op':
                            'replace',
                            'path':
                            '/data/enabled_plugins',
                            'value':
                            LiteralStr('[{}].'.format(', '.join(
                                self.option_get('config.enabled_plugins'))))
                        },
                        {
                            'op': 'replace',
                            'path': '/data/rabbitmq.conf',
                            'value': LiteralStr(self.configfile_get())
                        },
                    ],
                                                            in_place=False),
                                   name=self.BUILDITEM_CONFIG,
                                   source=self.SOURCE_NAME,
                                   instance=self.basename())
                ret.append(ritem)

        config_secret = {}

        if not IsKData(self.option_get('config.erlang_cookie')):
            config_secret.update({
                'erlang_cookie':
                self.kubragen.secret_data_encode(
                    self.option_get('config.erlang_cookie')),
            })

        if not IsKData(self.option_get('config.admin.username')):
            config_secret.update({
                'admin.username':
                self.kubragen.secret_data_encode(
                    self.option_get('config.admin.username')),
            })

        if not IsKData(self.option_get('config.admin.password')):
            config_secret.update({
                'admin.password':
                self.kubragen.secret_data_encode(
                    self.option_get('config.admin.password')),
            })

        if not IsKData(self.option_get('config.load_definitions')):
            if self.option_get('config.load_definitions') is not None:
                config_secret.update({
                    'load_definition.json':
                    self.kubragen.secret_data_encode(
                        self.option_get('config.load_definitions')),
                })

        if len(config_secret) > 0:
            ret.append(
                Object(
                    {
                        'apiVersion': 'v1',
                        'kind': 'Secret',
                        'metadata': {
                            'name': self.object_name('config-secret'),
                            'namespace': self.namespace(),
                        },
                        'type': 'Opaque',
                        'data': config_secret,
                    },
                    name=self.BUILDITEM_CONFIG_SECRET,
                    source=self.SOURCE_NAME,
                    instance=self.basename()))

        return ret
Exemplo n.º 17
0
    def internal_build_service(self) -> Sequence[ObjectItem]:
        ret = []

        ret.extend([
            Object(
                {
                    'apiVersion': 'v1',
                    'kind': 'Service',
                    'metadata': {
                        'name': self.object_name('service-headless'),
                        'namespace': self.namespace(),
                        'labels': {
                            'app': self.object_name('pod-label-app'),
                        }
                    },
                    'spec': {
                        'clusterIP':
                        'None',
                        'ports':
                        [{
                            'port': self.option_get('config.service_port'),
                            'protocol': 'TCP',
                            'name': 'http-metrics',
                            'targetPort': 'http-metrics'
                        }],
                        'selector': {
                            'app': self.object_name('pod-label-app'),
                        }
                    }
                },
                name=self.BUILDITEM_SERVICE_HEADLESS,
                source=self.SOURCE_NAME,
                instance=self.basename()),
            Object(
                {
                    'apiVersion': 'v1',
                    'kind': 'Service',
                    'metadata': {
                        'name': self.object_name('service'),
                        'namespace': self.namespace(),
                        'labels': {
                            'app': self.object_name('pod-label-app'),
                        },
                    },
                    'spec': {
                        'type':
                        'ClusterIP',
                        'ports': [{
                            'port':
                            self.option_get('config.service_port'),
                            'protocol':
                            'TCP',
                            'name':
                            'http-metrics',
                            'targetPort':
                            'http-metrics'
                        }],
                        'selector': {
                            'app': self.object_name('pod-label-app'),
                        },
                    }
                },
                name=self.BUILDITEM_SERVICE,
                source=self.SOURCE_NAME,
                instance=self.basename()),
            Object(
                {
                    'apiVersion': 'apps/v1',
                    'kind': 'StatefulSet',
                    'metadata': {
                        'name': self.object_name('statefulset'),
                        'namespace': self.namespace(),
                        'labels': {
                            'app': self.object_name('pod-label-app'),
                        },
                    },
                    'spec': {
                        'podManagementPolicy': 'OrderedReady',
                        'replicas': 1,
                        'selector': {
                            'matchLabels': {
                                'app': self.object_name('pod-label-app'),
                            }
                        },
                        'serviceName': self.object_name('service-headless'),
                        'updateStrategy': {
                            'type': 'RollingUpdate'
                        },
                        'template': {
                            'metadata': {
                                'labels': {
                                    'app': self.object_name('pod-label-app'),
                                },
                                'annotations':
                                ValueData(
                                    {
                                        'prometheus.io/scrape':
                                        QuotedStr('true'),
                                        'prometheus.io/port':
                                        QuotedStr('http-metrics'),
                                    },
                                    enabled=self.option_get(
                                        'config.prometheus_annotation')
                                    is not False),
                            },
                            'spec': {
                                'serviceAccountName':
                                ValueData(self.option_get(
                                    'config.authorization.serviceaccount_use'),
                                          disabled_if_none=True),
                                'securityContext': {
                                    'fsGroup': 10001,
                                    'runAsGroup': 10001,
                                    'runAsNonRoot': True,
                                    'runAsUser': 10001
                                },
                                'containers': [{
                                    'name':
                                    'loki',
                                    'image':
                                    self.option_get('container.loki'),
                                    'args':
                                    ['-config.file=/etc/loki/loki.yaml'],
                                    'volumeMounts': [{
                                        'name': 'config',
                                        'mountPath': '/etc/loki'
                                    }, {
                                        'name': 'storage',
                                        'mountPath': '/data',
                                        'subPath': None
                                    }],
                                    'ports': [{
                                        'name': 'http-metrics',
                                        'containerPort': 3100,
                                        'protocol': 'TCP'
                                    }],
                                    'livenessProbe': {
                                        'httpGet': {
                                            'path': '/ready',
                                            'port': 'http-metrics'
                                        },
                                        'initialDelaySeconds': 45
                                    },
                                    'readinessProbe': {
                                        'httpGet': {
                                            'path': '/ready',
                                            'port': 'http-metrics'
                                        },
                                        'initialDelaySeconds': 45
                                    },
                                    'securityContext': {
                                        'readOnlyRootFilesystem': True
                                    },
                                    'resources':
                                    ValueData(value=self.option_get(
                                        'kubernetes.resources.statefulset'),
                                              disabled_if_none=True),
                                }],
                                'terminationGracePeriodSeconds':
                                4800,
                                'volumes': [{
                                    'name': 'config',
                                    'secret': {
                                        'secretName':
                                        self.object_name('config-secret'),
                                        'items': [{
                                            'key': 'loki.yaml',
                                            'path': 'loki.yaml',
                                        }]
                                    }
                                },
                                            KDataHelper_Volume.info(
                                                base_value={
                                                    'name': 'storage',
                                                },
                                                value=self.option_get(
                                                    'kubernetes.volumes.data'))
                                            ]
                            }
                        }
                    }
                },
                name=self.BUILDITEM_STATEFULSET,
                source=self.SOURCE_NAME,
                instance=self.basename()),
        ])

        return ret
Exemplo n.º 18
0
    def internal_build_service(self) -> Sequence[ObjectItem]:
        ret = []

        ret.extend([
            Object(
                {
                    'kind': 'Service',
                    'apiVersion': 'v1',
                    'metadata': {
                        'name': self.object_name('elasticsearch-service'),
                        'namespace': self.namespace(),
                        'labels': {
                            'app':
                            self.object_name('elasticsearch-pod-label-app'),
                        }
                    },
                    'spec': {
                        'selector': {
                            'app':
                            self.object_name('elasticsearch-pod-label-app'),
                        },
                        'clusterIP':
                        'None',
                        'ports': [{
                            'port': 9200,
                            'name': 'rest'
                        }, {
                            'port': 9300,
                            'name': 'inter-node'
                        }],
                    }
                },
                name=self.BUILDITEM_ELASTICSEARCH_SERVICE,
                source=self.SOURCE_NAME,
                instance=self.basename()),
            Object(
                {
                    'apiVersion': 'apps/v1',
                    'kind': 'StatefulSet',
                    'metadata': {
                        'name': self.object_name('elasticsearch-statefulset'),
                        'namespace': self.namespace(),
                    },
                    'spec': {
                        'serviceName':
                        self.object_name('elasticsearch-service'),
                        'replicas':
                        self.option_get('config.elasticsearch.replicas'),
                        'selector': {
                            'matchLabels': {
                                'app':
                                self.object_name(
                                    'elasticsearch-pod-label-app'),
                            }
                        },
                        'template': {
                            'metadata': {
                                'labels': {
                                    'app':
                                    self.object_name(
                                        'elasticsearch-pod-label-app'),
                                }
                            },
                            'spec': {
                                'volumes': [
                                    KDataHelper_Volume.info(
                                        base_value={
                                            'name': 'data',
                                        },
                                        value=self.option_get(
                                            'kubernetes.volumes.elasticsearch-data'
                                        )),
                                ],
                                'containers': [{
                                    'name':
                                    'elasticsearch',
                                    'image':
                                    self.option_get('container.elasticsearch'),
                                    'ports': [{
                                        'containerPort': 9200,
                                        'name': 'rest',
                                        'protocol': 'TCP'
                                    }, {
                                        'containerPort': 9300,
                                        'name': 'inter-node',
                                        'protocol': 'TCP'
                                    }],
                                    'volumeMounts': [{
                                        'name':
                                        'data',
                                        'mountPath':
                                        '/usr/share/elasticsearch/data'
                                    }],
                                    'env': [{
                                        'name':
                                        'cluster.name',
                                        'value':
                                        self.object_name(
                                            'elasticsearch-statefulset'),
                                    }, {
                                        'name': 'NODE_NAME',
                                        'valueFrom': {
                                            'fieldRef': {
                                                'fieldPath': 'metadata.name'
                                            }
                                        },
                                    }, {
                                        'name':
                                        'node.name',
                                        'value':
                                        QuotedStr('$(NODE_NAME).{}'.format(
                                            self.object_name(
                                                'elasticsearch-service'))),
                                    }, {
                                        'name':
                                        'discovery.seed_hosts',
                                        'value':
                                        ','.join([
                                            '{}-{}.{}'.format(
                                                self.object_name(
                                                    'elasticsearch-statefulset'
                                                ), rpl,
                                                self.object_name(
                                                    'elasticsearch-service'))
                                            for rpl in range(
                                                self.option_get(
                                                    'config.elasticsearch.replicas'
                                                ))
                                        ]),
                                    }, {
                                        'name':
                                        'cluster.initial_master_nodes',
                                        'value':
                                        ','.join([
                                            '{}-{}.{}'.format(
                                                self.object_name(
                                                    'elasticsearch-statefulset'
                                                ), rpl,
                                                self.object_name(
                                                    'elasticsearch-service'))
                                            for rpl in range(
                                                self.option_get(
                                                    'config.elasticsearch.replicas'
                                                ))
                                        ]),
                                    }, {
                                        'name': 'ES_JAVA_OPTS',
                                        'value': '-Xms512m '
                                        '-Xmx512m'
                                    }],
                                    'resources':
                                    ValueData(value=self.option_get(
                                        'kubernetes.resources.elasticsearch-statefulset'
                                    ),
                                              disabled_if_none=True),
                                }],
                                'initContainers': [{
                                    'name':
                                    'fix-permissions',
                                    'image':
                                    'busybox',
                                    'command': [
                                        'sh', '-c', 'chown -R '
                                        '1000:1000 '
                                        '/usr/share/elasticsearch/data'
                                    ],
                                    'securityContext': {
                                        'privileged': True
                                    },
                                    'volumeMounts': [{
                                        'name':
                                        'data',
                                        'mountPath':
                                        '/usr/share/elasticsearch/data'
                                    }],
                                }, {
                                    'name':
                                    'increase-vm-max-map',
                                    'image':
                                    'busybox',
                                    'command': [
                                        'sysctl', '-w',
                                        'vm.max_map_count=262144'
                                    ],
                                    'securityContext': {
                                        'privileged': True
                                    },
                                }, {
                                    'name':
                                    'increase-fd-ulimit',
                                    'image':
                                    'busybox',
                                    'command':
                                    ['sh', '-c', 'ulimit -n '
                                     '65536'],
                                    'securityContext': {
                                        'privileged': True
                                    },
                                }]
                            }
                        },
                    }
                },
                name=self.BUILDITEM_ELASTICSEARCH_STATEFULSET,
                source=self.SOURCE_NAME,
                instance=self.basename()),
            Object(
                {
                    'apiVersion': 'apps/v1',
                    'kind': 'DaemonSet',
                    'metadata': {
                        'name': self.object_name('fluentd-daemonset'),
                        'namespace': self.namespace(),
                        'labels': {
                            'app': self.object_name('fluentd-pod-label-app'),
                        }
                    },
                    'spec': {
                        'selector': {
                            'matchLabels': {
                                'app':
                                self.object_name('fluentd-pod-label-app'),
                            }
                        },
                        'template': {
                            'metadata': {
                                'labels': {
                                    'app':
                                    self.object_name('fluentd-pod-label-app'),
                                }
                            },
                            'spec': {
                                'serviceAccount':
                                self.object_name('service-account'),
                                'serviceAccountName':
                                self.object_name('service-account'),
                                'tolerations': [{
                                    'key': 'node-role.kubernetes.io/master',
                                    'effect': 'NoSchedule'
                                }],
                                'containers': [{
                                    'name':
                                    'fluentd',
                                    'image':
                                    self.option_get('container.fluentd'),
                                    'env': [
                                        {
                                            'name':
                                            'FLUENT_ELASTICSEARCH_HOST',
                                            'value':
                                            '{}.{}.svc.cluster.local'.format(
                                                self.object_name(
                                                    'elasticsearch-service'),
                                                self.namespace()),
                                        }, {
                                            'name':
                                            'FLUENT_ELASTICSEARCH_PORT',
                                            'value': '9200'
                                        }, {
                                            'name':
                                            'FLUENT_ELASTICSEARCH_SCHEME',
                                            'value': 'http'
                                        }, {
                                            'name': 'FLUENTD_SYSTEMD_CONF',
                                            'value': 'disable'
                                        },
                                        ValueData(value={
                                            'name':
                                            'FLUENT_CONTAINER_TAIL_PARSER_TYPE',
                                            'value':
                                            '/^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/',
                                        },
                                                  enabled=self.kubragen.
                                                  provider.provider
                                                  == PROVIDER_K3D
                                                  or self.kubragen.provider.
                                                  provider == PROVIDER_K3S)
                                    ],
                                    'volumeMounts': [{
                                        'name': 'varlog',
                                        'mountPath': '/var/log'
                                    }, {
                                        'name': 'varlibdockercontainers',
                                        'mountPath':
                                        '/var/lib/docker/containers',
                                        'readOnly': True
                                    }],
                                    'resources':
                                    ValueData(value=self.option_get(
                                        'kubernetes.resources.fluentd-daemonset'
                                    ),
                                              disabled_if_none=True),
                                }],
                                'terminationGracePeriodSeconds':
                                30,
                                'volumes': [{
                                    'name': 'varlog',
                                    'hostPath': {
                                        'path': '/var/log'
                                    }
                                }, {
                                    'name': 'varlibdockercontainers',
                                    'hostPath': {
                                        'path': '/var/lib/docker/containers'
                                    }
                                }]
                            }
                        }
                    }
                },
                name=self.BUILDITEM_FLUENTD_DAEMONSET,
                source=self.SOURCE_NAME,
                instance=self.basename()),
        ])

        if self.option_get('enable.kibana'):
            ret.extend([
                Object(
                    {
                        'apiVersion': 'v1',
                        'kind': 'Service',
                        'metadata': {
                            'name': self.object_name('kibana-service'),
                            'namespace': self.namespace(),
                            'labels': {
                                'app':
                                self.object_name('kibana-pod-label-app'),
                            },
                        },
                        'spec': {
                            'ports': [{
                                'port':
                                self.option_get('config.kibana.service_port'),
                                'targetPort':
                                5601,
                            }],
                            'selector': {
                                'app':
                                self.object_name('kibana-pod-label-app'),
                            }
                        }
                    },
                    name=self.BUILDITEM_KIBANA_SERVICE,
                    source=self.SOURCE_NAME,
                    instance=self.basename()),
                Object(
                    {
                        'apiVersion': 'apps/v1',
                        'kind': 'Deployment',
                        'metadata': {
                            'name': self.object_name('kibana-deployment'),
                            'namespace': self.namespace(),
                            'labels': {
                                'app':
                                self.object_name('kibana-pod-label-app'),
                            }
                        },
                        'spec': {
                            # 'replicas': 1,
                            'selector': {
                                'matchLabels': {
                                    'app':
                                    self.object_name('kibana-pod-label-app'),
                                }
                            },
                            'template': {
                                'metadata': {
                                    'labels': {
                                        'app':
                                        self.object_name(
                                            'kibana-pod-label-app'),
                                    }
                                },
                                'spec': {
                                    'containers': [{
                                        'name':
                                        'kibana',
                                        'image':
                                        self.option_get('container.kibana'),
                                        'env': [{
                                            'name':
                                            'ELASTICSEARCH_HOSTS',
                                            'value':
                                            'http://{}:9200'.format(
                                                self.object_name(
                                                    'elasticsearch-service')),
                                        }],
                                        'ports': [{
                                            'containerPort': 5601
                                        }],
                                        'livenessProbe':
                                        ValueData(value={
                                            'httpGet': {
                                                'path': '/api/status',
                                                'port': 5601,
                                            },
                                            'initialDelaySeconds': 30,
                                            'timeoutSeconds': 20,
                                        },
                                                  enabled=self.option_get(
                                                      'config.probes')),
                                        'readinessProbe':
                                        ValueData(value={
                                            'httpGet': {
                                                'path': '/api/status',
                                                'port': 5601,
                                            },
                                            'initialDelaySeconds': 30,
                                            'timeoutSeconds': 20,
                                        },
                                                  enabled=self.option_get(
                                                      'config.probes')),
                                        'resources':
                                        ValueData(value=self.option_get(
                                            'kubernetes.resources.kibana-deployment'
                                        ),
                                                  disabled_if_none=True),
                                    }]
                                }
                            }
                        }
                    },
                    name=self.BUILDITEM_KIBANA_DEPLOYMENT,
                    source=self.SOURCE_NAME,
                    instance=self.basename()),
            ])

        return ret
Exemplo n.º 19
0
    def internal_build_service(self) -> Sequence[ObjectItem]:
        ret = [
            Object(
                {
                    'apiVersion': 'apps/v1',
                    'kind': 'Deployment',
                    'metadata': {
                        'name': self.object_name('deployment'),
                        'namespace': self.namespace(),
                        'labels': {
                            'app': self.object_name('pod-label-app'),
                        },
                    },
                    'spec': {
                        'replicas': 1,
                        'selector': {
                            'matchLabels': {
                                'app': self.object_name('pod-label-app'),
                            }
                        },
                        'template': {
                            'metadata': {
                                'labels': {
                                    'app': self.object_name('pod-label-app'),
                                }
                            },
                            'spec': {
                                'serviceAccountName':
                                self.object_name('service-account'),
                                'containers': [{
                                    'name':
                                    'kube-resource-report',
                                    'image':
                                    self.option_get(
                                        'container.kube-resource-report'),
                                    'args': [
                                        '--update-interval-minutes=1',
                                        '--additional-cost-per-cluster=30.0',
                                        '/output'
                                    ],
                                    'volumeMounts': [{
                                        'mountPath': '/output',
                                        'name': 'report-data'
                                    }],
                                    'securityContext': {
                                        'readOnlyRootFilesystem': True,
                                        'runAsNonRoot': True,
                                        'runAsUser': 1000
                                    },
                                    'resources':
                                    ValueData(value=self.option_get(
                                        'kubernetes.resources.deployment'),
                                              disabled_if_none=True),
                                }, {
                                    'name':
                                    'nginx',
                                    'image':
                                    self.option_get('container.nginx'),
                                    'volumeMounts': [{
                                        'mountPath': '/usr/share/nginx/html',
                                        'name': 'report-data',
                                        'readOnly': True
                                    }],
                                    'ports': [{
                                        'containerPort': 80
                                    }],
                                    'readinessProbe': {
                                        'httpGet': {
                                            'path': '/',
                                            'port': 80
                                        }
                                    },
                                    'resources':
                                    ValueData(value=self.option_get(
                                        'kubernetes.resources.deployment-nginx'
                                    ),
                                              disabled_if_none=True),
                                }],
                                'volumes': [{
                                    'name': 'report-data',
                                    'emptyDir': {
                                        'sizeLimit': '500Mi'
                                    }
                                }]
                            }
                        }
                    }
                },
                name=self.BUILDITEM_DEPLOYMENT,
                source=self.SOURCE_NAME,
                instance=self.basename()),
            Object(
                {
                    'apiVersion': 'v1',
                    'kind': 'Service',
                    'metadata': {
                        'name': self.object_name('service'),
                        'namespace': self.namespace(),
                        'labels': {
                            'app': self.object_name('pod-label-app'),
                        },
                    },
                    'spec': {
                        'selector': {
                            'app': self.object_name('pod-label-app'),
                        },
                        'type':
                        'ClusterIP',
                        'ports': [
                            {
                                'name': 'kube-resource-report-frontend',
                                'port': self.option_get('config.service_port'),
                                'protocol': 'TCP',
                                'targetPort': 80
                            }
                        ]
                    }
                },
                name=self.BUILDITEM_SERVICE,
                source=self.SOURCE_NAME,
                instance=self.basename()),
        ]

        return ret
Exemplo n.º 20
0
    def internal_build_accesscontrol(self) -> Sequence[ObjectItem]:
        ret = []

        if self.option_get(
                'config.authorization.serviceaccount_create') is not False:
            ret.extend([
                Object(
                    {
                        'apiVersion': 'v1',
                        'kind': 'ServiceAccount',
                        'metadata': {
                            'name': self.object_name('service-account'),
                            'namespace': self.namespace(),
                        }
                    },
                    name=self.BUILDITEM_SERVICE_ACCOUNT,
                    source=self.SOURCE_NAME,
                    instance=self.basename())
            ])

        if self.option_get('config.authorization.roles_create') is not False:
            ret.extend([
                Object(
                    {
                        'kind':
                        'ClusterRole',
                        'apiVersion':
                        'rbac.authorization.k8s.io/v1',
                        'metadata': {
                            'name': self.object_name('cluster-role'),
                        },
                        'rules': [{
                            'apiGroups': [''],
                            'resources':
                            ['nodes', 'pods', 'namespaces', 'services'],
                            'verbs': ['get', 'list']
                        }, {
                            'apiGroups': ['networking.k8s.io'],
                            'resources': ['ingresses'],
                            'verbs': ['list']
                        }, {
                            'apiGroups': ['metrics.k8s.io'],
                            'resources': ['nodes', 'pods'],
                            'verbs': ['get', 'list']
                        }, {
                            'apiGroups': [''],
                            'resources': ['services/proxy'],
                            'resourceNames': ['heapster'],
                            'verbs': ['get']
                        }, {
                            'apiGroups': ['autoscaling.k8s.io'],
                            'resources': ['verticalpodautoscalers'],
                            'verbs': ['get', 'list']
                        }, {
                            'apiGroups': ['apps'],
                            'resources': [
                                'deployments', 'statefulsets', 'replicasets',
                                'daemonsets'
                            ],
                            'verbs': ['get', 'list']
                        }]
                    },
                    name=self.BUILDITEM_CLUSTER_ROLE,
                    source=self.SOURCE_NAME,
                    instance=self.basename())
            ])

        if self.option_get('config.authorization.roles_bind') is not False:
            ret.extend([
                Object(
                    {
                        'apiVersion':
                        'rbac.authorization.k8s.io/v1',
                        'kind':
                        'ClusterRoleBinding',
                        'metadata': {
                            'name': self.object_name('cluster-role-binding'),
                        },
                        'roleRef': {
                            'apiGroup': 'rbac.authorization.k8s.io',
                            'kind': 'ClusterRole',
                            'name': self.object_name('cluster-role'),
                        },
                        'subjects':
                        [{
                            'kind': 'ServiceAccount',
                            'name': self.object_name('service-account'),
                            'namespace': self.namespace(),
                        }]
                    },
                    name=self.BUILDITEM_CLUSTER_ROLE_BINDING,
                    source=self.SOURCE_NAME,
                    instance=self.basename())
            ])

        return ret
Exemplo n.º 21
0
    def internal_build_service(self) -> Sequence[ObjectItem]:
        ret = []

        ret.extend([
            Object(
                {
                    'apiVersion': 'apps/v1',
                    'kind': 'DaemonSet',
                    'metadata': {
                        'name': self.object_name('daemonset'),
                        'namespace': self.namespace(),
                        'labels': {
                            'app': self.object_name('pod-label-app'),
                        },
                    },
                    'spec': {
                        'selector': {
                            'matchLabels': {
                                'app': self.object_name('pod-label-app'),
                            }
                        },
                        'template': {
                            'metadata': {
                                'labels': {
                                    'app': self.object_name('pod-label-app'),
                                },
                                'annotations':
                                ValueData(
                                    {
                                        'prometheus.io/scrape':
                                        QuotedStr('true'),
                                        'prometheus.io/port':
                                        QuotedStr('http-metrics'),
                                    },
                                    enabled=self.option_get(
                                        'config.prometheus_annotation')
                                    is not False),
                            },
                            'spec': {
                                'serviceAccountName':
                                self.object_name('service-account'),
                                'containers': [{
                                    'name':
                                    'promtail',
                                    'image':
                                    self.option_get('container.promtail'),
                                    'args': [
                                        '-config.file=/etc/promtail/promtail.yaml',
                                        ValueData(
                                            '-client.url={}/loki/api/v1/push'.
                                            format(
                                                self.option_get(
                                                    'config.loki_url')),
                                            enabled=self.option_get(
                                                'config.loki_url')
                                            is not None),
                                    ],
                                    'volumeMounts': [
                                        {
                                            'name': 'config',
                                            'mountPath': '/etc/promtail'
                                        }, {
                                            'name': 'run',
                                            'mountPath': '/run/promtail'
                                        }, {
                                            'mountPath':
                                            '/var/lib/docker/containers',
                                            'name': 'docker',
                                            'readOnly': True
                                        }, {
                                            'mountPath': '/var/log/pods',
                                            'name': 'pods',
                                            'readOnly': True
                                        }
                                    ],
                                    'env': [{
                                        'name': 'HOSTNAME',
                                        'valueFrom': {
                                            'fieldRef': {
                                                'fieldPath': 'spec.nodeName'
                                            }
                                        },
                                    }],
                                    'ports': [{
                                        'containerPort': 3101,
                                        'name': 'http-metrics'
                                    }],
                                    'securityContext': {
                                        'readOnlyRootFilesystem': True,
                                        'runAsGroup': 0,
                                        'runAsUser': 0
                                    },
                                    'readinessProbe': {
                                        'failureThreshold': 5,
                                        'httpGet': {
                                            'path': '/ready',
                                            'port': 'http-metrics'
                                        },
                                        'initialDelaySeconds': 10,
                                        'periodSeconds': 10,
                                        'successThreshold': 1,
                                        'timeoutSeconds': 1
                                    },
                                    'resources':
                                    ValueData(value=self.option_get(
                                        'kubernetes.resources.daemonset'),
                                              disabled_if_none=True),
                                }],
                                'tolerations': [{
                                    'effect': 'NoSchedule',
                                    'key': 'node-role.kubernetes.io/master',
                                    'operator': 'Exists'
                                }],
                                'volumes': [{
                                    'name': 'config',
                                    'configMap': {
                                        'name':
                                        self.object_name('config'),
                                        'items': [{
                                            'key': 'promtail.yaml',
                                            'path': 'promtail.yaml',
                                        }]
                                    }
                                }, {
                                    'name': 'run',
                                    'hostPath': {
                                        'path': '/run/promtail'
                                    }
                                }, {
                                    'hostPath': {
                                        'path': '/var/lib/docker/containers'
                                    },
                                    'name': 'docker'
                                }, {
                                    'hostPath': {
                                        'path': '/var/log/pods'
                                    },
                                    'name': 'pods'
                                }]
                            }
                        }
                    }
                },
                name=self.BUILDITEM_DAEMONSET,
                source=self.SOURCE_NAME,
                instance=self.basename()),
        ])

        return ret