From b7ecdee87c3b66279bca1a9de688610e40264f7e Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Sun, 21 May 2023 17:07:28 +0200
Subject: [PATCH] update project

---
 agent_based/squid.py       | 199 +++++++++++++++++++++++++++++++++++++
 agents/bakery/squid.py     |  47 +++++++++
 agents/plugins/squid       |  34 +++++++
 checkman/squid             |  48 ++-------
 gui/metrics/squid.py       | 128 ++++++++++++++++++++++++
 gui/wato/squid.py          | 142 ++++++++++++++++++++++++++
 packages/squid             |  18 ++++
 squid-2.0.2-2023-05-21.mkp | Bin 0 -> 4687 bytes
 squid.mkp                  | Bin 0 -> 4687 bytes
 9 files changed, 574 insertions(+), 42 deletions(-)
 create mode 100644 agent_based/squid.py
 create mode 100755 agents/bakery/squid.py
 create mode 100755 agents/plugins/squid
 create mode 100644 gui/metrics/squid.py
 create mode 100644 gui/wato/squid.py
 create mode 100644 packages/squid
 create mode 100644 squid-2.0.2-2023-05-21.mkp
 create mode 100644 squid.mkp

diff --git a/agent_based/squid.py b/agent_based/squid.py
new file mode 100644
index 0000000..b719d48
--- /dev/null
+++ b/agent_based/squid.py
@@ -0,0 +1,199 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2023-05-20
+
+# based on https://github.com/allangood/check_mk/tree/master/plugins/squid
+#
+# rewritten for cmk 2.x
+#
+# 2023-05-20: moved to ~/local/lib/check_mk/base/plugins/agent_based/utils
+#             renamed from check_squid.include to squid.py
+#
+
+
+# !/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2023-05-20
+
+# based on https://github.com/allangood/check_mk/tree/master/plugins/squid by Allan GooD: allan.cassaro@gmail.com
+#
+# rewritten for cmk 2.x
+#
+
+# ToDo: add support for multiple instances
+
+from typing import Dict
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    register,
+    check_levels,
+    check_levels_predictive,
+    Service,
+    render
+)
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
+    DiscoveryResult,
+    CheckResult,
+)
+
+
+def parse_squid(string_table) -> Dict[str, float]:
+    section = {}
+    for line in string_table:
+        entry, value = line[0].split('=')
+        entry = entry.strip()
+        try:
+            value = float(value.split('/')[0].strip().split(' ')[0].split('%')[0])
+        except ValueError:
+            continue
+        if 'kbytes' in entry:
+            value = value * 1024 + 8 # change kbytes to bits
+        section[entry] = value
+
+    return section
+
+
+register.agent_section(
+    name="squid",
+    parse_function=parse_squid,
+)
+
+
+def render_per_second(value: float) -> str:
+    return f'{value}/s'
+
+
+def render_seconds(value: float) -> str:
+    return f'{value:0.4f} seconds'
+
+
+squid_map = {
+    'Client': {
+        'client_http.requests': {
+            'label': 'Requests',
+            'levels_upper': 'client_requests',
+            'metric_name': 'client_requests_per_second',
+            'render_func': render_per_second,
+        },
+        'client_http.errors': {
+            'label': 'Errors',
+            'levels_upper': 'client_errors',
+            'metric_name': 'client_errors_per_second',
+            'render_func': render_per_second,
+        },
+        'client_http.hits': {
+            'label': 'Cache Hits',
+            'levels_upper': 'client_hits',
+            'metric_name': 'client_hits_per_second',
+            'render_func': render_per_second,
+        },
+        'client_http.kbytes_in': {
+            'label': 'In',
+            'levels_upper': 'client_bytes_in_out',
+            'metric_name': 'if_in_bps',
+            'render_func': render.networkbandwidth,
+        },
+        'client_http.kbytes_out': {
+            'label': 'Out',
+            'levels_upper': 'client_bytes_in_out',
+            'metric_name': 'if_out_bps',
+            'render_func': render.networkbandwidth,
+        },
+    },
+    'Server': {
+        'server.all.requests': {
+            'label': 'Requests',
+            'levels_upper': 'server_requests',
+            'metric_name': 'server_all_requests',
+            'render_func': render_per_second,
+        },
+        'server.all.errors': {
+            'label': 'Errors',
+            'levels_upper': 'server_errors',
+            'metric_name': 'server_all_errors',
+            'render_func': render_per_second,
+        },
+        'server.all.kbytes_in': {
+            'label': 'In',
+            'levels_upper': 'server_bytes_in_out',
+            'metric_name': 'if_in_bps',
+            'render_func': render.networkbandwidth,
+        },
+        'server.all.kbytes_out': {
+            'label': 'Out',
+            'levels_upper': 'server_bytes_in_out',
+            'metric_name': 'if_out_bps',
+            'render_func': render.networkbandwidth,
+        },
+    },
+    'CPU': {
+        'cpu_usage': {
+            'label': 'Usage',
+            'levels_upper': 'cpu_usage',
+            'metric_name': 'util',
+            'render_func': render.percent,
+        },
+        'cpu_time': {
+            'label': 'Time',
+            'levels_upper': 'cpu_time',
+            'metric_name': 'cpu_time',
+            'render_func': render.timespan,
+        },
+    },
+    'DNS': {
+        'dns.median_svc_time': {
+            'label': 'Median response time',
+            'levels_upper': 'dns_time',
+            'metric_name': 'dns_median_svc_time',
+            'render_func': render_seconds,
+        }},
+}
+
+
+def discovery_squid(section: Dict[str, float]) -> DiscoveryResult:
+    for item in squid_map.keys():
+        yield Service(item=item)
+
+
+def check_squid(item, params, section: Dict[str, float]) -> CheckResult:
+    for value in squid_map[item].keys():
+        entry = squid_map[item][value]
+        levels_upper = params.get(entry['levels_upper'], None)
+        yield from  check_levels_predictive(
+            label=entry['label'],
+            value=section[value],
+            levels=levels_upper,
+            render_func=entry['render_func'],
+            metric_name=entry['metric_name'],
+        ) if isinstance(levels_upper, dict) else check_levels(
+            label=entry['label'],
+            value=section[value],
+            levels_upper=levels_upper,
+            render_func=entry['render_func'],
+            metric_name=entry['metric_name'],
+        )
+
+
+register.check_plugin(
+    name='squid',
+    service_name='Squid %s',
+    discovery_function=discovery_squid,
+    check_function=check_squid,
+    check_default_parameters={
+        # 'client_requests': (600, 800),
+        # 'client_hits': (600, 800),
+        # 'server_requests': (600, 800),
+        'dns_time': (2, 4),
+        'cpu_usage': (60, 80)
+    },
+    check_ruleset_name='squid',
+)
diff --git a/agents/bakery/squid.py b/agents/bakery/squid.py
new file mode 100755
index 0000000..25a0191
--- /dev/null
+++ b/agents/bakery/squid.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2023-05-20
+
+# based on https://github.com/allangood/check_mk/tree/master/plugins/squid
+#
+# rewritten for cmk 2.x
+#
+# 2023-05-20: moved agent plugin from ~/local/share/check_mk/agents/plugins/linux
+#                                  to ~/local/share/check_mk/agents/plugins
+#             renamed bakery plugin from squid to squid.py
+
+from pathlib import Path
+from cmk.base.cee.plugins.bakery.bakery_api.v1 import (
+    FileGenerator,
+    OS,
+    Plugin,
+    PluginConfig,
+    register
+)
+
+
+def get_squid_files(conf) -> FileGenerator:
+    yield Plugin(
+        base_os=OS.LINUX,
+        source=Path('squid'),
+        # interval=interval,
+        # timeout=timeout
+    )
+
+    yield PluginConfig(
+        base_os=OS.LINUX,
+        lines=[f'port={conf["port"]}'],
+        target=Path('squid.cfg'),
+        include_header=False,
+    )
+
+
+register.bakery_plugin(
+    name='squid',
+    files_function=get_squid_files,
+)
diff --git a/agents/plugins/squid b/agents/plugins/squid
new file mode 100755
index 0000000..03aa184
--- /dev/null
+++ b/agents/plugins/squid
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+# based on https://github.com/allangood/check_mk/tree/master/plugins/squid by Allan GooD: allan.cassaro@gmail.com
+#
+# 2023-05-20: changed separator to :sep(0)
+#             changed section from check_squid to squid
+#
+# https://etutorials.org/Server+Administration/Squid.+The+definitive+guide/Chapter+14.+Monitoring+Squid/14.2+The+Cache+Manager/
+#
+# Table 14-1. Cache manager pages for squidclient mgr:<page>
+#
+MK_CONFDIR="/etc/check_mk"
+
+
+if [ -e $MK_CONFDIR/squid.cfg ] ; then
+  . "$MK_CONFDIR"/squid.cfg
+fi
+
+if [ -z "$port" ]; then
+  port=$(ss -tlpn | grep squid | tr -s ' ' | cut -d' ' -f 4 | cut -d':' -f 2)
+fi
+
+
+if type squidclient > /dev/null 2>&1 ; then
+  echo "<<squid:sep(0)>>>"
+
+  # one squid instance
+  squidclient -p "$port" -T2 mgr:5min | grep =
+
+  # multiple squid instances
+  # instance names must be without spaces and with colon char at the end
+  # squidclient -p 3128 -T2 mgr:5min | grep ' = ' | sed -e 's/^/Instance1:/'
+  # squidclient -p 3129 -T2 mgr:5min | grep ' = ' | sed -e 's/^/Instance2:/'
+fi
diff --git a/checkman/squid b/checkman/squid
index 08ef898..c4e71db 100644
--- a/checkman/squid
+++ b/checkman/squid
@@ -1,45 +1,9 @@
-title: Dummy check man page - used as template for new check manuals
-agents: linux, windows, aix, solaris, hpux, vms, freebsd, snmp
-catalog: see modules/catalog.py for possible values
+title: Check for Squid3 (www.squid-cache.org) health
+agents: linux
+catalog: os/misc
 license: GPL
