hybrid logging 52/1052/4
authorbborbely <botond.borbely@nokia.com>
Tue, 25 Jun 2019 11:12:14 +0000 (13:12 +0200)
committerbborbely <botond.borbely@nokia.com>
Wed, 26 Jun 2019 10:38:58 +0000 (12:38 +0200)
Change-Id: I55274e2c2be1b6cecb2151305e053fca16606d04

recuserconfighandlers/reccaashandler/reccaashandler.py [new file with mode: 0644]
validators/src/CaasValidation.py

diff --git a/recuserconfighandlers/reccaashandler/reccaashandler.py b/recuserconfighandlers/reccaashandler/reccaashandler.py
new file mode 100644 (file)
index 0000000..8c98d58
--- /dev/null
@@ -0,0 +1,42 @@
+#! /usr/bin/python
+# Copyright 2019 Nokia
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from cmframework.apis import cmuserconfig
+from cmframework.apis import cmerror
+from cmdatahandlers.api import configerror
+
+"""
+This plugin is used to handle REC specific infra logging configs. Currently
+its sole purpose is to set the default plugin (elasticsearch) for internal logging.
+"""
+
+
+class reccaashandler(cmuserconfig.CMUserConfigPlugin):
+
+    def __init__(self):
+        super(reccaashandler, self).__init__()
+
+    def handle(self, confman):
+        try:
+            self._set_default_infra_log_store(confman)
+        except configerror.ConfigError as exp:
+            raise cmerror.CMError(str(exp))
+
+    @staticmethod
+    def _set_default_infra_log_store(confman):
+        root = 'cloud.caas'
+        log_conf = confman.get_caas_handler()
+        if not log_conf.get_caas_parameter('infra_log_store'):
+            log_conf.config[root]['infra_log_store'] = 'elasticsearch'
index e72a598..b8e02fc 100644 (file)
@@ -92,6 +92,14 @@ class CaasValidation(cmvalidator.CMValidator):
     CLUSTER_NETS = 'cluster_networks'
     TENANT_NETS = 'tenant_networks'
 
+    BLOG_FORWARDING = "infra_log_store"
+    LOG_FORWARDING = "log_forwarding"
+    URL_PORT_PATTERN = r"^(?:https?|udp|tcp):(?:\/\/)(?:((?:[\w\.-]+|" \
+                       r"\[(([1-9a-f][0-9a-f]{0,3}|\:)\:[1-9a-f][0-9a-f]{0,3}){0,7}\])\:[0-9]+))"
+    FLUENTD_PLUGINS = ['elasticsearch', 'remote_syslog']
+    INFRA_LOG_FLUENTD_PLUGINS = ['elasticsearch', 'remote_syslog']
+    LOG_FW_STREAM = ['stdout', 'stderr', 'both']
+
     def __init__(self):
         cmvalidator.CMValidator.__init__(self)
         self.validation_utils = validation.ValidationUtils()
@@ -114,6 +122,7 @@ class CaasValidation(cmvalidator.CMValidator):
         self.validate_instantiation_timeout()
         self.validate_encrypted_ca(self.ENCRYPTED_CA)
         self.validate_encrypted_ca(self.ENCRYPTED_CA_KEY)
+        self.validate_log_forwarding()
         self.validate_networks(props)
 
     def _get_conf(self, props, domain):
@@ -197,6 +206,52 @@ class CaasValidation(cmvalidator.CMValidator):
         except TypeError as exc:
             raise CaasValidationError('Invalid {}: {}'.format(enc_ca, exc))
 
+    def validate_log_forwarding(self):
+        # pylint: disable=too-many-branches
+        if self.caas_utils.is_optional_param_present(self.BLOG_FORWARDING, self.caas_conf):
+            if self.caas_conf[self.BLOG_FORWARDING] not in self.INFRA_LOG_FLUENTD_PLUGINS:
+                raise CaasValidationError('"{}" property not valid! '
+                                          'Choose from {}!'.format(self.BLOG_FORWARDING,
+                                                                   self.INFRA_LOG_FLUENTD_PLUGINS))
+        if self.caas_utils.is_optional_param_present(self.LOG_FORWARDING, self.caas_conf):
+            log_fw_list = self.caas_conf[self.LOG_FORWARDING]
+            if log_fw_list:
+                url_d = dict()
+                url_s = set()
+                for list_item in log_fw_list:
+                    self.caas_utils.check_key_in_dict('namespace', list_item)
+                    if list_item['namespace'] == 'kube-system':
+                        raise CaasValidationError(
+                            'You can\'t set "kube-system" as namespace in "{}"!'.format(
+                                self.LOG_FORWARDING))
+                    self.caas_utils.check_key_in_dict('target_url', list_item)
+                    if not list_item['target_url'] or not re.match(self.URL_PORT_PATTERN,
+                                                                   list_item['target_url']):
+                        raise CaasValidationError(
+                            '"target_url" property {} not valid!'.format(list_item['target_url']))
+                    if not url_d:
+                        url_d[list_item['namespace']] = list_item['target_url']
+                    if list_item['namespace'] in url_d:
+                        if list_item['target_url'] in url_s:
+                            raise CaasValidationError('There can\'t be multiple rules for the same '
+                                                      'target_url for the same {} '
+                                                      'namespace!'.format(list_item['namespace']))
+                        else:
+                            url_s.add(list_item['target_url'])
+                        url_d[list_item['namespace']] = url_s
+                    else:
+                        url_d[list_item['namespace']] = list_item['target_url']
+                    if self.caas_utils.is_optional_param_present('plugin', list_item) and list_item[
+                        'plugin'] not in self.FLUENTD_PLUGINS:
+                        raise CaasValidationError(
+                            '"plugin" property not valid! Choose from {}'.format(
+                                self.FLUENTD_PLUGINS))
+                    if self.caas_utils.is_optional_param_present('stream', list_item) and list_item[
+                        'stream'] not in self.LOG_FW_STREAM:
+                        raise CaasValidationError(
+                            '"stream" property not valid! Choose from {}'.format(
+                                self.LOG_FW_STREAM))
+
     def validate_networks(self, props):
         caas_nets = []
         for nets_key in [self.CLUSTER_NETS, self.TENANT_NETS]: