Sistema de Informações Gerenciais do Interlegis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

253 lines
9.2 KiB

import json
import shutil
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext as _
from django_extensions.management.jobs import DailyJob
from sigi.apps.servicos import generate_instance_name, nomeia_instancias
from sigi.apps.servicos.models import Servico, TipoServico
from sigi.apps.casas.models import Orgao
from sigi.apps.utils.management.jobs import JobReportMixin
class Job(JobReportMixin, DailyJob):
help = _("Sincronização dos Serviços SEIT na infraestrutura")
report_template = "servicos/emails/report_sincroniza_rancher.rst"
nomes_gerados = None
errors = {}
infos = {}
def do_job(self):
self.nomes_gerados = {
generate_instance_name(o): o
for o in Orgao.objects.filter(tipo__legislativo=True)
}
for tipo in TipoServico.objects.filter(modo="H").exclude(
tipo_rancher=""
):
self.process(tipo)
try:
shutil.rmtree(settings.HOSPEDAGEM_PATH)
except Exception as e:
pass
self.report_data = {
"erros": self.errors,
"infos": self.infos,
}
def process(self, tipo):
nomeia_instancias(
servicos=Servico.objects.filter(
tipo_servico=tipo, data_desativacao=None, instancia=""
),
user=self.sys_user,
)
NAO_CONSTA = "*não-consta-no-rancher*"
self.errors[tipo] = []
self.infos[tipo] = []
file_path = settings.HOSPEDAGEM_PATH / tipo.arquivo_rancher
if not file_path.exists() or not file_path.is_file():
self.errors[tipo].append(_(f"Arquivo {file_path} não encontado."))
return
json_data = json.loads(file_path.read_text())
portais = [
item
for item in json_data["items"]
if item["kind"].lower() == "app"
and item["spec"]["chart"]["metadata"]["name"] == tipo.tipo_rancher
]
namespaces = [
item
for item in json_data["items"]
if item["kind"].lower() == "namespace"
]
encontrados = 0
novos = 0
desativados = 0
self.infos[tipo].append(
_(f"{len(portais)} {tipo.nome} encontrados no Rancher")
)
# Atualiza portais existentes e cria novos #
for p in portais:
namespace = p["metadata"]["namespace"]
name = p["metadata"]["name"]
if tipo.spec_rancher in p["spec"]["values"]:
if "hostname" in p["spec"]["values"][tipo.spec_rancher]:
hostname = p["spec"]["values"][tipo.spec_rancher][
"hostname"
]
elif "domain" in p["spec"]["values"][tipo.spec_rancher]:
hostname = p["spec"]["values"][tipo.spec_rancher]["domain"]
else:
hostname = NAO_CONSTA
self.errors[tipo].append(
_(
f"Instância {namespace} de {tipo.nome} sem URL no "
"rancher"
)
)
if "hostprefix" in p["spec"]["values"][tipo.spec_rancher]:
prefix = p["spec"]["values"][tipo.spec_rancher][
"hostprefix"
]
hostname = f"{prefix}.{hostname}"
elif tipo.prefixo_padrao != "":
hostname = f"{tipo.prefixo_padrao}.{hostname}"
else:
hostname = NAO_CONSTA
self.errors[tipo].append(
_(
f"Instância {namespace} de {tipo.nome} sem URL no rancher"
)
)
nova_versao = (
p["spec"]["values"]["image"]["tag"]
if "image" in p["spec"]["values"]
else ""
)
if NAO_CONSTA in hostname:
nova_url = ""
else:
nova_url = f"https://{hostname}/"
try:
portal = Servico.objects.get(
instancia=namespace,
tipo_servico=tipo,
data_desativacao=None,
)
encontrados += 1
except Servico.MultipleObjectsReturned:
self.errors[tipo].append(
_(
f"Existe mais de um registro ativo da instância {namespace}"
f" de {tipo}."
)
)
continue
except Servico.DoesNotExist:
if (
namespace in self.nomes_gerados
or name in self.nomes_gerados
):
orgao = (
self.nomes_gerados[namespace]
if namespace in self.nomes_gerados
else self.nomes_gerados[name]
)
portal = Servico(
casa_legislativa=orgao,
tipo_servico=tipo,
instancia=namespace,
url=nova_url,
versao=nova_versao,
data_ativacao=p["spec"]["info"]["firstDeployed"][:10],
hospedagem_interlegis=True,
)
portal.save()
self.admin_log_addition(portal, "Criado no Rancher")
novos += 1
self.infos[tipo].append(
_(
f"Criada instância {namespace} de {tipo.nome} para "
f"{orgao.nome} ({orgao.municipio.uf.sigla})"
)
)
else:
self.errors[tipo].append(
_(
f"{namespace} ({hostname}) não parece pertencer a "
"nenhum órgão."
)
)
continue
# Verificar se tem registro de suspensão do namespace
if namespace == "acegua-rs":
breakpoint()
suspenso = [
ns["metadata"]["annotations"]["suspenso"]
for ns in namespaces
if ns["metadata"]["name"] == namespace
and "suspenso" in ns["metadata"]["annotations"]
]
if suspenso:
# Desativar o portal no SIGI
portal.data_desativacao = timezone.localdate()
portal.motivo_desativacao = (
"Suspenso no Rancher com os seguintes apontamentos:"
+ ", ".join([f'"{s}"' for s in suspenso])
)
portal.save()
self.admin_log_change(portal, portal.motivo_desativacao)
# atualiza o serviço no SIGI
if (
nova_versao != portal.versao
or nova_url != portal.url
or not portal.hospedagem_interlegis
):
message = (
"Atualizado no Rancher: "
+ (
f"Versão: de '{portal.versao}' para '{nova_versao}' "
if portal.versao != nova_versao
else ""
)
+ (
f"Url: de '{portal.url}' para '{nova_url}' "
if portal.url != nova_url
else ""
)
+ (
f"hospedagem interlegis"
if not portal.hospedagem_interlegis
else ""
)
)
portal.versao = nova_versao
portal.url = nova_url
portal.hospedagem_interlegis = True
portal.save()
self.admin_log_change(portal, message)
# Desativa portais registrados no SIGI que não estão no Rancher #
nomes_instancias = [p["metadata"]["name"] for p in portais]
for portal in Servico.objects.filter(
tipo_servico=tipo,
data_desativacao=None,
hospedagem_interlegis=True,
):
if (
portal.instancia == ""
or portal.instancia not in nomes_instancias
):
portal.data_desativacao = timezone.localdate()
portal.motivo_desativacao = _("Não encontrado no Rancher")
portal.save()
self.admin_log_change(portal, "Desativado no Rancher")
self.infos[tipo].append(
f"{portal.instancia} ({portal.url}) de "
f"{portal.casa_legislativa.nome} desativado pois não "
"foi encontrado no Rancher."
)
desativados += 1
self.infos[tipo].append(
_(f"{encontrados} {tipo.nome} do Rancher encontrados no SIGI")
)
self.infos[tipo].append(
_(f"{novos} novos {tipo.nome} criados no SIGI")
)
self.infos[tipo].append(
_(f"{desativados} {tipo.nome} desativados no SIGI")
)