-distribution: check_mk
+distribution: OMD
 description:
- Describe here: (1) what the check actually does, (2) under which
- circumstances it goes warning/critical, (3) which devices are supported
- by the check, (4) if the check requires a separated plugin or
- tool or separate configuration on the target host.
+ This check checks for Squid3 (www.squid-cache.org) basic health.
+ You need to install the plugin {squid} into the {plugins} directory of your agent.
 
-item:
- Describe the syntax and meaning of the check's item here. Provide all
- information one needs if coding a manual check with {checks +=} in {main.mk}.
- Give an example.  If the check uses {None} as sole item,
- then leave out this section.
-
-examples:
- # Give examples for configuration in {main.mk} here. If the check has
- # configuration variable, then give example for them here.
-
- # set default levels to 40 and 60 percent:
- foo_default_values = (40, 60)
-
- # another configuration variable here:
- inventory_foo_filter = [ "superfoo", "superfoo2" ]
-
-perfdata:
- Describe precisely the number and meaning of performance variables
- the check sends. If it outputs no performance data, then leave out this
- section.
-
-inventory:
- Describe how the inventory for the check works. Which items
- will it find? Describe the influence of check specific
- configuration parameters to the inventory.
-
-[parameters]
-foofirst(int): describe the first parameter here (if parameters are grouped
-        as tuple)
-fooother(string): describe another parameter here.
-
-[configuration]
-foo_default_levels(int, int): Describe global configuration variable of
-    foo here. Important: also tell the user how they are preset.
diff --git a/gui/metrics/squid.py b/gui/metrics/squid.py
new file mode 100644
index 0000000..a6bd657
--- /dev/null
+++ b/gui/metrics/squid.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2023-05-20
+#
+# metrics plugin for squid checks
+#
+#
+
+from cmk.gui.i18n import _
+
+from cmk.gui.plugins.metrics.utils import (
+    check_metrics,
+    metric_info,
+    graph_info,
+    perfometer_info
+)
+
+check_metrics['check_mk-squid'] = {
+    'predict_client_requests_per_second': {'auto_graph': False},
+    'predict_client_hits_per_second': {'auto_graph': False},
+    'predict_server_all_requests': {'auto_graph': False},
+    'predict_util': {'auto_graph': False},
+}
+
+
+metric_info['client_hits_per_second'] = {'title': _('Cache hits'), 'unit': '1/s', 'color': '11/a', }
+metric_info['client_requests_per_second'] = {'title': _('Requests'), 'unit': '1/s', 'color': '31/a', }
+metric_info['client_errors_per_second'] = {'title': _('Errors'), 'unit': '1/s', 'color': '21/a', }
+
+metric_info['predict_client_hits_per_second'] = {'title': _('Cache hits (Predicted)'), 'unit': '1/s', 'color': '52/a', }
+metric_info['predict_client_requests_per_second'] = {'title': _('Requests (Predicted)'), 'unit': '1/s', 'color': '51/a', }
+
+
+graph_info['squid_client'] = {
+    'title': _('Squid Client statistics'),
+    'metrics': [
+        ('client_hits_per_second', 'line'),
+        ('client_errors_per_second', 'line'),
+        ('client_requests_per_second', 'line'),
+    ],
+    'scalars': [
+        'client_hits_per_second:warn',
+        'client_hits_per_second:crit',
+    ],
+}
+
+graph_info['squid_client_predicted'] = {
+    'title': _('Predicted Squid Client statistics'),
+    'metrics': [
+        ('predict_client_hits_per_second', '-area'),
+        ('predict_client_requests_per_second', 'area'),
+    ],
+    'optional_metrics': [
+        'predict_client_hits_per_second',
+        'predict_client_requests_per_second'
+    ],
+}
+
+metric_info['server_all_requests'] = {'title': _('Requests'), 'unit': '1/s', 'color': '31/a', }
+metric_info['server_all_errors'] = {'title': _('Errors'), 'unit': '1/s', 'color': '21/a', }
+
+metric_info['predict_server_all_requests'] = {'title': _('Requests (Predicted)'), 'unit': '1/s', 'color': '51/a', }
+
+graph_info['squid_server'] = {
+    'title': _('Squid Server statistics'),
+    'metrics': [
+        ('server_all_errors', 'line'),
+        ('server_all_requests', 'line'),
+
+    ],
+    'scalars': [
+        'server_all_requests:warn',
+        'server_all_requests:crit',
+    ],
+}
+
+graph_info['squid_server_predicted'] = {
+    'title': _('Predicted Squid Server statistics'),
+    'metrics': [
+        ('predict_server_all_requests', 'area'),
+    ],
+}
+
+metric_info['cpu_time'] = {'title': _('CPU time'), 'unit': 's', 'color': '16/a', }
+metric_info['predict_util'] = {'title': _('CPU utilization (Predicted)'), 'unit': 's', 'color': '51/a', }
+
+graph_info['squid_cpu_time'] = {
+    'title': _('Squid CPU time'),
+    'metrics': [
+        ('cpu_time', 'area'),
+    ],
+    'scalars': [
+        'cpu_time:warn',
+        'cpu_time:crit',
+    ],
+}
+
+graph_info['squid_cpu_util_predicted'] = {
+    'title': _('Predicted Squid CPU utilization'),
+    'metrics': [
+        ('predict_util', 'area'),
+    ],
+}
+
+metric_info['dns_median_svc_time'] = {'title': _('DNS response time'), 'unit': 's', 'color': '26/a', }
+
+graph_info['squid_dns_median_svc_time'] = {
+    'title': _('Squid DNS median response time'),
+    'metrics': [
+        ('dns_median_svc_time', 'area'),
+    ],
+    'scalars': [
+        'dns_median_svc_time:warn',
+        'dns_median_svc_time:crit',
+    ],
+}
+
+perfometer_info.append({
+    'type': 'logarithmic',
+    'metric': 'dns_median_svc_time',
+    'half_value': 2,
+    'exponent': 2,
+})
diff --git a/gui/wato/squid.py b/gui/wato/squid.py
new file mode 100644
index 0000000..50bc02a
--- /dev/null
+++ b/gui/wato/squid.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2023-05-20
+
+# based on https://github.com/allangood/check_mk/tree/master/plugins/squid
+#
+# rewritten for cmk 2.x
+#
+# 2023-05-20: moved to ~/local/lib/check_mk/gui/plugins/wato
+#             renamed from check_squid.py to squid-py
+#             changed client_reqps to client_requests
+#             changed server_reqps to server_requests
+#             changed cpu_time to cpu_usage
+
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    Integer,
+    Tuple,
+    TextInput,
+    Float,
+)
+from cmk.gui.plugins.wato.utils import (
+    rulespec_registry,
+    HostRulespec,
+    RulespecGroupCheckParametersApplications,
+    CheckParameterRulespecWithItem,
+    Levels,
+)
+
+from cmk.gui.cee.plugins.wato.agent_bakery.rulespecs.utils import (
+    RulespecGroupMonitoringAgentsAgentPlugins,
+)
+
+
+def _valuespec_squid():
+    return Dictionary(
+        title=_('Squid Web Proxy (Linux)'),
+        elements=[
+            # ('client_requests',
+            #  Tuple(
+            #      title=_('Set levels for Client Requests'),
+            #      elements=[
+            #          Integer(title=_('Warning at'), default_value=600, unit='/s'),
+            #          Integer(title=_('Critical at'), default_value=800, unit='/s'),
+            #      ])),
+            # not sure if client hits as upper levels are use full
+            # ('client_hits',
+            #  Tuple(
+            #      title=_('Set levels for Client Hits'),
+            #      elements=[
+            #          Integer(title=_('Warning at'), default_value=600, unit='/s'),
+            #          Integer(title=_('Critical at'), default_value=800, unit='/s'),
+            #      ])),
+            # ('server_requests',
+            #  Tuple(
+            #      title=_('Set levels for Server Requests'),
+            #      elements=[
+            #          Integer(title=_('Warning at'), default_value=600, unit='/s'),
+            #          Integer(title=_('Critical at'), default_value=800, unit='/s'),
+            #      ])),
+            # ('cpu_usage',
+            #  Tuple(
+            #      title=_('Set levels for Squid CPU usage'),
+            #      elements=[
+            #          Float(title=_('Warning at'), default_value=60.0, unit='%'),
+            #          Float(title=_('Critical at'), default_value=80.0, unit='%')
+            #      ])),
+            ('client_requests',
+             Levels(
+                 title=_('Set levels for Client Requests'),
+                 unit='/s',
+             )),
+            ('client_hits',
+             Levels(
+                 title=_('Set levels for Client Hits'),
+                 unit='/s'
+             )),
+            ('server_requests',
+             Levels(
+                 title=_('Set levels for Server Requests'),
+                 unit='/s',
+             )),
+            ('cpu_usage',
+             Levels(
+                 title=_('Set levels for Squid CPU usage'),
+                 unit='%',
+                 default_levels=(60.0, 80.0)
+             )),
+            ('dns_time',
+             Tuple(
+                 title=_('Set levels for DNS response time'),
+                 elements=[
+                     Float(title=_('Warning at'), default_value=2.0, unit='seconds'),
+                     Float(title=_('Critical at'), default_value=4.0, unit='seconds'),
+                 ])),
+        ]
+    )
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name='squid',
+        group=RulespecGroupCheckParametersApplications,
+        match_type='dict',
+        parameter_valuespec=_valuespec_squid,
+        title=lambda: _('Squid Web Proxy'),
+        item_spec=lambda: TextInput(
+            title="Squid counter",
+            help='Service name without "Squid" i.e. "DNS response time"',
+        ),
+    ))
+
+
+def _valuespec_agent_squid():
+    return Dictionary(
+        help=_('The plugin <tt>squid</tt> allows monitoring of Squid Web Proxies.'),
+        title=_('Squid Web Proxy (Linux)'),
+        elements=[
+            ('port',
+             Integer(
+                 title=_('Port number'),
+                 help=_('TCP port number that squidclient connects to.'),
+                 default_value=3128,
+             )
+             )
+        ]
+    )
+
+
+rulespec_registry.register(
+    HostRulespec(
+        group=RulespecGroupMonitoringAgentsAgentPlugins,
+        name='agent_config:squid',
+        valuespec=_valuespec_agent_squid,
+    )
+)
diff --git a/packages/squid b/packages/squid
new file mode 100644
index 0000000..f3fa9cf
--- /dev/null
+++ b/packages/squid
@@ -0,0 +1,18 @@
+{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)',
+ 'description': 'Squid3 Health Check\n'
+                '\n'
+                'based on Allan GooD - allan.cassaro@gmail.com work. \n'
+                'See https://github.com/allangood/check_mk\n'
+                '\n'
+                'Rewritten for CMK 2.1.x\n',
+ 'download_url': 'https://thl-cmk.hopto.org',
+ 'files': {'agent_based': ['squid.py'],
+           'agents': ['bakery/squid.py', 'plugins/squid'],
+           'checkman': ['squid'],
+           'gui': ['wato/squid.py', 'metrics/squid.py']},
+ 'name': 'squid',
+ 'title': 'Squid3 Health Check',
+ 'version': '2.0.2-2023-05-21',
+ 'version.min_required': '2.1.0b1',
+ 'version.packaged': '2.1.0p21',
+ 'version.usable_until': None}
\ No newline at end of file
diff --git a/squid-2.0.2-2023-05-21.mkp b/squid-2.0.2-2023-05-21.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..368a74d4dd298243d899efaa2fea6214f20e0870
GIT binary patch
literal 4687
zcmZvfWmFRm|HVZRL0U?r1`@*P6p4u=q-%g6FvQU!N=r(2jjkchhK{a*ARPh&BqRhy
z;y1cSZhy}|&iS9`d0yQY_r>>oUflD&mph(<0wwJNyGitX=j{v=l@gN>lM<DZkdhXa
zkQJ4Z6mxTZdt=8sz;~g=1HXL1RO!*2j^^KVRx~ZiU;lAA*!upAPrq5&CM&ua5KE(8
zN9HsjzZHB+dqd?(Tsq8sduOR&8Ij2MRwA42MtHPp!j^bgxTXg8TP3b<22ajCCGOME
zk^ebxdc;MOlpK{392gkr_2lBV!H4X3iebETg#0s?ACk~psggYXeZzsT;4IMh){fWb
zlk4WHBVPb#feLhI8H}G6G%8dR6zug^qZVlbQ@8#Qdv^oXf{U95%vZhC3$UGM8sX`-
z5P`AR8XJ83LqKeO(BUik{8X{pKDzI<Z1p9-mNQ)!PIMn47Re?Y(;!k8&x9=Aan)&6
zH+!86BVsv}hn(5Sjt~#X>SypNJEUJ?t;UcBEUIey%Y;Pg(a`f-PG!tt?8{W!t<0JT
z39zM~ow6r$gpx$KlMs>>t;v=W+L|@BkvYX4485<Ljiq)^tV$9KD}DusIfRr?xQUl+
z(?2*~Dch3HFdGv#wO$Aw>(s4Hus+}KUsny?%RL<Qeva_*7VO3E$TDjSJMc!fEtbem
zi&LVVd*LinGMDQ$iraLWKM6*@kH!o0TxXkk@96S6(}RDsfPj+`O-F3osUSKXT{{P?
zl1rb8ueyCZRiMA`haaS3XCX(O7Qcu|gb)di^ef`ffzt;9QR^zi<ea!3A>(^VbcmLb
z#fwXsVu;YIXob@NzXRx%B~heoYO$Waeny$f4p$I*Cm}V!@hoUg_uBU8&S1JuCXPQ#
zB%8^quGHZA?U<H8_)&(?tqtI#^a6Lrd~xSH%Rm`JYJe(c>HhcljaU;VCVOm^ve+XV
zbs%T8KK$b6_Pgh>qBiS~2d}W;=F5SwnO}OpDGHZ}bOS2^T|~MILCv6JqCx1?tkT4V
z`&%g$qe4y1+qlE(5GCUi(0#ln=|^_zq$GsbmEfu^OWRT))lc+Bh@sMDh0RFu(#T1`
zRHwjiQC;#Yqd#moLZeQ;?e4`l%GmSbORG{DL|2+T8XTk{xH{llIG8+Dk-C$5<hS0c
zf01BC$BzRlG-sz=2;HI&y4WY5;bSybR3jbD8AW~^imD4HHLlm{xABbPN`AQW*{$Ds
z3YaisJX0xAaD&A5@qxO^5LH2n_gfnE!w*;PSSpT%t@pbk;;IzswKG<(;!zB65+El7
zGx#!Jgg2W+hy^8&>G;#<DXgv4COF8$)IaR80rRQS6BhLL9RBQmCs{14{)QBGBcku+
zJvA%%r&q~sMVgdM18&PjpC(dHdfdS^V((_*$0Ob?+N>C=(GfKb6K=!Cy-ZHb`U${(
z+@+GG#w#++<sBM=|3~)ZheI55w-Qa9cQw-gELCIHFti{d4OC%Nat$cbHB7Sf#Mr7I
zj9INe@l1XLG9>pg;vaH$$Q_R|qdb4+q?v%4S+J9cJ;`EWHR+MVb)@%WBBp39z9!^D
z_4v3oIBO#SCWj~b0u)C9XmMQwFRrxL8#h;z-YBllpW59yCp)kw4#SEz4l^ZX=hd|V
zsfFdgSegziQsjhQ<4ZZp0!7b(YxC0cb<};ldi+|bi<5$@vJ66B5sx5I>@1L5eZ1mM
znF7g3)^)Z+>~7e-LdWKODeyz_NHmLK5Fvxwc1DeM$n%hTp5mB88xs6m%0bN0V!d}b
z3%+4GT$I|t#-$moeN#3^ZlE-lj}G#J9_^BgR)xi(j?}kxP{<jwL!YADGUjgLSJC~A
z;TA@F=efsU>lm%`BM(d`7f-T{R*N6iTwCZ~toyywga?M@F<~tiiky6;;@@qye*E+!
z*L9WMNow?N(lC<_-|(vb;_TCcdkEzckF7nh_M{L)WfIkH<nZ-$gc}5m&I~cb%$gO?
zBs?F>{-FuE1zW6nuOBpvoJoz-!07etF?R)DOlYsT>@e-T+HCS@p81KS(a*eE-L(z?
z`Yz`(rY9qFHV-qm+>Q1cJ1Z=O#HpgLI5%6VROPAWRPN`ftl9ZGI$R#H`;M6hZ1IyJ
z&9|@1vzOJR0T(_fe(tDys50H$<d;&T5p&;~y(HtdI>ZEu$k|*xl`1n_FhLJy;m<Hx
zt`iNYa^mO5L3v48G3ScD?Rt&Do}B?HcFB`_`dCl~`Kd&c9r^b>(fh%0tnYbd!i3Lg
zFUDQG;DfkGzh9zn#AHj`lE6u%Uwia;dl*_Na5}|wSd_xT>9W!L?dk5TTH5s*u2B1G
z*GrZ*A0OO_nekI+5$aycjJ+bk^qOQu*e8)e6$EdNfy@1HwC|9WHv*kAIh~TLW*}##
zIy6~X)13>W;>r5nXhl)RXm%w1#s0HThe(SzQr>_yR8$qjOe~dlcLS-aY{#5qzBq8!
zS@XKR&(bOR8;(a=VH?v?hB!=>ny(O>l|9TqlB5wnVr9GprxuHs^`A}+8F$NqWC4F-
z_&ur&lj~&lOqS}LnTY_jOn!M4KmVK5r_7Sm{J^_TZv3L!?kfB~mM?UXC+kR~=Dv$@
zdt8)S6@Y}{qKT4kJWPm7C&YAn@8zwaAe4-09{c>E3<v=*@2GQpxU`vm^IVJ*dT5jT
z8LGo+zWiaxsX@OC6isjdht$Fp%K?DA_1*2cb&UH{%Yp0QXr(>;LcyJG*pM+8f><$S
zT-T>Z&?&+ecOi7)DHf}4Tlz1M%za$;=`Yk5n%K`YrO9rFJ^|2E{I?KnpJ5+@=6_?u
zZx;|bRxY6iq^+Ni2JK&ih;w_%(Sj(#?VdD(7Brv8K|SC{I1&Ot1+pvMLRx1F+acqa
z)>cXTKmR;liHUeLKPvz{N2!9pP)ITe)~txr46HY?iU{)Aerf!cAC*<0pcL{wyKQBA
zO2jP0(~o%isp!iSDd&{<jBis>B^OycnRX7+vsy4o_Ek`L_8FvLIK6EZp?MZ}w-Kb<
zF?{8_Pl1R(t{y_RC`$Q0*xUzT_`AXu$=|7!IyjKxA2Iw7&i_*VtMn2>Dod=A-(MV&
zY=ABW1qJ_-Xc=M#&n7lO3VRmb1WyXOw4=fY&$u{afT{xzl!)g{UoS!29>j{{TpWqX
zdj@rX&WA7N7)IkEyRtw%&g>u!pQmlMUciA|pt@<b7)9mo*i<!>sjqsJ+>eEVGI<c9
z2Rq3RryUiCLlV-GhZRLb-YTQ+-=c%J@hpWv3OC@fgln07*4;Xj7Ha7>rMFtG7}qX1
zzP_0Qkm;Mw6la)~TnSViYh>pki#Rj;TD}L$b+_rfJmx-UrVxpF5Un5C^m)}KyjzqC
zO$WDHSdzIe1~JVFKaoZV6eg|)$JKFYw+59m$XnFm*1G9^@`IV<Y~=dz>(d3nl;nQG
z5^-XUIFU@u>d<uUOx(QZeZ7zx<;+ET%a$h(kexg7PS2_~vY_cGQuna4=qFutDl1p+
zTW6qW>mel*XKEviw|o8&B$J2+GKBbA?!fPxcuc7Ux6QO$lV^8ji|*~kwtKY#`&HBK
zS^b!Nh&7*8hlV2i7K{g}l0NWt`c~&d2Nq>-=|8`#&gW11;)R=Rr_<aEv!hvo{uHDP
zN(|=OoMJqwr~2kT6q{VM{p-IMZgAaNL9Kvu%5KMkbM$P0{%13%FI$rQjl-zk<w&w6
zw2`J&zR;ZAl%(#`LD>YP9->}+81!e;vx(6Z=eb<yw5ZryzJ7ap(bGWr_>l#(OxNc&
zDi1A8`W1i0rhN%%D=$&lCg7l}BCixVA>&!x->o-y#p$#<4o24ndOW|-iI<#Qv-u|t
zIwV#6QmX7MV?V}=P4ZVKG?vkGvLJr%=PkAkO2!<C*Wci3Mk`~uunuu8cm3)B-WUqD
zj;jq-F*$ED66X#-9%Neo{^8oU@_QbIs;~6UV7@-!y0I2^2VrmVs7bV@;ZG!sNuNO5
zdD~#T?3CA&Yj_DCsb&9A0-XIH4ha%~NJA+62f<39t9>q<oRUU{S1xOh!ze_IEo1dQ
zO%xUwDK!YmH96L(v<N>TRN)^p*h%2nWJd^VOCwQXY*Um;5&tnK#Cy;CcmHq^lzw;<
zjw+$=2%df(VH=>roAPpW{>dC<!J1ci!q9})eWEp46Y~ZrN#h>zTI<6GsMG#$Fw5B-
zC+bfV&$yNxDoioFKLXZNvy>7b4@s4?y0xddlC^r&kyd5<M&9=Pk~i!XoEs`Nf+Zl-
z?7P2O3lY~1amlb7k}Sp*9EMh0)3qfpyu0@su{fzjfDc2ojfdGmSn%)aYYF{s9s;2I
zyZ7<0_2Pu%XQ-Nbp%szL;;e7`rhu?AedTg{0+R%R=Y6U1Bow5f$}t@O7F++srn;Lx
zw^50?x8ZDqO*I$q=;T+eo~^8PBoO<1Nz6hQqy_BLe^vVp+=%@8Njonr<-E1T{7|Om
z%AE7D{ri14U{xd^t!*1UzhZU5RSc?~#?Pe@?&l2p&ZdwYCf;0nqLFX)W=m5KsX1G`
zkF)0~U67ufXZYvB!g%(xhl|n8;k0beIuJ_YCtrN{!Y*VDogoCCT(z`N04=1_Me)hq
zM)1+Bm9P9BYH^YL;qP+18TSe1e+NO9n`l0Ca?WK{J<pB{{z@7DK)9PkAUas><0Cui
z;+sMOGj*YS<gD#6%GGEG;jrh#Ov}{Y^~6BgzsKL4s|uJ3-X)IEd@*IW#=j)bKyM#k
zF&c?*yBI3m*>TmE{(jXax-L??_;TbX_RH(mZ;XPZrW5&{eKa~SSsQ;dpmn6Ye+|qO
zUHNcYtf&c(yQFF=0WZ(OWUc>@c)0Dc=2|VYF(*&X<n;ErA?3s^oddFHWe;+yE>6v8
z#+HIaZbhLdi^?5ArBJ#fv23zXw8%k+bwE4!!c%<5FmzK0>p6NXTR6kTIJ3CuqFl#x
zq~m&I4<I>z?ca&3OE`4(bhM8pT{Z#t0%x8(@OT~#Z8j*m@1&PkAif|*cPQub%UPBp
zZmx+8iI-u`nEM3Ev*nn9f-!wm(9z;^^C_wdjk~Td5G2^7;Hp5qmE0-5(L|QHDKEVU
zSMw3<^kds)3k=ikhR(rotM*@4Wg~>*+snOMEL}9=eJ&V%dJ?g?eh(pO?|`6iWQa~j
zr`hf_F8`%YrwZ#92gnBN1erUOjx@lowNX%t{s!i;>UV)R4v;;4PiH@^Lbm-@{_dea
zGuMlqJviXVOw(9>5L=c5B*>_dUbDmak&y4ma7Rfa@|fmpoct-I#qG56#RtU|Vm`G-
z_-mrC7w-xvF$x?=WXBVmc8Qb(t*ucTFMVi{_ESpA+|PMt(~8=ZvnaQ0ScL&Y<(mw$
zPrldcAMa+Sa-tiSYviD0E-8$$b|K|o*C(Ih>Do}Qps7MeB&&%M#df_7+DCp=ewHq1
zTirqPo}~A-Lms~?0&()Ot2PdR@_9TqUpMw8WTIzmFU=&o260T=j&$hIDbdjWyC-Q`
zqd4%>m!3e`S;44m#V*oU0Eh8j`f8~9A^xKyxZB#E$Fynj;j_HPSyt(JGwQ@*z`V^M
z9u9M5=xK<tV^ehTjsN*<%WAFc=yV329A!GZGa=^c)*3RAGnv?KV2yHiHm+MTZzzU0
zCgw7I2;Y!U0vqU5kZDXFeRx#Z)v#&F9m8icKD)vA`C|U3hP8e9-Jrv!&Mw<pTTOLJ
zSF-%YuW<D|nyFNU8gj`x<K4|fmq_R9sciWw(4ho)&#B24j^;FKbLvsf<$z5cl{Hbr
zJ}E5Jqe|z5bVcnm$a1}@uFHnQgLNEB4$SoqCEG{7r29P)Uw)m8>it}xG-or{w&P}r
zsv9uFp%`{|tC*?f9=kA)a($5*@>#a=hw8XhosJ^R-pJsf^g!~WBLmzUy(M97Qv5-a
zs;0iM@LZhW?(!M|?DqE)oiLkLvco*wnvz6?s_%1~?(C)M=5eV6)g&9RDn{96T?U*K
ztKwga)_M5I)79Q?iQ;H-uXU{`FN3)4Pn)jpw{-BjQdJ>MjL^l^OVCe}s-}{7<Zj#*
zyDU__eu6?9Nc)`@yor5*#55O;&+Lbl(I}X^&Pv|#kB!d2JS@)G5uH*YrKe3(ySO#N
lCjgVe(e9By{l7Z+uf^&ASH*wxR=CbUFM{bDZtUN<@n4a{Dh2=m

literal 0
HcmV?d00001

diff --git a/squid.mkp b/squid.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..368a74d4dd298243d899efaa2fea6214f20e0870
GIT binary patch
literal 4687
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

literal 0
HcmV?d00001

-- 
GitLab