Ejemplo n.º 1
0
def load_config(filename,
                path="calico/felix/test/data/",
                env_dict=None,
                host_dict=None,
                global_dict=None):
    if env_dict is None:
        env_dict = {}
    if host_dict is None:
        host_dict = {}
    if global_dict is None:
        global_dict = {}

    global_dict.setdefault("InterfacePrefix", "tap")

    with mock.patch.dict("os.environ", env_dict):
        with mock.patch('calico.common.complete_logging'):
            config = Config()

    combined_dict = global_dict.copy()
    combined_dict.update(host_dict)

    with mock.patch('calico.common.complete_logging'):
        config.update_from(combined_dict)

    return config
Ejemplo n.º 2
0
    def test_default_config(self):
        """
        Test various ways of defaulting config.
        """
        files = [
            "felix_missing.cfg",  # does not exist
            "felix_empty.cfg",  # empty file
            "felix_empty_section.cfg",  # file with empty section
            "felix_extra.cfg",  # extra config is just logged
        ]

        for filename in files:
            with mock.patch('calico.common.complete_logging'):
                config = Config("calico/felix/test/data/%s" % filename)
            host_dict = {"InterfacePrefix": "blah", "MetadataPort": 123}
            global_dict = {
                "InterfacePrefix": "overridden",
                "MetadataAddr": "1.2.3.4"
            }
            with mock.patch('calico.common.complete_logging'):
                config.report_etcd_config(host_dict, global_dict)

            # Test defaulting.
            self.assertEqual(config.ETCD_ADDR, "localhost:4001")
            self.assertEqual(config.HOSTNAME, socket.gethostname())
            self.assertEqual(config.IFACE_PREFIX, "blah")
            self.assertEqual(config.METADATA_PORT, 123)
            self.assertEqual(config.METADATA_IP, "1.2.3.4")
            self.assertEqual(config.REPORTING_INTERVAL_SECS, 30)
            self.assertEqual(config.REPORTING_TTL_SECS, 90)
Ejemplo n.º 3
0
    def test_env_var_override(self):
        """
        Test environment variables override config options,
        """
        with mock.patch.dict("os.environ", {"FELIX_ETCDADDR": "9.9.9.9:1234",
                                            "FELIX_METADATAPORT": "999"}):
            config = Config("calico/felix/test/data/felix_section.cfg")

        host_dict = { "InterfacePrefix": "blah",
                      "StartupCleanupDelay": "42",
                      "MetadataAddr": "4.3.2.1",
                      "MetadataPort": "123" }

        global_dict = { "InterfacePrefix": "blah",
                        "StartupCleanupDelay": "99",
                        "MetadataAddr": "5.4.3.2",
                        "MetadataPort": "123" }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config(host_dict, global_dict)

        self.assertEqual(config.ETCD_ADDR, "9.9.9.9:1234")
        self.assertEqual(config.HOSTNAME, socket.gethostname())
        self.assertEqual(config.LOGFILE, "/log/nowhere.log")
        self.assertEqual(config.IFACE_PREFIX, "whatever")
        self.assertEqual(config.METADATA_PORT, 999)
        self.assertEqual(config.METADATA_IP, "1.2.3.4")
        self.assertEqual(config.STARTUP_CLEANUP_DELAY, 42)
Ejemplo n.º 4
0
 def test_ip_in_ip_enabled(self):
     test_values = [
         ("true", True),
         ("t", True),
         ("True", True),
         ("1", True),
         (1, True),
         ("yes", True),
         ("y", True),
         ("false", False),
         ("f", False),
         ("False", False),
         ("0", False),
         (0, False),
         ("no", False),
         ("n", False),
     ]
     for value, expected in test_values:
         with mock.patch('calico.common.complete_logging'):
             config = Config("calico/felix/test/data/felix_missing.cfg")
             cfg_dict = { "InterfacePrefix": "blah",
                          "IpInIpEnabled": value }
             config.report_etcd_config({}, cfg_dict)
             self.assertEqual(config.IP_IN_IP_ENABLED, expected,
                              "%r was mis-interpreted as %r" %
                              (value, config.IP_IN_IP_ENABLED))
