Функция BaseCommand.print() печатает аргумент на stdout, всегда используйте ее, вместо встроенной функции print() в командах. В данном случае мы печатаем версию.
В качестве примера вынесем код проверки настроенных метрик в команду. Добавим возможность передавать список метрик через параметры. Расположим код в файле commands/check-metrics.py:
Мы проверяем, заданы ли парамеры командной строки (option["metrics"]), если нет - вызываем функцию BaseCommand.die(). Функция die() печатает сообщение об ошибке в stderr и завершает работу команды с системным кодом ошибки().
Нам необходимо по имени метрики получить ее объект (запись в базе). В NOC для получения записи по имени используются методы моделей .get_by_name(). Помимо упрощения кода .get_by_name() также обеспечивает кеширование, что может сильно повышать производительность.
Если запись не найдена, .get_by_name() возвращает None. Мы используем проверку на None, чтобы убедиться, что пользователь правильно указал имя метрики. Если пользователь указал неверное имя, мы печатаем сообщение и переходим к обработке следующей метрики.
Если пользователь задал хоть одну интерфейсную метрику, вызываем функцию check_interface_metrics и передаем ей в качестве параметра список interface_metrics
check-metrics.py
3839404142434445464748495051
defcheck_object_metrics(self,metrics:List[MetricType]):mt_check:Dict[str,MetricType]={str(mt.id):mtformtinmetrics}formopinManagedObjectProfile.objects.filter(enable_periodic_discovery_metrics=True,enable_periodic_discovery=True):checks=set(mt_check)formcinmop.metrics:ifmc["metric_type"]inchecks:checks.remove(mc["metric_type"])ifchecks:self.print(f"[{mop.name}] Not configured metrics: ",",".join(mt_check[c].nameforcinchecks),)
Определим функцию check_object_metrics, которая принимает на вход список объектных метрик.
check-metrics.py
3839404142434445464748495051
defcheck_object_metrics(self,metrics:List[MetricType]):mt_check:Dict[str,MetricType]={str(mt.id):mtformtinmetrics}formopinManagedObjectProfile.objects.filter(enable_periodic_discovery_metrics=True,enable_periodic_discovery=True):checks=set(mt_check)formcinmop.metrics:ifmc["metric_type"]inchecks:checks.remove(mc["metric_type"])ifchecks:self.print(f"[{mop.name}] Not configured metrics: ",",".join(mt_check[c].nameforcinchecks),)
Мы строим словарь mt_check, который в качестве ключа использует id метрики, а в качестве значения хранит объект метрики.
check-metrics.py
3839404142434445464748495051
defcheck_object_metrics(self,metrics:List[MetricType]):mt_check:Dict[str,MetricType]={str(mt.id):mtformtinmetrics}formopinManagedObjectProfile.objects.filter(enable_periodic_discovery_metrics=True,enable_periodic_discovery=True):checks=set(mt_check)formcinmop.metrics:ifmc["metric_type"]inchecks:checks.remove(mc["metric_type"])ifchecks:self.print(f"[{mop.name}] Not configured metrics: ",",".join(mt_check[c].nameforcinchecks),)
Мы извлекаем все профили объекта, для которых включен periodic discovery и заданы метрики.
check-metrics.py
3839404142434445464748495051
defcheck_object_metrics(self,metrics:List[MetricType]):mt_check:Dict[str,MetricType]={str(mt.id):mtformtinmetrics}formopinManagedObjectProfile.objects.filter(enable_periodic_discovery_metrics=True,enable_periodic_discovery=True):checks=set(mt_check)formcinmop.metrics:ifmc["metric_type"]inchecks:checks.remove(mc["metric_type"])ifchecks:self.print(f"[{mop.name}] Not configured metrics: ",",".join(mt_check[c].nameforcinchecks),)
Мы строим множество check по ключам mt_check. В дальнейшем мы будем убирать из него найденные метрики.
check-metrics.py
3839404142434445464748495051
defcheck_object_metrics(self,metrics:List[MetricType]):mt_check:Dict[str,MetricType]={str(mt.id):mtformtinmetrics}formopinManagedObjectProfile.objects.filter(enable_periodic_discovery_metrics=True,enable_periodic_discovery=True):checks=set(mt_check)formcinmop.metrics:ifmc["metric_type"]inchecks:checks.remove(mc["metric_type"])ifchecks:self.print(f"[{mop.name}] Not configured metrics: ",",".join(mt_check[c].nameforcinchecks),)
Мы проходим по всем метрикам, заданным в профиле, и, если они присутствуют в нашем check, удаляем их из множества check.
check-metrics.py
3839404142434445464748495051
defcheck_object_metrics(self,metrics:List[MetricType]):mt_check:Dict[str,MetricType]={str(mt.id):mtformtinmetrics}formopinManagedObjectProfile.objects.filter(enable_periodic_discovery_metrics=True,enable_periodic_discovery=True):checks=set(mt_check)formcinmop.metrics:ifmc["metric_type"]inchecks:checks.remove(mc["metric_type"])ifchecks:self.print(f"[{mop.name}] Not configured metrics: ",",".join(mt_check[c].nameforcinchecks),)
Если в нашем множестве checks остались мерики, пишем сообщение, что они не сконфигурированы для профиля.
check-metrics.py
53545556575859606162
defcheck_interface_metrics(self,metrics:List[MetricType]):foripinInterfaceProfile.objects.filter(metrics__exists=True):checks=set(metrics)formcinip.metrics:ifmc.metric_typeinchecks:checks.remove(mc.metric_type)ifchecks:self.print(f"[{ip.name}] Not configured metrics: ",",".join(c.nameforcinchecks))
Определим функцию check_interface_metrics, которая принимает на вход список интерфейсных метрик.
check-metrics.py
54555657585960616263
defcheck_interface_metrics(self,metrics:List[MetricType]):foripinInterfaceProfile.objects.filter(metrics__exists=True):checks=set(metrics)formcinip.metrics:ifmc.metric_typeinchecks:checks.remove(mc.metric_type)ifchecks:self.print(f"[{ip.name}] Not configured metrics: ",",".join(c.nameforcinchecks))
Мы проходим по всем профилям интерфейсов, для которых сконфигурированы метрики.
check-metrics.py
54555657585960616263
defcheck_interface_metrics(self,metrics:List[MetricType]):foripinInterfaceProfile.objects.filter(metrics__exists=True):checks=set(metrics)formcinip.metrics:ifmc.metric_typeinchecks:checks.remove(mc.metric_type)ifchecks:self.print(f"[{ip.name}] Not configured metrics: ",",".join(c.nameforcinchecks))
Мы строим множество checks из всех элементов входных параметров функции
check-metrics.py
54555657585960616263
defcheck_interface_metrics(self,metrics:List[MetricType]):foripinInterfaceProfile.objects.filter(metrics__exists=True):checks=set(metrics)formcinip.metrics:ifmc.metric_typeinchecks:checks.remove(mc.metric_type)ifchecks:self.print(f"[{ip.name}] Not configured metrics: ",",".join(c.nameforcinchecks))
Мы проходим по всем метрикам, заданным в профиле, и, если они присутствуют в нашем check, удаляем их из множества check.
check-metrics.py
54555657585960616263
defcheck_interface_metrics(self,metrics:List[MetricType]):foripinInterfaceProfile.objects.filter(metrics__exists=True):checks=set(metrics)formcinip.metrics:ifmc.metric_typeinchecks:checks.remove(mc.metric_type)ifchecks:self.print(f"[{ip.name}] Not configured metrics: ",",".join(c.nameforcinchecks))
Если в нашем множестве checks остались мерики, пишем сообщение, что они не сконфигурированы для профиля.
check-metrics.py
6566
if__name__=="__main__":Command().run()
Эта часть кода является общей для всех команд и отвечает за запуск нашей команды из командной строки.