from .services.base_service import Base_service
import sys
import os
from py_module.whiptail import Whiptail
import py_module.yaml as yaml
import py_module.docker as docker
import py_module.jinja2 as jinja
import shutil
import subprocess
import string
import uuid
import time 
from .docker_installer import Docker_installer
from .services import *


class CS_Update(Base_service):
    def preload(self):
#        with Docker_installer(logger_level = self.logger_level) as run:
#            pass
        self.menu = (
            ('cs-rabbitmq','Р7-КС24: MQTT-служба очередей','ON'),
            ('cs-postgres','Р7-КС24: Служба базы данных','ON'),
            ('cs-filestorage','Р7-КС24: Служба файлового хранилища','ON'),
            ('cs-searchapi','Р7-КС24: Служба поиска','ON'),
            ('cs-registry','Р7-КС24: Реестр служб','ON'),
            ('cs-ssoapi','Р7-КС24: Служба авторизации SSO','ON'),
            ('cs-api','Р7-КС24: Служба API','ON'),
            ('cs-processing','Р7-КС24: Служба процессинга','ON'),
            ('cs-draw','Р7-КС24: Компонент Р7-Графика','ON'),
            ('cs-frontend','Р7-КС24: Веб-интерфейс','ON'),
        );
        self.logger.info('Инициализирую основные переменные')

        if not self.DETALIZATION:
            self.DETALIZATION = 1
        self.INSTALL_DUMP_PATH='./images'
        self.INSTALL_CONF_PATH='./configs'
        self.INSTALL_NEW_PATH=['/opt/r7-office-docker']
        self.BACK_MENU=[False]

### ENVIRONMENT GERENAL
        self.DETALIZATION = 1
        self.CS_VERSION=['2025.3.12.15877']
#        self.DS_VERSION=['latest']
        self.DS_VERSION=['2025.3.1.923']
        self.MAIL_VERSION=['1.0.35']
        self.PREFIX_CS=['cs']
        self.PREFIX_DS=['ds']
        self.PREFIX_MAIL=['mail']
        self.PREFIX_TEAM=['team']

        self.GENERAL_NODE_LOGS_STORAGE=['./support_logs']

        self.CS_NODE_FRONTEND_CERT_CRT_PATH=['./configs/ssl']
        self.CS_NODE_FRONTEND_CERT_CRT_FILE=['fullchain.crt']
        self.CS_NODE_FRONTEND_CERT_KEY_PATH=['./configs/ssl']
        self.CS_NODE_FRONTEND_CERT_KEY_FILE=['privkey.key']

        self.CS_NODE_PSQL_STORAGE=['./data/db/cs_database']
        self.CS_NODE_FILE_STORAGE=['./data/cs_storage/root']
        self.CS_NODE_INDEX_STORAGE=['./data/search_index']

        self.DS_NODE_PSQL_STORAGE=['./data/db/ds_database','./data/db/ds_database']
        self.DS_NODE_FILE_STORAGE=['./data/ds_storage','./data/ds_storage']
        self.DS_NODE_LICENSE_FILE=['./license/license.lic']

        self.MAIL_NODE_PSQL_STORAGE=['./data/db/mail_database']
        self.MAIL_NODE_MAILDIR_STORAGE=['./data/mail_storage/maildir']
        self.MAIL_NODE_DKIM_STORAGE=['./data/mail_storage/dkim_keys']

#env for published port of services on node
        self.CS_NODE_API_PORT_PUBLISHED=['38033']
        self.CS_NODE_RABBIT_PORT_PUBLISHED=['5672']
        self.CS_NODE_PSQL_PORT_PUBLISHED=['5432']
        self.CS_NODE_DRAW_PORT_PUBLISHED=['3005']
        self.CS_NODE_FILESTORAGE_PORT_HTTP_PUBLISHED=['11580']
        self.CS_NODE_FILESTORAGE_PORT_TCP_PUBLISHED=['11581']
        self.CS_NODE_SEARCH_PORT_PUBLISHED=['2664']
        self.CS_NODE_SSO_PORT_PUBLISHED=['38034']
        self.CS_NODE_REGISTRY_PORT_PUBLISHED=['7777']

        self.DS_NODE_DOCSERVER_PORT_PUBLISHED=['8000']
        self.DS_NODE_RABBIT_PORT_PUBLISHED=['5673']
        self.DS_NODE_PSQL_PORT_PUBLISHED=['5433']
        self.DS_NODE_REDIS_PORT_PUBLISHED=['6379']

        self.MAIL_NODE_API_PORT_PUBLISHED=['8891']
        self.MAIL_NODE_PSQL_PORT_PUBLISHED=['5434']
        self.MAIL_NODE_DKIM_PORT_PUBLISHED=['8891']
        self.MAIL_NODE_MTA_PORT_SMTP_PUBLISHED=['25']
        self.MAIL_NODE_MTA_PORT_SMTPS_PUBLISHED=['465']
        self.MAIL_NODE_MTA_PORT_SMTPS_TLS_PUBLISHED=['587']
        self.MAIL_NODE_MDA_PORT_POP3_PUBLISHED=['110']
        self.MAIL_NODE_MDA_PORT_POP3S_PUBLISHED=['995']
        self.MAIL_NODE_MDA_PORT_IMAP_PUBLISHED=['143']
        self.MAIL_NODE_MDA_PORT_IMAPS_PUBLISHED=['993']

### ENVIRONMENT CS
#env for frontend
        self.CS_FRONTEND_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-frontend']
        self.CS_FRONTEND_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_FRONTEND_CONTAINER_NAME=['cs-frontend']

        self.CS_FRONTEND_HOST=['cs-frontend']
        self.CS_FRONTEND_SCHEME=['https']
        self.CS_FRONTEND_SCHEME_REDIRECT=[True]
        self.CS_FRONTEND_DOMAIN=['domain.ru']
        self.CS_FRONTEND_HTTP_PORT=['80']
        self.CS_FRONTEND_HTTPS_PORT=['443']
        self.CS_FRONTEND_PREFIX_CDDISK=['disk']
        self.CS_FRONTEND_PREFIX_PAYMENTS=['payments']
        self.CS_FRONTEND_PREFIX_PAGES=['pages']
        self.CS_FRONTEND_PREFIX_FORMS=['forms']
        self.CS_FRONTEND_PREFIX_DRAW=['draw']
        self.CS_FRONTEND_PREFIX_ADMIN=['admin']
        self.CS_FRONTEND_PREFIX_CDMAIL=['mail']
        self.CS_FRONTEND_PREFIX_CONTACTS=['contacts']
        self.CS_FRONTEND_PREFIX_CALENDAR=['calendar']
        self.CS_FRONTEND_PREFIX_PROJECTS=['projects']
        self.CS_FRONTEND_STORAGE=['/app']
        self.CS_FRONTEND_CERT_PATH=['/etc/nginx/ssl']
        self.CS_FRONTEND_CERT_CRT_FILE=['fullchain.crt']
        self.CS_FRONTEND_CERT_KEY_FILE=['privkey.key']
#env for rabbit
        self.CS_RABBIT_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-rabbitmq']
        self.CS_RABBIT_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_RABBIT_CONTAINER_NAME=['cs-rabbitmq']

        self.CS_RABBIT_HOST=['cs-rabbit']
        self.CS_RABBIT_USER=['guest']
        self.CS_RABBIT_PWD=['guest']
        self.CS_RABBIT_PORT=['5672']
        self.CS_RABBIT_CLIENT_TIMEOUT=['10']
#env for psql
        self.CS_PSQL_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-postgres']
        self.CS_PSQL_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_PSQL_CONTAINER_NAME=['cs-psql']

        self.CS_TEAM_CLIENT_ID=['']
        self.CS_TEAM_CLIENT_SECRET=['']
        self.CS_PAGES_CLIENT_ID=['']
        self.CS_PAGES_CLIENT_SECRET=['']
        self.CS_FORMS_CLIENT_ID=['empty']
        self.CS_FORMS_CLIENT_SECRET=['empty']

        self.CS_PSQL_HOST=['cs-psql']
        self.CS_PSQL_DB=['postgres']
        self.CS_PSQL_USER=['postgres']
        self.CS_PSQL_PWD=['pg_pass']
        self.CS_PSQL_PORT=['5432']
        self.CS_PSQL_DATA=['/var/lib/postgresql/data']
        self.CS_PSQL_CORE_MACHINE_KEY=['empty']
#env for draw
        self.CS_DRAW_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-draw']
        self.CS_DRAW_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_DRAW_CONTAINER_NAME=['cs-draw']

        self.CS_DRAW_HOST=['cs-draw']
        self.CS_DRAW_PORT=['3005']
#env for api
        self.CS_API_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-api']
        self.CS_API_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_API_CONTAINER_NAME=['cs-api']

        self.CS_API_HOST=['cs-api']
        self.CS_API_PORT=['38033']
        self.CS_API_LOGLEVEL=['Trace']
        self.CS_API_INTERFACE=['+']
        self.CS_API_ALLOWHOSTS=['*']
        self.CS_API_HTTP_TIMEOUT=['00:10:00']
        self.CS_API_CERT_OAUTH_FILE=['domain.pfx']
        self.CS_API_CERT_PATH=['/app/ssl']
        self.CS_API_CERT_PATHKEY=['/app/ssl']
        self.CS_API_STORAGE_TMP=['/app/tmp_storage']
        self.CS_API_ROOTNODE=['False']
#env for api and processing
        self.CS_STORAGE_S3_REGION=['region']
        self.CS_STORAGE_S3_ENDPOINT=['http://localhost/s3']
        self.CS_STORAGE_S3_BUCKET_NAME=['ds-storage']
        self.CS_STORAGE_S3_ACCESS_KEY_ID=['AKID2']
        self.CS_STORAGE_S3_SECRET_ACCESS_KEY=['SECRET']
#env for processing
        self.CS_PROCESSING_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-processing']
        self.CS_PROCESSING_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_PROCESSING_CONTAINER_NAME=['cs-processing']

        self.CS_PROCESSING_HOST=['cs-processing']
        self.CS_PROCESSING_LOGLEVEL=['Trace']
        self.CS_PROCESSING_STORAGE_TMP=['/app/tmp_storage']
        self.CS_PROCESSING_ROOTNODE=['False']
        self.CS_PROCESSING_PUSH_CERT_PATH=['None']
        self.CS_PROCESSING_GCM_AUTHKEY=['None']
        self.CS_PROCESSING_GCM_URL=['None']
        self.CS_PROCESSING_VOIP_CERT=['None']
        self.CS_PROCESSING_VOIP_CERT_PWD=['None']
        self.CS_PROCESSING_SANDBOX_CERT=['None']
        self.CS_PROCESSING_SANDBOX_CERT_PWD=['None']
        self.CS_PROCESSING_PUSH_PRODUCTION_ONLY=['None']
#env for filestorage
        self.CS_FILESTORAGE_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-filestorage']
        self.CS_FILESTORAGE_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_FILESTORAGE_CONTAINER_NAME=['cs-filestorage']

        self.CS_FILESTORAGE_HOST=['cs-filestorage']
        self.CS_FILESTORAGE_PORT_HTTP=['11580']
        self.CS_FILESTORAGE_PORT_TCP=['11581']
        self.CS_FILESTORAGE_HTTP_INTERFACE=['0.0.0.0']
        self.CS_FILESTORAGE_ALLOWHOSTS=['*']
        self.CS_FILESTORAGE_TCP_INTERFACE=['0.0.0.0']
        self.CS_FILESTORAGE_ROOTNODE=['False']
        self.CS_FILESTORAGE_LOGLEVEL=['Trace']
        self.CS_FILESTORAGE_STORAGE=['/var/filestorage']
#env for search
        self.CS_SEARCH_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-searchapi']
        self.CS_SEARCH_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_SEARCH_CONTAINER_NAME=['cs-search']

        self.CS_SEARCH_HOST=['cs-search']
        self.CS_SEARCH_PORT=['2664']
        self.CS_SEARCH_INTERFACE=['+']
        self.CS_SEARCH_ALLOWHOSTS=['*']
        self.CS_SEARCH_INDEXFOLDER=['/app/data']
        self.CS_SEARCH_LOGLEVEL=['Trace']
        self.CS_SEARCH_CLEARMEMORYINTERVAL=['00:01:00']
        self.CS_SEARCH_CLOSEINDEXINTERVAL=['0.23:30:00']
        self.CS_SEARCH_INDEXLIVEINTERVAL=['60']
        self.CS_SEARCH_NEVERCLOSEINDEX=['True']
        self.CS_SEARCH_USELOCALTERMREPOSITORY=['True']
        self.CS_SEARCH_PERCENTMEMORYUSAGE=['80']
        self.CS_SEARCH_SHARDCOUNT=['16']
        self.CS_SEARCH_AVAILABLEPHYSICALMEMORY=['8000']
#env for registry
        self.CS_REGISTRY_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-registry']
        self.CS_REGISTRY_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_REGISTRY_CONTAINER_NAME=['cs-registry']

        self.CS_REGISTRY_HOST=['cs-registry']
        self.CS_REGISTRY_PORT=['7777']
        self.CS_REGISTRY_INTERFACE=['0.0.0.0']
        self.CS_REGISTRY_ALLOWHOSTS=['*']
        self.CS_REGISTRY_LOGLEVEL=['Trace']
#env for sso
        self.CS_SSO_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/cs/cddisk-ssoapi']
        self.CS_SSO_IMAGE_VERSION=[self.CS_VERSION[0]]
        self.CS_SSO_CONTAINER_NAME=['cs-ssoapi']

        self.CS_SSO_HOST=['cs-sso']
        self.CS_SSO_PORT=['38034']
        self.CS_SSO_INTERFACE=['+']
        self.CS_SSO_ALLOWHOSTS=['*']
        self.CS_SSO_LOGLEVEL=['Trace']
        self.CS_LDAP_ENDPOINT=['']
        self.CS_LDAP_USER=['']
        self.CS_LDAP_PWD=['']
        self.CS_LDAP_LOGINPOSTFIX=['']
        self.CS_LDAP_TYPE=['ActiveDirectory']
        self.CS_SSO_IDP_METADATA=['empty']
        self.CS_SSO_SAML_SIGNATUREALGORITM=['http://www.w3.org/2001/04/xmldsig-more#rsa-sha256']
        self.CS_SSO_ISSUER=['empty']
        self.CS_SSO_SIGN_CERT=['domain.pfx']
        self.CS_SSO_SIGN_CERT_PWD=['empty']
        self.CS_SSO_CERT_VALID_MODE=['None']
        self.CS_SSO_REVOCATION_MODE=['NoCheck']


### ENVIRONMENT DS
#env for frontend
        self.DS_FRONTEND_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/ds/ds-frontend']
        self.DS_FRONTEND_IMAGE_VERSION=[self.DS_VERSION[0]]
        self.DS_FRONTEND_CONTAINER_NAME=['ds-frontend']

        self.DS_FRONTEND_HOST=['ds-frontend','ds-frontend']
        self.DS_FRONTEND_PREFIX_DOCSERVER=['doc']
        self.DS_FRONTEND_SCHEME=self.CS_FRONTEND_SCHEME
        self.DS_FRONTEND_SCHEME_REDIRECT=self.CS_FRONTEND_SCHEME_REDIRECT
        self.DS_FRONTEND_DOMAIN=self.CS_FRONTEND_DOMAIN
        self.DS_FRONTEND_HTTP_PORT=['80']
        self.DS_FRONTEND_HTTPS_PORT=['443']
#env for docserver
        self.DS_DOCSERVER_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/ds/ds-app']
        self.DS_DOCSERVER_IMAGE_VERSION=[self.DS_VERSION[0]]
        self.DS_DOCSERVER_CONTAINER_NAME=['ds-docserver']

        self.DS_DOCSERVER_HOST=['ds-docserver']
        self.DS_DOCSERVER_PORT=['8000']
        self.DS_DOCSERVER_JWT_KEY=['empty']
        self.DS_DOCSERVER_STORAGE_KEY=self.DS_DOCSERVER_JWT_KEY