Ejemplo n.º 5
0
 def test_no_iface_prefix(self):
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = {}
     with self.assertRaisesRegexp(ConfigException,
                     "Missing undefaulted value.*InterfacePrefix"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 6
0
    def test_default_config(self):
        """
        Test various ways of defaulting config.
        """
        files = [ "felix_missing.cfg", # does not exist
                  "felix_empty.cfg", # empty file
                  "felix_empty_section.cfg", # file with empty section
                  "felix_extra.cfg", # extra config is just logged
                  ]

        for filename in files:
            host = socket.gethostname()
            host_path = "/calico/host/%s/config/" % host


            config = Config("calico/felix/test/data/%s" % filename)
            cfg_dict = { "InterfacePrefix": "blah",
                         "ExtraJunk": "whatever", #ignored
                         "ResyncIntervalSecs": "123" }
            config.update_config(cfg_dict)

            # Test defaulting.
            self.assertEqual(config.ETCD_ADDR, "localhost:4001")
            self.assertEqual(config.HOSTNAME, host)
            self.assertEqual(config.IFACE_PREFIX, "blah")
            self.assertEqual(config.RESYNC_INT_SEC, 123)
Ejemplo n.º 7
0
    def test_default_config(self):
        """
        Test various ways of defaulting config.
        """
        files = [ "felix_missing.cfg", # does not exist
                  "felix_empty.cfg", # empty file
                  "felix_empty_section.cfg", # file with empty section
                  "felix_extra.cfg", # extra config is just logged
                  ]

        for filename in files:
            config = Config("calico/felix/test/data/%s" % filename)
            host_dict = { "InterfacePrefix": "blah",
                          "MetadataPort": 123 }
            global_dict = { "InterfacePrefix": "overridden",
                            "MetadataAddr": "1.2.3.4" }
            with mock.patch('calico.common.complete_logging'):
                config.report_etcd_config(host_dict, global_dict)

            # Test defaulting.
            self.assertEqual(config.ETCD_ADDR, "localhost:4001")
            self.assertEqual(config.HOSTNAME, socket.gethostname())
            self.assertEqual(config.IFACE_PREFIX, "blah")
            self.assertEqual(config.METADATA_PORT, 123)
            self.assertEqual(config.METADATA_IP, "1.2.3.4")
Ejemplo n.º 8
0
    def test_env_var_override(self):
        """
        Test environment variables override config options,
        """
        with mock.patch.dict("os.environ", {
                "FELIX_ETCDADDR": "9.9.9.9:1234",
                "FELIX_METADATAPORT": "999"
        }):
            with mock.patch('calico.common.complete_logging'):
                config = Config("calico/felix/test/data/felix_section.cfg")

        host_dict = {
            "InterfacePrefix": "blah",
            "StartupCleanupDelay": "42",
            "MetadataAddr": "4.3.2.1",
            "MetadataPort": "123"
        }

        global_dict = {
            "InterfacePrefix": "blah",
            "StartupCleanupDelay": "99",
            "MetadataAddr": "5.4.3.2",
            "MetadataPort": "123"
        }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config(host_dict, global_dict)

        self.assertEqual(config.ETCD_ADDR, "9.9.9.9:1234")
        self.assertEqual(config.HOSTNAME, socket.gethostname())
        self.assertEqual(config.LOGFILE, "/log/nowhere.log")
        self.assertEqual(config.IFACE_PREFIX, "whatever")
        self.assertEqual(config.METADATA_PORT, 999)
        self.assertEqual(config.METADATA_IP, "1.2.3.4")
        self.assertEqual(config.STARTUP_CLEANUP_DELAY, 42)
Ejemplo n.º 9
0
 def test_no_iface_prefix(self):
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = {}
     with self.assertRaisesRegexp(
             ConfigException, "Missing undefaulted value.*InterfacePrefix"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 10
0
 def test_ip_in_ip_enabled(self):
     test_values = [
         ("true", True),
         ("t", True),
         ("True", True),
         ("1", True),
         (1, True),
         ("yes", True),
         ("y", True),
         ("false", False),
         ("f", False),
         ("False", False),
         ("0", False),
         (0, False),
         ("no", False),
         ("n", False),
     ]
     for value, expected in test_values:
         with mock.patch('calico.common.complete_logging'):
             config = Config("calico/felix/test/data/felix_missing.cfg")
             cfg_dict = {"InterfacePrefix": "blah", "IpInIpEnabled": value}
             config.report_etcd_config({}, cfg_dict)
             self.assertEqual(
                 config.IP_IN_IP_ENABLED, expected,
                 "%r was mis-interpreted as %r" %
                 (value, config.IP_IN_IP_ENABLED))
Ejemplo n.º 11
0
 def test_blank_metadata_addr(self):
     config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = { "InterfacePrefix": "blah",
                  "MetadataAddr": "",
                  "MetadataPort": "123" }
     with self.assertRaisesRegexp(ConfigException,
                                  "Blank value.*MetadataAddr"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 12
0
 def test_metadata_port_not_int(self):
     config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = { "InterfacePrefix": "blah",
                  "MetadataAddr": "127.0.0.1",
                  "MetadataPort": "bloop" }
     with self.assertRaisesRegexp(ConfigException,
                                  "Field was not integer.*MetadataPort"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 13
0
 def test_ip_in_ip_enabled_bad(self):
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = {"InterfacePrefix": "blah", "IpInIpEnabled": "blah"}
     with self.assertRaisesRegexp(
             ConfigException, "Field was not a valid Boolean"
             ".*IpInIpEnabled"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 14
0
    def test_bad_log_level(self):
        for field in ("LogSeverityFile", "LogSeverityScreen", "LogSeveritySys"):
            config = Config("calico/felix/test/data/felix_missing.cfg")

            cfg_dict = { "LogInterfacePrefix": "blah",
                         field: "bloop" }
            with self.assertRaisesRegexp(ConfigException,
                                         "Invalid log level.*%s" % field):
                config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 15
0
 def test_bad_metadata_addr(self):
     config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = { "InterfacePrefix": "blah",
                  "MetadataAddr": "bloop",
                  "MetadataPort": "123" }
     with self.assertRaisesRegexp(ConfigException,
                                  "Invalid or unresolvable.*MetadataAddr"):
         config.report_etcd_config({}, cfg_dict)
     self.m_gethostbyname.assert_has_calls([mock.call("bloop")])
Ejemplo n.º 16
0
    def test_no_logfile(self):
        # Logging to file can be excluded by explicitly saying "none"
        config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = { "InterfacePrefix": "blah",
                     "LogFilePath": "None" }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.LOGFILE, None)
Ejemplo n.º 17
0
 def test_ip_in_ip_enabled_bad(self):
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = { "InterfacePrefix": "blah",
                  "IpInIpEnabled": "blah" }
     with self.assertRaisesRegexp(ConfigException,
                                  "Field was not a valid Boolean"
                                  ".*IpInIpEnabled"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 18
0
    def test_bad_log_level(self):
        for field in ("LogSeverityFile", "LogSeverityScreen",
                      "LogSeveritySys"):
            with mock.patch('calico.common.complete_logging'):
                config = Config("calico/felix/test/data/felix_missing.cfg")

            cfg_dict = {"LogInterfacePrefix": "blah", field: "bloop"}
            with self.assertRaisesRegexp(ConfigException,
                                         "Invalid log level.*%s" % field):
                config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 19
0
 def test_metadata_port_not_valid_1(self):
     for i in (0, -1, 99999):
         log.debug("Test invalid metadata port %d", i)
         config = Config("calico/felix/test/data/felix_missing.cfg")
         cfg_dict = { "InterfacePrefix": "blah",
                      "MetadataAddr": "127.0.0.1",
                      "MetadataPort": i }
         with self.assertRaisesRegexp(ConfigException,
                                      "Invalid field value.*MetadataPort"):
             config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 20
0
 def test_reporting_interval_not_int(self):
     """
     Test exception is raised if status reporting interval is invalid.
     """
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = {"InterfacePrefix": "blah", "ReportingIntervalSecs": "NaN"}
     with self.assertRaisesRegexp(ConfigException,
                                  "Field was not integer.*"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 21
0
 def test_metadata_port_not_int(self):
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = {
         "InterfacePrefix": "blah",
         "MetadataAddr": "127.0.0.1",
         "MetadataPort": "bloop"
     }
     with self.assertRaisesRegexp(ConfigException,
                                  "Field was not integer.*MetadataPort"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 22
0
 def test_reporting_interval_not_int(self):
     """
     Test exception is raised if status reporting interval is invalid.
     """
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = { "InterfacePrefix": "blah",
                  "ReportingIntervalSecs": "NaN"}
     with self.assertRaisesRegexp(ConfigException,
                                  "Field was not integer.*"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 23
0
 def test_blank_metadata_addr(self):
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = {
         "InterfacePrefix": "blah",
         "MetadataAddr": "",
         "MetadataPort": "123"
     }
     with self.assertRaisesRegexp(ConfigException,
                                  "Blank value.*MetadataAddr"):
         config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 24
0
    def test_default_ipset_size(self):
        """
        Test that ipset size is defaulted if out of range.
        """
        with mock.patch("calico.common.complete_logging"):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {"InterfacePrefix": "blah", "MaxIpsetSize": "0"}
        with mock.patch("calico.common.complete_logging"):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.MAX_IPSET_SIZE, 2 ** 20)
Ejemplo n.º 25
0
def main():
    common.default_logging(gevent_in_use=False)

    # The parent process sends us communication pipes as FD 3 and 4. Open
    # those as files.  Wrap the resulting files in a FileObject to make
    # them cooperate with gevent.
    pipe_from_parent = os.fdopen(3, 'rb', -1)
    pipe_to_parent = os.fdopen(4, 'wb', -1)

    reader = MessageReader(pipe_from_parent)
    writer = MessageWriter(pipe_to_parent)

    config = Config()

    while True:
        for msg_type, msg, seq_no in reader.new_messages():
            _log.info("New %s message (#%s)", msg_type, seq_no)
            if msg_type == MSG_TYPE_CONFIG_UPDATE:
                config.update_from(msg.config)
            elif msg_type == MSG_TYPE_IPSET_DELTA:
                _log.info("IP set delta message: %s", msg)
            elif msg_type == MSG_TYPE_IPSET_REMOVED:
                _log.info("IP set removed message: %s", msg)
            elif msg_type == MSG_TYPE_IPSET_UPDATE:
                _log.info("IP set added message: %s", msg)
            elif msg_type == MSG_TYPE_WL_EP_UPDATE:
                _log.info("Workload endpoint update message: %s", msg)
            elif msg_type == MSG_TYPE_WL_EP_REMOVE:
                _log.info("Workload endpoint remove message: %s", msg)
            elif msg_type == MSG_TYPE_HOST_EP_UPDATE:
                _log.info("Host endpoint update message: %s", msg)
            elif msg_type == MSG_TYPE_HOST_EP_REMOVE:
                _log.info("Host endpoint update remove: %s", msg)
            elif msg_type == MSG_TYPE_HOST_METADATA_UPDATE:
                _log.info("Host endpoint update message: %s", msg)
            elif msg_type == MSG_TYPE_HOST_METADATA_REMOVE:
                _log.info("Host endpoint remove message: %s", msg)
            elif msg_type == MSG_TYPE_IPAM_POOL_UPDATE:
                _log.info("IPAM pool update messages:%s", msg)
            elif msg_type == MSG_TYPE_IPAM_POOL_REMOVE:
                _log.info("IPAM pool remove message: %s", msg)
            elif msg_type == MSG_TYPE_POLICY_UPDATE:
                _log.info("Policy update message: %s", msg)
            elif msg_type == MSG_TYPE_POLICY_REMOVED:
                _log.info("Policy update message: %s", msg)
            elif msg_type == MSG_TYPE_PROFILE_UPDATE:
                _log.info("Profile update message: %s", msg)
            elif msg_type == MSG_TYPE_PROFILE_REMOVED:
                _log.info("Profile update message: %s", msg)
            elif msg_type == MSG_TYPE_IN_SYNC:
                _log.info("In sync message: %s", msg)
            else:
                _log.error("Unexpected message %r %s", msg_type, msg)
Ejemplo n.º 26
0
 def test_bad_metadata_addr(self):
     with mock.patch('calico.common.complete_logging'):
         config = Config("calico/felix/test/data/felix_missing.cfg")
     cfg_dict = {
         "InterfacePrefix": "blah",
         "MetadataAddr": "bloop",
         "MetadataPort": "123"
     }
     with self.assertRaisesRegexp(ConfigException,
                                  "Invalid or unresolvable.*MetadataAddr"):
         config.report_etcd_config({}, cfg_dict)
     self.m_gethostbyname.assert_has_calls([mock.call("bloop")])
Ejemplo n.º 27
0
 def test_metadata_port_not_valid_1(self):
     for i in (0, -1, 99999):
         log.debug("Test invalid metadata port %d", i)
         with mock.patch('calico.common.complete_logging'):
             config = Config("calico/felix/test/data/felix_missing.cfg")
         cfg_dict = {
             "InterfacePrefix": "blah",
             "MetadataAddr": "127.0.0.1",
             "MetadataPort": i
         }
         with self.assertRaisesRegexp(ConfigException,
                                      "Invalid field value.*MetadataPort"):
             config.report_etcd_config({}, cfg_dict)
Ejemplo n.º 28
0
    def test_no_metadata(self):
        # Metadata can be excluded by explicitly saying "none"
        config = Config("calico/felix/test/data/felix_missing.cfg")

        cfg_dict = { "InterfacePrefix": "blah",
                     "MetadataAddr": "NoNe",
                     "MetadataPort": 123 }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        # Test defaulting.
        self.assertEqual(config.METADATA_IP, None)
        self.assertEqual(config.METADATA_PORT, None)
Ejemplo n.º 29
0
    def test_default_ipset_size(self):
        """
        Test that ipset size is defaulted if out of range.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {
            "InterfacePrefix": "blah",
            "MaxIpsetSize": "0",
        }
        with mock.patch('calico.common.complete_logging'):
            config.update_from({}, cfg_dict)

        self.assertEqual(config.MAX_IPSET_SIZE, 2**20)
Ejemplo n.º 30
0
    def test_negative_reporting_interval(self):
        """
        Test that status reporting is disabled if interval time is negative.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = { "InterfacePrefix": "blah",
                     "ReportingIntervalSecs": -42,
                     "ReportingTTLSecs": 7 }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_INTERVAL_SECS, 0)
        self.assertEqual(config.REPORTING_TTL_SECS, 0)
Ejemplo n.º 31
0
    def test_valid_interval_and_ttl(self):
        """
        Test valid reporting parameters are not changed.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = { "InterfacePrefix": "blah",
                     "ReportingIntervalSecs": 42,
                     "ReportingTTLSecs": 47}
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_INTERVAL_SECS, 42)
        self.assertEqual(config.REPORTING_TTL_SECS, 47)
Ejemplo n.º 32
0
    def test_reporting_interval_and_ttl_zero(self):
        """
        Test that zero reporting interval and ttl are passed correctly.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = { "InterfacePrefix": "blah",
                     "ReportingIntervalSecs": 0,
                     "ReportingTTLSecs": 0}
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_INTERVAL_SECS, 0)
        self.assertEqual(config.REPORTING_TTL_SECS, 0)
Ejemplo n.º 33
0
    def test_reporting_float(self):
        """
        Test that float reporting interval and ttl values are rounded down to integer.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = { "InterfacePrefix": "blah",
                     "ReportingIntervalSecs": 21.75,
                     "ReportingTTLSecs": 63.248}
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_INTERVAL_SECS, 21)
        self.assertEqual(config.REPORTING_TTL_SECS, 63)
Ejemplo n.º 34
0
    def test_reporting_interval_and_ttl_zero(self):
        """
        Test that zero reporting interval and ttl are passed correctly.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {
            "InterfacePrefix": "blah",
            "ReportingIntervalSecs": 0,
            "ReportingTTLSecs": 0
        }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_INTERVAL_SECS, 0)
        self.assertEqual(config.REPORTING_TTL_SECS, 0)
Ejemplo n.º 35
0
    def test_valid_interval_and_ttl(self):
        """
        Test valid reporting parameters are not changed.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {
            "InterfacePrefix": "blah",
            "ReportingIntervalSecs": 42,
            "ReportingTTLSecs": 47
        }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_INTERVAL_SECS, 42)
        self.assertEqual(config.REPORTING_TTL_SECS, 47)
Ejemplo n.º 36
0
    def test_default_ttl(self):
        """
        Test that ttl is defaulted to at least 2.5 times the reporting
        interval.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {
            "InterfacePrefix": "blah",
            "ReportingIntervalSecs": "21",
            "ReportingTTLSecs": "21",
        }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_TTL_SECS, 52)
Ejemplo n.º 37
0
    def test_negative_reporting_interval(self):
        """
        Test that status reporting is disabled if interval time is negative.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {
            "InterfacePrefix": "blah",
            "ReportingIntervalSecs": -42,
            "ReportingTTLSecs": 7
        }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_INTERVAL_SECS, 0)
        self.assertEqual(config.REPORTING_TTL_SECS, 0)
Ejemplo n.º 38
0
    def test_default_ttl(self):
        """
        Test that ttl is defaulted to at least 2.5 times the reporting
        interval.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {
            "InterfacePrefix": "blah",
            "ReportingIntervalSecs": "21",
            "ReportingTTLSecs": "21",
        }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_TTL_SECS, 52)
Ejemplo n.º 39
0
    def test_no_metadata(self):
        # Metadata can be excluded by explicitly saying "none"
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")

        cfg_dict = {
            "InterfacePrefix": "blah",
            "MetadataAddr": "NoNe",
            "MetadataPort": 123
        }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        # Test defaulting.
        self.assertEqual(config.METADATA_IP, None)
        self.assertEqual(config.METADATA_PORT, None)
Ejemplo n.º 40
0
    def test_reporting_float(self):
        """
        Test that float reporting interval and ttl values are rounded down to integer.
        """
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {
            "InterfacePrefix": "blah",
            "ReportingIntervalSecs": 21.75,
            "ReportingTTLSecs": 63.248
        }
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.REPORTING_INTERVAL_SECS, 21)
        self.assertEqual(config.REPORTING_TTL_SECS, 63)
Ejemplo n.º 41
0
def main():
    try:
        # Initialise the logging with default parameters.
        common.default_logging()

        # Load config
        # FIXME: old felix used argparse but that's not in Python 2.6, so
        # hard-coded path.

        try:
            config = Config("/etc/calico/felix.cfg")
        except:
            # Attempt to open a log file, ignoring any errors it gets, before
            # we raise the exception.
            try:
                common.complete_logging("/var/log/calico/felix.log",
                                        logging.DEBUG, logging.DEBUG,
                                        logging.DEBUG)
            except:
                pass

            raise

        _log.info("Felix initializing")
        gevent.spawn(_main_greenlet, config).join()  # Should never return
    except BaseException:
        # Make absolutely sure that we exit by asking the OS to terminate our
        # process.  We don't want to let a stray background thread keep us
        # alive.
        _log.exception("Felix exiting due to exception")
        os._exit(1)
        raise  # Unreachable but keeps the linter happy about the broad except.
Ejemplo n.º 42
0
def load_config(filename, path="calico/felix/test/data/", env_dict=None,
                host_dict=None, global_dict=None):
    if env_dict is None:
        env_dict = {}
    if host_dict is None:
        host_dict = {}
    if global_dict is None:
        global_dict = {}

    with mock.patch.dict("os.environ", env_dict):
        with mock.patch('calico.common.complete_logging'):
            config = Config(path+filename)

    with mock.patch('calico.common.complete_logging'):
        config.report_etcd_config(host_dict, global_dict)

    return config
Ejemplo n.º 43
0
    def test_no_logfile(self):
        # Logging to file can be excluded by explicitly saying "none"
        host = socket.gethostname()
        host_path = "/calico/host/%s/config/" % host

        result = StubEtcdResult("/calico/config/")
        result.add_child("InterfacePrefix", "blah")
        result.add_child("LogFilePath", "NoNe")

        result = StubEtcdResult(host_path)

        config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = { "InterfacePrefix": "blah",
                     "LogFilePath": "None",
                     "ResyncIntervalSecs": "123" }
        config.update_config(cfg_dict)

        self.assertEqual(config.LOGFILE, None)
Ejemplo n.º 44
0
def load_config(filename,
                path="calico/felix/test/data/",
                env_dict=None,
                host_dict=None,
                global_dict=None):
    if env_dict is None:
        env_dict = {}
    if host_dict is None:
        host_dict = {}
    if global_dict is None:
        global_dict = {}

    with mock.patch.dict("os.environ", env_dict):
        with mock.patch('calico.common.complete_logging'):
            config = Config(path + filename)

    with mock.patch('calico.common.complete_logging'):
        config.report_etcd_config(host_dict, global_dict)

    return config
Ejemplo n.º 45
0
    def test_invalid_port(self):
        data = {
            "felix_invalid_port.cfg": "Invalid port in field",
            "felix_invalid_addr.cfg": "Invalid or unresolvable",
            "felix_invalid_both.cfg": "Invalid or unresolvable",
            "felix_invalid_format.cfg": "Invalid format for field"
        }

        for filename in data:
            log.debug("Test filename : %s", filename)
            with self.assertRaisesRegexp(ConfigException, data[filename]):
                config = Config("calico/felix/test/data/%s" % filename)
Ejemplo n.º 46
0
    def test_unreadable_etcd_key(self):
        """
        Test that we throw an exception when the etcd key is unreadable
        """
        with nested(mock.patch("os.path.isfile", autospec=True),
                    mock.patch("os.access", autospec=True)) \
             as (m_isfile, m_access):

            m_isfile.return_value = True
            m_access.return_value = False
            with self.assertRaisesRegexp(ConfigException,
                                         "Cannot read key file"):
                config = Config("calico/felix/test/data/felix_unreadable_key.cfg")
Ejemplo n.º 47
0
    def test_unreadable_etcd_ca(self):
        """
        Test that we throw an exception when the etcd CA cert is unreadable
        """
        with nested(mock.patch("os.path.isfile", autospec=True),
                    mock.patch("os.access", autospec=True)) \
             as (m_isfile, m_access):

            m_isfile.return_value = True
            m_access.side_effect = iter([True, True, False])
            with self.assertRaisesRegexp(ConfigException,
                                         "Missing CA certificate"):
                config = Config("calico/felix/test/data/felix_unreadable_ca.cfg")
Ejemplo n.º 48
0
    def test_no_logfile(self):
        # Logging to file can be excluded by explicitly saying "none" -
        # but if in etcd config the file is still created.
        with mock.patch('calico.common.complete_logging'):
            config = Config("calico/felix/test/data/felix_missing.cfg")
        cfg_dict = {"InterfacePrefix": "blah", "LogFilePath": "None"}
        with mock.patch('calico.common.complete_logging'):
            config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.LOGFILE, None)

        config = Config("calico/felix/test/data/felix_nolog.cfg")
        cfg_dict = {"InterfacePrefix": "blah"}
        config.report_etcd_config({}, cfg_dict)

        self.assertEqual(config.LOGFILE, None)
