diff options
-rw-r--r-- | data/templates/telegraf/telegraf.j2 | 15 | ||||
-rw-r--r-- | interface-definitions/service_monitoring_telegraf.xml.in | 33 | ||||
-rw-r--r-- | op-mode-definitions/dhcp.xml.in | 39 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_monitoring_telegraf.py | 29 | ||||
-rwxr-xr-x | src/conf_mode/service_monitoring_telegraf.py | 18 | ||||
-rwxr-xr-x | src/op_mode/dhcp.py | 10 |
6 files changed, 143 insertions, 1 deletions
diff --git a/data/templates/telegraf/telegraf.j2 b/data/templates/telegraf/telegraf.j2 index 9623bdec6..f382dbf2e 100644 --- a/data/templates/telegraf/telegraf.j2 +++ b/data/templates/telegraf/telegraf.j2 @@ -41,6 +41,21 @@ bucket = "{{ influxdb.bucket }}" ### End InfluxDB2 ### {% endif %} +{% if loki is vyos_defined %} +### Loki ### +[[outputs.loki]] + ## The domain of Loki + domain = "{{ loki.url }}:{{ loki.port }}" +{% if loki.authentication.username is vyos_defined and loki.authentication.password is vyos_defined %} + ## Basic Authentication + username = "{{ loki.authentication.username }}" + password = "{{ loki.authentication.password }}" +{% endif %} +{% if loki.metric_name_label is vyos_defined %} +metric_name_label = "{{ loki.metric_name_label }}" +{% endif %} +### End Loki ### +{% endif %} {% if prometheus_client is vyos_defined %} ### Prometheus ### [[outputs.prometheus_client]] diff --git a/interface-definitions/service_monitoring_telegraf.xml.in b/interface-definitions/service_monitoring_telegraf.xml.in index 2624023ea..2ac0d940e 100644 --- a/interface-definitions/service_monitoring_telegraf.xml.in +++ b/interface-definitions/service_monitoring_telegraf.xml.in @@ -148,6 +148,39 @@ #include <include/url-http-https.xml.i> </children> </node> + <node name="loki"> + <properties> + <help>Output plugin Loki</help> + </properties> + <children> + <node name="authentication"> + <properties> + <help>HTTP basic authentication parameters</help> + </properties> + <children> + #include <include/generic-username.xml.i> + #include <include/generic-password.xml.i> + </children> + </node> + <leafNode name="metric-name-label"> + <properties> + <help>Metric name label</help> + <valueHelp> + <format>txt</format> + <description>Label to use for the metric name</description> + </valueHelp> + <constraint> + #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> + </constraint> + </properties> + </leafNode> + #include <include/port-number.xml.i> + <leafNode name="port"> + <defaultValue>3100</defaultValue> + </leafNode> + #include <include/url-http-https.xml.i> + </children> + </node> <leafNode name="source"> <properties> <help>Source parameters for monitoring</help> diff --git a/op-mode-definitions/dhcp.xml.in b/op-mode-definitions/dhcp.xml.in index 6114142f0..027072261 100644 --- a/op-mode-definitions/dhcp.xml.in +++ b/op-mode-definitions/dhcp.xml.in @@ -233,4 +233,43 @@ </node> </children> </node> + <node name="release"> + <properties> + <help>Release specified variable</help> + </properties> + <children> + <node name="dhcp"> + <properties> + <help>Release DHCP client lease</help> + </properties> + <children> + <tagNode name="interface"> + <properties> + <help>Release DHCP client lease for specified interface</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces</script> + </completionHelp> + </properties> + <command>sudo ${vyos_op_scripts_dir}/dhcp.py release_client_lease --family inet --interface "$4"</command> + </tagNode> + </children> + </node> + <node name="dhcpv6"> + <properties> + <help>Release DHCPv6 client lease</help> + </properties> + <children> + <tagNode name="interface"> + <properties> + <help>Release DHCPv6 client lease for specified interface</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces</script> + </completionHelp> + </properties> + <command>sudo ${vyos_op_scripts_dir}/dhcp.py release_client_lease --family inet6 --interface "$4"</command> + </tagNode> + </children> + </node> + </children> + </node> </interfaceDefinition> diff --git a/smoketest/scripts/cli/test_service_monitoring_telegraf.py b/smoketest/scripts/cli/test_service_monitoring_telegraf.py index 3374411f5..886b88683 100755 --- a/smoketest/scripts/cli/test_service_monitoring_telegraf.py +++ b/smoketest/scripts/cli/test_service_monitoring_telegraf.py @@ -17,6 +17,7 @@ import unittest from base_vyostest_shim import VyOSUnitTestSHIM +from vyos.configsession import ConfigSessionError from vyos.utils.process import process_named_running from vyos.utils.file import read_file @@ -63,5 +64,33 @@ class TestMonitoringTelegraf(VyOSUnitTestSHIM.TestCase): for input in inputs: self.assertIn(input, config) + def test_02_loki(self): + label = 'r123' + loki_url = 'http://localhost' + port = '3100' + loki_username = 'VyOS' + loki_password = 'PassW0Rd_VyOS' + + self.cli_set(base_path + ['loki', 'url', loki_url]) + self.cli_set(base_path + ['loki', 'port', port]) + self.cli_set(base_path + ['loki', 'metric-name-label', label]) + + self.cli_set(base_path + ['loki', 'authentication', 'username', loki_username]) + # password not set + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_set(base_path + ['loki', 'authentication', 'password', loki_password]) + + # commit changes + self.cli_commit() + + config = read_file(TELEGRAF_CONF) + self.assertIn(f'[[outputs.loki]]', config) + self.assertIn(f'domain = "{loki_url}:{port}"', config) + self.assertIn(f'metric_name_label = "{label}"', config) + self.assertIn(f'username = "{loki_username}"', config) + self.assertIn(f'password = "{loki_password}"', config) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/service_monitoring_telegraf.py b/src/conf_mode/service_monitoring_telegraf.py index 40eb13e23..9455b6109 100755 --- a/src/conf_mode/service_monitoring_telegraf.py +++ b/src/conf_mode/service_monitoring_telegraf.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2021-2023 VyOS maintainers and contributors +# Copyright (C) 2021-2024 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -113,6 +113,9 @@ def get_config(config=None): if not conf.exists(base + ['azure-data-explorer']): del monitoring['azure_data_explorer'] + if not conf.exists(base + ['loki']): + del monitoring['loki'] + return monitoring def verify(monitoring): @@ -159,6 +162,19 @@ def verify(monitoring): if 'url' not in monitoring['splunk']: raise ConfigError(f'Monitoring splunk "url" is mandatory!') + # Verify Loki + if 'loki' in monitoring: + if 'url' not in monitoring['loki']: + raise ConfigError(f'Monitoring loki "url" is mandatory!') + if 'authentication' in monitoring['loki']: + if ( + 'username' not in monitoring['loki']['authentication'] + or 'password' not in monitoring['loki']['authentication'] + ): + raise ConfigError( + f'Authentication "username" and "password" are mandatory!' + ) + return None def generate(monitoring): diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py index 3229da4ad..dffd99de5 100755 --- a/src/op_mode/dhcp.py +++ b/src/op_mode/dhcp.py @@ -423,6 +423,16 @@ def renew_client_lease(raw: bool, family: ArgFamily, interface: str): else: call(f'systemctl restart dhclient@{interface}.service') +@_verify_client +def release_client_lease(raw: bool, family: ArgFamily, interface: str): + if not raw: + v = 'v6' if family == 'inet6' else '' + print(f'Release DHCP{v} client on interface {interface}...') + if family == 'inet6': + call(f'systemctl stop dhcp6c@{interface}.service') + else: + call(f'systemctl stop dhclient@{interface}.service') + if __name__ == '__main__': try: res = vyos.opmode.run(sys.modules[__name__]) |