#env for docserver over s3
        self.DS_STORAGE_S3_REGION=['region']
        self.DS_STORAGE_S3_ENDPOINT=['http://localhost/s3']
        self.DS_STORAGE_S3_BUCKET_NAME=['ds-storage']
        self.DS_STORAGE_S3_ACCESS_KEY_ID=['AKID2']
        self.DS_STORAGE_S3_SECRET_ACCESS_KEY=['SECRET']
#env for rabbit
        self.DS_RABBIT_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/ds/ds-rabbitmq']
        self.DS_RABBIT_IMAGE_VERSION=[self.DS_VERSION[0]]
        self.DS_RABBIT_CONTAINER_NAME=['ds-rabbitmq']

        self.DS_RABBIT_HOST=['ds-rabbit','ds-rabbit']
        self.DS_RABBIT_USER=['guest','guest']
        self.DS_RABBIT_PWD=['guest','guest']
        self.DS_RABBIT_PORT=['5672','5672']
#env for psql
        self.DS_PSQL_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/ds/ds-postgres']
        self.DS_PSQL_IMAGE_VERSION=[self.DS_VERSION[0]]
        self.DS_PSQL_CONTAINER_NAME=['ds-postgres']

        self.DS_PSQL_HOST=['ds-psql','ds-psql']
        self.DS_PSQL_DB=['postgres','postgres']
        self.DS_PSQL_USER=['postgres','postgres']
        self.DS_PSQL_PWD=['pg_pass','pg_pass']
        self.DS_PSQL_PORT=['5432','5432']
#env for redis
        self.DS_REDIS_IMAGE_NAME=['downloads.r7-office.ru:9011/r7office/ds/ds-redis']
        self.DS_REDIS_IMAGE_VERSION=[self.DS_VERSION[0]]
        self.DS_REDIS_CONTAINER_NAME=['ds-redis']

        self.DS_REDIS_HOST=['ds-redis']
        self.DS_REDIS_PORT=['6379']