Ejemplo n.º 49
0
    def test_invalid_etcd(self):
        """
        Test that etcd validation works correctly.
        """
        data = {
            "felix_invalid_scheme.cfg": "Invalid protocol scheme",
            "felix_missing_key.cfg": "Missing etcd key",
            "felix_missing_cert.cfg": "Missing etcd certificate"
        }

        for filename in data:
            log.debug("Test filename : %s", filename)
            with self.assertRaisesRegexp(ConfigException, data[filename]):
                config = Config("calico/felix/test/data/%s" % filename)
Ejemplo n.º 50
0
def main():
    # Initialise the logging with default parameters.
    common.default_logging(gevent_in_use=True)

    # Create configuration, reading defaults from file if it exists.
    parser = optparse.OptionParser()
    parser.add_option('-c',
                      '--config-file',
                      dest='config_file',
                      help="configuration file to use",
                      default="/etc/calico/felix.cfg")
    options, args = parser.parse_args()

    try:
        config = Config(options.config_file)
    except Exception:
        # Config loading error, and not just invalid parameters (from optparse)
        # as they generate a SystemExit. Attempt to open a log file, ignoring
        # any errors it gets, before we raise the exception.
        try:
            common.complete_logging("/var/log/calico/felix.log",
                                    logging.DEBUG,
                                    logging.DEBUG,
                                    logging.DEBUG,
                                    gevent_in_use=True)
        except Exception:
            pass

        # Log the exception with logging in whatever state we managed to get it
        # to, then reraise it, taking Felix down.
        _log.exception("Exception loading configuration")
        raise

    _log.info("Felix initializing")

    try:
        gevent.spawn(_main_greenlet, config).join()  # Should never return
    except Exception:
        # Make absolutely sure that we exit by asking the OS to terminate our
        # process.  We don't want to let a stray background thread keep us
        # alive.
        _log.exception("Felix exiting due to exception")
        os._exit(1)
        raise  # Unreachable but keeps the linter happy about the broad except.
Ejemplo n.º 51
0
    def test_file_sections(self):
        """
        Test various ways of defaulting config.
        """
        files = [
            "felix_section.cfg",  # lots of sections
        ]

        for filename in files:
            with mock.patch('calico.common.complete_logging'):
                config = Config("calico/felix/test/data/%s" % filename)

            # Test that read ignoring sections.
            self.assertEqual(config.ETCD_ADDR, "localhost:4001")
            self.assertEqual(config.HOSTNAME, socket.gethostname())
            self.assertEqual(config.LOGFILE, "/log/nowhere.log")
            self.assertEqual(config.IFACE_PREFIX, "whatever")
            self.assertEqual(config.METADATA_PORT, 246)
            self.assertEqual(config.METADATA_IP, "1.2.3.4")
Ejemplo n.º 52
0
 def test_bad_localaddr(self):
     with self.assertRaisesRegexp(ConfigException,
                                  "Invalid or unresolvable LocalAddress"):
         config = Config("calico/felix/test/data/felix_bad_localaddr.cfg")