### ENVIRONMENT TEAM
#env for rabbit
        self.TEAM_FQDN=['team.domain.ru']
        self.TEAM_RABBIT_HOST=['team-rabbit']
        self.TEAM_RABBIT_USER=['team']
        self.TEAM_RABBIT_PWD=['team']
        self.TEAM_RABBIT_PORT=['5672']
        self.TEAM_RABBIT_PUBLISH_PORT=['5672']
        self.TEAM_HTTPS_PUBLISH_PORT=['443']
        self.TEAM_HTTP_PUBLISH_PORT=['80']
        self.dockercli = docker.from_env();
        self.CS_TEAM_CLIENT_ID=['']
        self.CS_TEAM_CLIENT_SECRET=['']
        self.CS_PAGES_CLIENT_ID=['']
        self.CS_PAGES_CLIENT_SECRET=['']
        self.CS_FORMS_CLIENT_ID=['']
        self.CS_FORMS_CLIENT_SECRET=['']


    def postload(self, **kwarg):
        self.CS_PAGES_CLIENT_ID[0]=str(uuid.uuid4())
        self.CS_PAGES_CLIENT_SECRET[0]=str(uuid.uuid4())
        self.CS_FORMS_CLIENT_ID[0]=str(uuid.uuid4())
        self.CS_FORMS_CLIENT_SECRET[0]=str(uuid.uuid4())

        self.get_requests(**kwarg);
        if self.BACK_MENU[0]==True:
            return
        self.load_images(['cddisk-api.tar.gz','cddisk-draw.tar.gz','cddisk-filestorage.tar.gz','cddisk-frontend.tar.gz','cddisk-postgres.tar.gz','cddisk-processing.tar.gz','cddisk-rabbitmq.tar.gz','cddisk-registry.tar.gz','cddisk-searchapi.tar.gz','cddisk-ssoapi.tar.gz']);
        self.build_compose();
        self.build_configs();
        self.deploy();
        return self;

    def load_images(self, images: list = []):
        outputs=[];
        self.logger.info(f'Начинаю импорт дампа образов: {images}')
        for image in images:
            self.logger.debug(f'Открываю файл дампа: {self.INSTALL_DUMP_PATH}/{image}')
            if os.path.isfile(f'{self.INSTALL_DUMP_PATH}/{image}'):
                with open(f'{self.INSTALL_DUMP_PATH}/{image}', 'rb') as file:
                    print(f'\nЗагружаю dump образов:\n{sys.path[0]}/images/{image}\n');
                    self.logger.info(f'Загружаю dump образов: {self.INSTALL_DUMP_PATH}/{image}')
                    try:
                        outputs = outputs + self.dockercli.images.load(file);
                    except:
                        self.logger.error(f'Произошла ошибка при загрузке docker-образов из dump-файла: {image}')
                        return self.msgbox(f'Произошла ошибка при загрузке docker-образов из dump-файла {image}.');
            else:
                self.logger.error(f'Файл dump образов отсутствует: {self.INSTALL_DUMP_PATH}/{image}')

    def build_compose(self):
        self.logger.info(f'Открываю compose-файл template.yaml на запись')
        try:        
            with open(f'{self.INSTALL_NEW_PATH[-1]}/template.yaml', 'r') as file:
                compose_data = yaml.safe_load(file)
        except FileNotFoundError:
            self.msgbox(f'в каталоге {self.INSTALL_NEW_PATH[-1]} отсутствует файл template.yaml')
            return
        except PermissionError:
            self.msgbox(f'в каталоге {self.INSTALL_NEW_PATH[-1]} отсутствует доступ к файлу template.yaml')
            return            
        if 'cs-rabbitmq' in compose_data['services']:
            compose_data['services']['cs-rabbitmq']['image'] = f'{self.CS_RABBIT_IMAGE_NAME[-1]}:{self.CS_RABBIT_IMAGE_VERSION[-1]}'
        else:
            print(f"Сервис cs-rabbitmq не найден в template.yaml")
        if 'cs-postgres' in compose_data['services']:
            compose_data['services']['cs-postgres']['image'] = f'{self.CS_PSQL_IMAGE_NAME[-1]}:{self.CS_PSQL_IMAGE_VERSION[-1]}'
            compose_data['services']['cs-postgres']['environment']['r7_FORMS_CLIENT_ID'] = self.CS_FORMS_CLIENT_ID[-1]
            compose_data['services']['cs-postgres']['environment']['r7_FORMS_CLIENT_SECRET'] = self.CS_FORMS_CLIENT_SECRET[-1]
            compose_data['services']['cs-postgres']['environment']['r7_PAGES_CLIENT_ID'] = self.CS_PAGES_CLIENT_ID[-1]
            compose_data['services']['cs-postgres']['environment']['r7_PAGES_CLIENT_SECRET'] = self.CS_PAGES_CLIENT_SECRET[-1]
            compose_data['services']['cs-postgres']['environment']['r7_FORMS_URL'] = f'{self.CS_FRONTEND_SCHEME[-1]}://{self.CS_FRONTEND_PREFIX_FORMS[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}:{self.CS_FRONTEND_HTTPS_PORT[-1]}'
            compose_data['services']['cs-postgres']['environment']['r7_PAGES_URL'] = f'{self.CS_FRONTEND_SCHEME[-1]}://{self.CS_FRONTEND_PREFIX_PAGES[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}:{self.CS_FRONTEND_HTTPS_PORT[-1]}'
            compose_data['services']['cs-postgres']['environment']['r7_TEAM_CLIENT_ID'] = self.CS_TEAM_CLIENT_ID[-1]
            compose_data['services']['cs-postgres']['environment']['r7_TEAM_CLIENT_SECRET'] = self.CS_TEAM_CLIENT_SECRET[-1]
            compose_data['services']['cs-postgres']['environment']['r7_db_port'] = self.CS_PSQL_PORT[-1]
            compose_data['services']['cs-postgres']['volumes'].append({'type': 'bind', 'source': './10-update-database.sh', 'target': '/docker-entrypoint.d/10-update-database.sh'})
                # 'volumes':[
                #     {'type': 'bind', 'source': f'{self.CS_NODE_PSQL_STORAGE[-1]}', 'target': '/var/lib/postgresql/data/'}
        else:
            print(f"Сервис cs-postgres не найден в template.yaml")
        if 'cs-filestorage' in compose_data['services']:
            compose_data['services']['cs-filestorage']['image'] = f'{self.CS_FILESTORAGE_IMAGE_NAME[-1]}:{self.CS_FILESTORAGE_IMAGE_VERSION[-1]}'
        else:
            print(f"Сервис cs-filestorage не найден в template.yaml")
        if 'cs-searchapi' in compose_data['services']:
            compose_data['services']['cs-searchapi']['image'] = f'{self.CS_SEARCH_IMAGE_NAME[-1]}:{self.CS_SEARCH_IMAGE_VERSION[-1]}'
        else:
            print(f"Сервис cs-searchapi не найден в template.yaml")
        if 'cs-registry' in compose_data['services']:
            compose_data['services']['cs-registry']['image'] = f'{self.CS_REGISTRY_IMAGE_NAME[-1]}:{self.CS_REGISTRY_IMAGE_VERSION[-1]}'
        else:
            print(f"Сервис cs-registry не найден в template.yaml")
        if 'cs-processing' in compose_data['services']:
            compose_data['services']['cs-processing']['image'] = f'{self.CS_PROCESSING_IMAGE_NAME[-1]}:{self.CS_PROCESSING_IMAGE_VERSION[-1]}'
        else:
            print(f"Сервис cs-processing не найден в template.yaml")
        if 'cs-ssoapi' in compose_data['services']:
            compose_data['services']['cs-ssoapi']['image'] = f'{self.CS_SSO_IMAGE_NAME[-1]}:{self.CS_SSO_IMAGE_VERSION[-1]}'
        else:
            print(f"Сервис cs-ssoapi не найден в template.yaml")
        if 'cs-api' in compose_data['services']:
            compose_data['services']['cs-api']['image'] = f'{self.CS_API_IMAGE_NAME[-1]}:{self.CS_API_IMAGE_VERSION[-1]}'
            compose_data['services']['cs-api']['environment']['r7_ADMIN_DOMAIN'] = f'{self.CS_FRONTEND_PREFIX_ADMIN[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}'
            compose_data['services']['cs-api']['environment']['r7_FORMS_CLIENT_ID'] = self.CS_FORMS_CLIENT_ID[-1]
            compose_data['services']['cs-api']['environment']['r7_FORMS_CLIENT_SECRET'] = self.CS_FORMS_CLIENT_SECRET[-1]
            compose_data['services']['cs-api']['environment']['r7_PAGES_CLIENT_ID'] = self.CS_PAGES_CLIENT_ID[-1]
            compose_data['services']['cs-api']['environment']['r7_PAGES_CLIENT_SECRET'] = self.CS_PAGES_CLIENT_SECRET[-1]
            compose_data['services']['cs-api']['environment']['r7_FORMS_URL'] = f'{self.CS_FRONTEND_SCHEME[-1]}://{self.CS_FRONTEND_PREFIX_FORMS[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}:{self.CS_FRONTEND_HTTPS_PORT[-1]}'
            compose_data['services']['cs-api']['environment']['r7_PAGES_URL'] = f'{self.CS_FRONTEND_SCHEME[-1]}://{self.CS_FRONTEND_PREFIX_PAGES[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}:{self.CS_FRONTEND_HTTPS_PORT[-1]}'
            compose_data['services']['cs-api']['environment']['r7_PAGES_DOMAIN'] = f'{self.CS_FRONTEND_PREFIX_PAGES[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}'
            compose_data['services']['cs-api']['environment']['r7_FORMS_DOMAIN'] = f'{self.CS_FRONTEND_PREFIX_FORMS[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}'
            compose_data['services']['cs-api']['environment']['r7_SITE_DOMAIN'] = f'{self.CS_FRONTEND_DOMAIN[-1]}'
            compose_data['services']['cs-api']['environment']['r7_TEAM_CLIENT_ID'] = self.CS_TEAM_CLIENT_ID[-1]
            compose_data['services']['cs-api']['environment']['r7_TEAM_CLIENT_SECRET'] = self.CS_TEAM_CLIENT_SECRET[-1]
            compose_data['services']['cs-api']['environment']['r7_api_port'] = self.CS_API_PORT[-1]
            compose_data['services']['cs-api']['ports']=[{'mode': 'host', 'protocol': 'tcp', 'published': self.CS_API_PORT[-1],'target': '38033'}]
        else:
            print(f"Сервис cs-api не найден в template.yaml")
        if 'cs-draw' in compose_data['services']:
            compose_data['services']['cs-draw']['image'] = f'{self.CS_DRAW_IMAGE_NAME[-1]}:{self.CS_DRAW_IMAGE_VERSION[-1]}'
        else:
            print(f"Сервис cs-draw не найден в template.yaml")
        if 'cs-frontend' in compose_data['services']:
            compose_data['services']['cs-frontend']['image'] = f'{self.CS_FRONTEND_IMAGE_NAME[-1]}:{self.CS_FRONTEND_IMAGE_VERSION[-1]}'
            compose_data['services']['cs-frontend']['environment']['r7_FORMS_URL'] = f'{self.CS_FRONTEND_SCHEME[-1]}://{self.CS_FRONTEND_PREFIX_FORMS[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}:{self.CS_FRONTEND_HTTPS_PORT[-1]}'
            compose_data['services']['cs-frontend']['environment']['r7_PAGES_URL'] = f'{self.CS_FRONTEND_SCHEME[-1]}://{self.CS_FRONTEND_PREFIX_PAGES[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}:{self.CS_FRONTEND_HTTPS_PORT[-1]}'
            compose_data['services']['cs-frontend']['environment']['r7_PAGES_DOMAIN'] = f'{self.CS_FRONTEND_PREFIX_PAGES[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}'
            compose_data['services']['cs-frontend']['environment']['r7_FORMS_DOMAIN'] = f'{self.CS_FRONTEND_PREFIX_FORMS[-1]}.{self.CS_FRONTEND_DOMAIN[-1]}'
        else:
            print(f"Сервис cs-frontend не найден в template.yaml")

        # Сохраняем изменения обратно в файл

        with open(f'{self.INSTALL_NEW_PATH[-1]}/template.yaml', 'w') as file:
            yaml.dump(compose_data, file, default_flow_style=False)

        print(f"Переменная окружения обновлена ")
        self.logger.info(f'Выгружаю compose-файл template.yaml')

    def build_configs(self):
        self.logger.info(f'Произвожу поиск файлов-шаблонов конфигураций')
        for root, dirs, files in os.walk(f'{self.INSTALL_CONF_PATH}/frontend'):
            for file in files:
                if file.endswith('.j2'):
                    self.logger.info(f'Вызываю шаблонизатор Jinja2 на файл {root}/{file}')
                    env = jinja.Environment(loader=jinja.FileSystemLoader([root]))
                    template = env.get_template(file);
                    self.logger.info(f'Открываю файл {root}/{file.replace(".j2", "")} на запись.')
                    with open(f'{root}/{file.replace(".j2", "")}', 'w') as f:
                        self.logger.info(f'Произвожу рендеринг шаблона и экспорт в файл')
                        f.write(template.render(self.__dict__));
                        self.logger.info(f'Файл {root}/{file.replace(".j2", "")} создан.')
        for root, dirs, files in os.walk(f'{self.INSTALL_CONF_PATH}'):
            for file in files:
                if file.endswith('.j3'):
                    self.logger.info(f'Вызываю шаблонизатор Jinja2 на файл {root}/{file}')
                    env = jinja.Environment(loader=jinja.FileSystemLoader([root]))
                    template = env.get_template(file);
                    self.logger.info(f'Открываю файл {root}/{file.replace(".j3", "")} на запись.')
                    with open(f'{root}/{file.replace(".j3", "")}', 'w') as f:
                        self.logger.info(f'Произвожу рендеринг шаблона и экспорт в файл')
                        f.write(template.render(self.__dict__));
                        self.logger.info(f'Файл {root}/{file.replace(".j3", "")} создан.')

    def deploy(self):
        print (f'\n\nКопирую файлы.\n\n############\n#### ВНИМАНИЕ: НЕ ОСТАНАВЛИВАЙТЕ ПРОЦЕСС\n############\n\n');
        print (f'\n\nКопирую /py_module\n\n');
        shutil.copytree('./py_module',f'{self.INSTALL_NEW_PATH[-1]}/py_module', dirs_exist_ok=True)
        print (f'\n\nКопирую /config-examples\n\n');
        shutil.copytree('./config-examples',f'{self.INSTALL_NEW_PATH[-1]}/config-examples', dirs_exist_ok=True)
        print (f'\n\nКопирую /grafana_data\n\n');
        shutil.copytree('./grafana_data',f'{self.INSTALL_NEW_PATH[-1]}/grafana_data', dirs_exist_ok=True)
        print (f'\n\nКопирую /images\n\n');
        shutil.copytree('./images',f'{self.INSTALL_NEW_PATH[-1]}/images', dirs_exist_ok=True)
        #shutil.copy2('./clear-data.sh',f'{self.INSTALL_NEW_PATH[-1]}')
        shutil.copy2('./configs/tokens',f'{self.INSTALL_NEW_PATH[-1]}/configs/tokens')
        shutil.copy2('./configs/tokens.j2',f'{self.INSTALL_NEW_PATH[-1]}/configs/tokens.j3')
        shutil.copy2('./configs/frontend/nginx/pages.conf.j2',f'{self.INSTALL_NEW_PATH[-1]}/configs/frontend/nginx/pages.conf.j2')
        shutil.copy2('./configs/frontend/nginx/forms.conf.j2',f'{self.INSTALL_NEW_PATH[-1]}/configs/frontend/nginx/forms.conf.j2')
        shutil.copy2('./configs/frontend/nginx/pages.conf',f'{self.INSTALL_NEW_PATH[-1]}/configs/frontend/nginx/pages.conf')
        shutil.copy2('./configs/frontend/nginx/forms.conf',f'{self.INSTALL_NEW_PATH[-1]}/configs/frontend/nginx/forms.conf')
        shutil.copy2('./10-update-database.sh',f'{self.INSTALL_NEW_PATH[-1]}/10-update-database.sh')

        command = [f'{self.INSTALL_NEW_PATH[-1]}/runtime/docker-plugins/docker-compose', '-f', f'{self.INSTALL_NEW_PATH[-1]}/template.yaml', 'up', '--force-recreate', '-d', '-V']
        return_code, stdout, stderr = self.subprocess(command, fd_stderr=sys.stdout)
        if return_code != 0:
            self.logger.error(f'При попытке запуска команды ({command}) произошли ошибки')
            for err in stderr: self.logger.error(err) if 'error' in err.lower() else self.logger.info(err)
            self.msgbox(f'При запуске сервисов произошли ошибки. Обратитесь в службу технической поддержки Р7-офис.')
            return
        else:
            for err in stderr: self.logger.debug(err)
            self.logger.info('Docker Compose Plugin завершился без ошибок.')

        time.sleep(5)
        command = [f'{self.INSTALL_NEW_PATH[-1]}/runtime/docker/docker', 'exec', '-i', 'cs-psql', '/docker-entrypoint.d/10-update-database.sh']
        return_code, stdout, stderr = self.subprocess(command, fd_stderr=sys.stdout)
        if return_code != 0:
            self.logger.error(f'При попытке запуска команды ({command}) произошли ошибки')
            for err in stderr: self.logger.error(err) if 'error' in err.lower() else self.logger.info(err)
            self.msgbox(f'При запуске сервисов произошли ошибки. Обратитесь в службу технической поддержки Р7-офис.')
        else:
            for err in stderr: self.logger.debug(err)
            self.logger.info('Docker Compose Plugin завершился без ошибок.')
            self.msgbox(f'Сервисы продуктов Р7-офис обновлены.');

    def get_requests(self, prefix_env: str = "CS", dialog: list = None, external:bool = False, **kwarg):
        dialogs = dialog if isinstance(dialog, list) else [
            {
                "env": f'INSTALL_NEW_PATH',
                "enable": None,
                'msg': (
                    f'Р7-Корпоративный сервер:\n\nУкажите путь, где установлена версия 14752',
                    f'Путь до директории обязателен к заполнению',
                    f'Указанный путь не найден'
                ),
                "func_parse": self.parse_path_dir(),
                "func_check": self.check_extended_dir(),
                "func_visibility": self.visibility_detalization(),
                "detalization": 1
            },
            {
                "env": f'CS_FRONTEND_DOMAIN',
                "enable": True,
                "msg": (
                    f'Введите имя домена',
                    f'Имя домена обязательно к заполнению.',
                    None
                ),
                "func_check": self.check_domain(),
                "func_parse": self.parse_default()
            },            
            {
                "env": f'CS_FRONTEND_PREFIX_CDDISK',
                "enable": None,
                "msg": (
                    f'Р7-Корпоративный сервер:\n\nВведите префикс для FQDN-имени модуля "Р7-Диск", который сейчас используется',
                    f'Префикс имени сайта обязателен к заполнению.',
                    f'Префикс не может содержать спецсимволы, кроме "-"'
                ),
                "func_check": self.check_hostname(),
                "func_visibility": [self.visibility_detalization()],
                "detalization": 1
            },
            {
                "env": f'CS_FRONTEND_PREFIX_ADMIN',
                "enable": None,
                "msg": (
                    f'Р7-Корпоративный сервер:\n\nВведите префикс для FQDN-имени модуля "Р7-Панель управления", который сейчас используется',
                    f'Префикс имени сайта обязателен к заполнению.',
                    f'Префикс не может содержать спецсимволы, кроме "-"'
                ),
                "func_check": self.check_hostname(),
                "func_visibility": [self.visibility_detalization()],
                "detalization": 1
            },
            {
                "env": f'CS_FRONTEND_PREFIX_PAGES',
                "enable": None,
                "msg": (
                    f'Р7-Корпоративный сервер:\n\nВведите префикс для FQDN-имени сайта "Р7-Страницы".\nТекущее назначенное имя: {self.CS_FRONTEND_PREFIX_PAGES[0]}.{self.CS_FRONTEND_DOMAIN[-1]}',
                    f'Префикс имени сайта обязателен к заполнению.',
                    f'Префикс не может содержать спецсимволы, кроме "-"'
                ),
                "func_check": self.check_hostname(),
                "func_visibility": [self.visibility_detalization()],
                "detalization": 1
            },
            {
                "env": f'CS_FRONTEND_PREFIX_FORMS',
                "enable": None,
                "msg": (
                    f'Р7-Корпоративный сервер:\n\nВведите префикс для FQDN-имени сайта "Р7-Формы".\nТекущее назначенное имя: {self.CS_FRONTEND_PREFIX_FORMS[0]}.{self.CS_FRONTEND_DOMAIN[-1]}',
                    f'Префикс имени сайта обязателен к заполнению.',
                    f'Префикс не может содержать спецсимволы, кроме "-"'
                ),
                "func_check": self.check_hostname(),
                "func_visibility": [self.visibility_detalization()],
                "detalization": 1
            },
            {
                "env": f'CS_PAGES_CLIENT_ID',
                "enable": None,
                'msg': (
                    f'Р7-Корпоративный сервер:\n\n{"Сгенерируйте PAGES_CLIENT_ID для модуля Страницы, либо используйте предложенный (сохранится в файле ./configs/tokens)"}',
                    f'Указание ID обязательно для работы модуля',
                    None
                ),
                "func_check": self.check_uid(),
                "func_visibility": self.visibility_detalization(),
                "detalization": 1
            },
            {
                "env": f'CS_PAGES_CLIENT_SECRET',
                "enable": None,
                'msg': (
                    f'Р7-Корпоративный сервер:\n\n{"Сгенерируйте PAGES_CLIENT_SECRET для модуля Страницы, либо используйте предложенный (сохранится в файле ./configs/tokens)"}',
                    f'Указание ID обязательно для работы модуля',
                    None
                ),
                "func_check": self.check_uid(),
                "func_visibility": self.visibility_detalization(),
                "detalization": 1
            },
            {
                "env": f'CS_FORMS_CLIENT_ID',
                "enable": None,
                'msg': (
                    f'Р7-Корпоративный сервер:\n\n{"Cгенерируйте FORMS_CLIENT_ID для модуля Формы, либо используйте предложенный (сохранится в файле ./configs/tokens)"}',
                    f'Указание ID обязательно для работы модуля',
                    None
                ),
                "func_check": self.check_uid(),
                "func_visibility": self.visibility_detalization(),
                "detalization": 1
            },
            {
                "env": f'CS_FORMS_CLIENT_SECRET',
                "enable": None,
                'msg': (
                    f'Р7-Корпоративный сервер:\n\n{"Сгенерируйте FORMS_CLIENT_SECRET для модуля Формы, либо используйте предложенный (сохранится в файле ./configs/tokens)"}',
                    f'Указание ID обязательно для работы модуля',
                    None
                ),
                "func_check": self.check_uid(),
                "func_visibility": self.visibility_detalization(),
                "detalization": 1
            },
            {
                "env": f'CS_TEAM_CLIENT_ID',
                "enable": None,
                'msg': (
                    f'Р7-Корпоративный сервер:\n\nВведите сгенерированный ранее TEAM_CLIENT_ID для интеграции с Р7-Команда (указан в веб-форме и сохранится в файле ./configs/tokens)',
                    f'Указание ID обязательно для работы модуля',
                    None
                ),
                "func_check": self.check_uid(),
                "func_visibility": self.visibility_detalization(),
                "detalization": 1
            },
            {
                "env": f'CS_TEAM_CLIENT_SECRET',
                "enable": None,
                'msg': (
                    f'Р7-Корпоративный сервер:\n\nВведите сгенерированный ранее TEAM_CLIENT_SECRET для интеграции с Р7-Команда (указан в веб-форме и сохранится в файле./configs/tokens)',
                    f'Указание ID обязательно для работы модуля',
                    None
                ),
                "func_check": self.check_uid(),
                "func_visibility": self.visibility_detalization(),
                "detalization": 1
            },
        ];
        self.get_dialogs(dialogs)
    
