From 41ed01d0a99682c1e2336dbd7eb5979291824691 Mon Sep 17 00:00:00 2001 From: heedaeshin Date: Thu, 31 Oct 2024 17:31:20 +0900 Subject: [PATCH 1/2] Add : Operate Data Service --- .gitignore | 36 +++- Dockerfile | 10 +- .../template/example/AWS/BUILDER/main.tf | 70 ++++++++ .../AWS/BUILDER/modules/dynamodb/main.tf | 12 ++ .../AWS/BUILDER/modules/dynamodb/variables.tf | 60 +++++++ .../example/AWS/BUILDER/modules/mysql/main.tf | 15 ++ .../AWS/BUILDER/modules/mysql/variables.tf | 60 +++++++ .../AWS/BUILDER/modules/storage/main.tf | 6 + .../AWS/BUILDER/modules/storage/variables.tf | 60 +++++++ .../template/example/AWS/BUILDER/variables.tf | 165 ++++++++++++++++++ .../template/example/GCP/BUILDER/main.tf | 35 ++++ .../GCP/BUILDER/modules/firestore/main.tf | 14 ++ .../BUILDER/modules/firestore/variables.tf | 19 ++ .../example/GCP/BUILDER/modules/mysql/main.tf | 27 +++ .../GCP/BUILDER/modules/mysql/variables.tf | 34 ++++ .../GCP/BUILDER/modules/storage/main.tf | 11 ++ .../GCP/BUILDER/modules/storage/variables.tf | 20 +++ .../template/example/GCP/BUILDER/variables.tf | 13 ++ .../template/example/NCP/BUILDER/main.tf | 106 +++++++++++ .../NCP/BUILDER/modules/mongodb/main.tf | 20 +++ .../NCP/BUILDER/modules/mongodb/variavles.tf | 62 +++++++ .../example/NCP/BUILDER/modules/rdb/main.tf | 19 ++ .../NCP/BUILDER/modules/rdb/variables.tf | 34 ++++ .../NCP/BUILDER/modules/storage/main.tf | 15 ++ .../NCP/BUILDER/modules/storage/variables.tf | 25 +++ .../template/example/NCP/BUILDER/variables.tf | 69 ++++++++ docker-compose.yaml | 1 + docs/Datamanager-Demo-Guide.md | 41 +++-- docs/Datamanager-Docker-Guide.md | 7 +- .../pre-check/gcp_cloud_sql_admin_api.png | Bin 0 -> 19628 bytes docs/image/web/DelService.png | Bin 0 -> 71182 bytes docs/image/web/GenService.png | Bin 0 -> 40880 bytes scripts/apply.sh | 4 + scripts/destroy.sh | 4 + scripts/exec_terraform.sh | 76 ++++++++ scripts/init-settings.sh | 9 + scripts/set_credentials.sh | 86 +++++++++ web/js/scripts.js | 78 +++++++++ web/templates/header.html | 7 +- websrc/controllers/serivceHandlers.go | 164 ++++++++++++++++- websrc/docs/docs.go | 54 ++++++ websrc/docs/swagger.json | 54 ++++++ websrc/docs/swagger.yaml | 36 ++++ websrc/routes/serviceRoute.go | 7 + 44 files changed, 1627 insertions(+), 18 deletions(-) create mode 100644 data/var/run/data-manager/template/example/AWS/BUILDER/main.tf create mode 100644 data/var/run/data-manager/template/example/AWS/BUILDER/modules/dynamodb/main.tf create mode 100644 data/var/run/data-manager/template/example/AWS/BUILDER/modules/dynamodb/variables.tf create mode 100644 data/var/run/data-manager/template/example/AWS/BUILDER/modules/mysql/main.tf create mode 100644 data/var/run/data-manager/template/example/AWS/BUILDER/modules/mysql/variables.tf create mode 100644 data/var/run/data-manager/template/example/AWS/BUILDER/modules/storage/main.tf create mode 100644 data/var/run/data-manager/template/example/AWS/BUILDER/modules/storage/variables.tf create mode 100644 data/var/run/data-manager/template/example/AWS/BUILDER/variables.tf create mode 100644 data/var/run/data-manager/template/example/GCP/BUILDER/main.tf create mode 100644 data/var/run/data-manager/template/example/GCP/BUILDER/modules/firestore/main.tf create mode 100644 data/var/run/data-manager/template/example/GCP/BUILDER/modules/firestore/variables.tf create mode 100644 data/var/run/data-manager/template/example/GCP/BUILDER/modules/mysql/main.tf create mode 100644 data/var/run/data-manager/template/example/GCP/BUILDER/modules/mysql/variables.tf create mode 100644 data/var/run/data-manager/template/example/GCP/BUILDER/modules/storage/main.tf create mode 100644 data/var/run/data-manager/template/example/GCP/BUILDER/modules/storage/variables.tf create mode 100644 data/var/run/data-manager/template/example/GCP/BUILDER/variables.tf create mode 100644 data/var/run/data-manager/template/example/NCP/BUILDER/main.tf create mode 100644 data/var/run/data-manager/template/example/NCP/BUILDER/modules/mongodb/main.tf create mode 100644 data/var/run/data-manager/template/example/NCP/BUILDER/modules/mongodb/variavles.tf create mode 100644 data/var/run/data-manager/template/example/NCP/BUILDER/modules/rdb/main.tf create mode 100644 data/var/run/data-manager/template/example/NCP/BUILDER/modules/rdb/variables.tf create mode 100644 data/var/run/data-manager/template/example/NCP/BUILDER/modules/storage/main.tf create mode 100644 data/var/run/data-manager/template/example/NCP/BUILDER/modules/storage/variables.tf create mode 100644 data/var/run/data-manager/template/example/NCP/BUILDER/variables.tf create mode 100644 docs/image/pre-check/gcp_cloud_sql_admin_api.png create mode 100644 docs/image/web/DelService.png create mode 100644 docs/image/web/GenService.png create mode 100644 scripts/apply.sh create mode 100644 scripts/destroy.sh create mode 100644 scripts/exec_terraform.sh create mode 100644 scripts/init-settings.sh create mode 100644 scripts/set_credentials.sh diff --git a/.gitignore b/.gitignore index 7363eb0..edfe0a3 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,38 @@ go.work mc-data-manager # Credential -profile.json \ No newline at end of file +profile.json +secrets.json +gcp.json +*.tfvars + + + +# Local .terraform directories +.terraform/ +.terraform* +terraform.tfstate +terraform.tfstate.* +crash.log +crash.* +*.tfvars +*.tfstate +*.tfstate.* + +# Sensitive variable definition files +secrets.tfvars +terraform.tfvars +*.auto.tfvars + +# Ignore override files as they are usually machine-specific +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +# Ignore plan output files +*.tfplan \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index bb53d33..44aa50b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,15 @@ ARG GID=0 ARG USER=root ARG GROUP=root #------------------------------------------------------------- -RUN apt-get update && apt-get install -y ca-certificates curl && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get upgrade +RUN apt-get install -y ca-certificates curl jq gnupg software-properties-common wget lsb-release && rm -rf /var/lib/apt/lists/* + +#------------------------------------------------------------- +# Add the HashiCorp GPG key and official repository for Terraform +RUN wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | tee /usr/share/keyrings/hashicorp-archive-keyring.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/hashicorp.list && \ + apt update && apt install -y terraform && \ + rm -rf /var/lib/apt/lists/* #------------------------------------------------------------- # User Set RUN if [ "${USER}" != "root" ]; then \ diff --git a/data/var/run/data-manager/template/example/AWS/BUILDER/main.tf b/data/var/run/data-manager/template/example/AWS/BUILDER/main.tf new file mode 100644 index 0000000..b29f5f7 --- /dev/null +++ b/data/var/run/data-manager/template/example/AWS/BUILDER/main.tf @@ -0,0 +1,70 @@ +# main.tf +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.73.0" + } + } +} + +# AWS Provider set +provider "aws" { + region = var.region + access_key = var.access_key + secret_key = var.secret_key + +} + +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_subnet" "main" { + vpc_id = aws_vpc.main.id + cidr_block = "10.0.1.0/24" + availability_zone = var.zone +} + + +resource "aws_security_group" "allow_all" { + name = "allow_all_traffic" + description = "Allow all inbound and outbound traffic" + vpc_id = aws_vpc.main.id + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + + + +# S3 module call +module "s3" { + source = "./modules/storage" + bucket_name = var.bucket_name +} + +# mysql module call +module "mysql" { + source = "./modules/mysql" + db_name = var.db_name + db_user = var.db_user + db_pswd = var.db_pswd +} + +# DynamoDB module call +module "dynamodb" { + source = "./modules/dynamodb" + table_name = var.table_name +} diff --git a/data/var/run/data-manager/template/example/AWS/BUILDER/modules/dynamodb/main.tf b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/dynamodb/main.tf new file mode 100644 index 0000000..f74440e --- /dev/null +++ b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/dynamodb/main.tf @@ -0,0 +1,12 @@ +resource "aws_dynamodb_table" "dynamodb_table" { + name = var.table_name + read_capacity = 1 + write_capacity = 1 + hash_key = "UserId" + + attribute { + name = "UserId" + type = "S" + } + deletion_protection_enabled = false +} diff --git a/data/var/run/data-manager/template/example/AWS/BUILDER/modules/dynamodb/variables.tf b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/dynamodb/variables.tf new file mode 100644 index 0000000..38d6e6c --- /dev/null +++ b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/dynamodb/variables.tf @@ -0,0 +1,60 @@ +# variables.tf + +# variable "access_key" { +# description = "AWS Access Key" +# type = string +# } + +# variable "secret_key" { +# description = "AWS Secret Key" +# type = string +# } + +# variable "region" { +# description = "AWS Region" +# type = string +# default = "KR" +# } + +# variable "vpc_name" { +# description = "vpc_name" +# type = string +# default = "mcmp-vpc" + +# } + +# variable "private_subnet_name" { +# description = "private_subnet_name" +# type = string + +# } +# variable "public_subnet_name" { +# description = "public_subnet_name" +# type = string + +# } + +variable "table_name" { + description = "table_name" + type = string +} + +# variable "db_name" { +# description = "DB name" +# type = string +# } + + +# variable "db_user" { +# description = "DB user" +# type = string +# } + +# variable "db_pswd" { +# description = "DB PW" +# type = string +# } + + + + diff --git a/data/var/run/data-manager/template/example/AWS/BUILDER/modules/mysql/main.tf b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/mysql/main.tf new file mode 100644 index 0000000..a72b991 --- /dev/null +++ b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/mysql/main.tf @@ -0,0 +1,15 @@ + + + +resource "aws_db_instance" "default" { + allocated_storage = 10 + db_name = var.db_name + engine = "mysql" + engine_version = "8.0" + instance_class = "db.t3.micro" + username = var.db_user + password = var.db_pswd + parameter_group_name = "default.mysql8.0" + skip_final_snapshot = true + deletion_protection = false +} \ No newline at end of file diff --git a/data/var/run/data-manager/template/example/AWS/BUILDER/modules/mysql/variables.tf b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/mysql/variables.tf new file mode 100644 index 0000000..5ad12a6 --- /dev/null +++ b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/mysql/variables.tf @@ -0,0 +1,60 @@ +# variables.tf + +# variable "access_key" { +# description = "AWS Access Key" +# type = string +# } + +# variable "secret_key" { +# description = "AWS Secret Key" +# type = string +# } + +# variable "region" { +# description = "AWS Region" +# type = string +# default = "KR" +# } + +# variable "vpc_name" { +# description = "vpc_name" +# type = string +# default = "mcmp-vpc" + +# } + +# variable "private_subnet_name" { +# description = "private_subnet_name" +# type = string + +# } +# variable "public_subnet_name" { +# description = "public_subnet_name" +# type = string + +# } + +# variable "bucket_name" { +# description = "bucket_name" +# type = string +# } + +variable "db_name" { + description = "DB name" + type = string +} + + +variable "db_user" { + description = "DB user" + type = string +} + +variable "db_pswd" { + description = "DB PW" + type = string +} + + + + diff --git a/data/var/run/data-manager/template/example/AWS/BUILDER/modules/storage/main.tf b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/storage/main.tf new file mode 100644 index 0000000..64bbbdd --- /dev/null +++ b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/storage/main.tf @@ -0,0 +1,6 @@ + + +resource "aws_s3_bucket" "bucket" { + bucket = var.bucket_name + +} \ No newline at end of file diff --git a/data/var/run/data-manager/template/example/AWS/BUILDER/modules/storage/variables.tf b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/storage/variables.tf new file mode 100644 index 0000000..413c10a --- /dev/null +++ b/data/var/run/data-manager/template/example/AWS/BUILDER/modules/storage/variables.tf @@ -0,0 +1,60 @@ +# variables.tf + +# variable "access_key" { +# description = "AWS Access Key" +# type = string +# } + +# variable "secret_key" { +# description = "AWS Secret Key" +# type = string +# } + +# variable "region" { +# description = "AWS Region" +# type = string +# default = "KR" +# } + +# variable "vpc_name" { +# description = "vpc_name" +# type = string +# default = "mcmp-vpc" + +# } + +# variable "private_subnet_name" { +# description = "private_subnet_name" +# type = string + +# } +# variable "public_subnet_name" { +# description = "public_subnet_name" +# type = string + +# } + +variable "bucket_name" { + description = "bucket_name" + type = string +} + +# variable "db_name" { +# description = "DB name" +# type = string +# } + + +# variable "db_user" { +# description = "DB user" +# type = string +# } + +# variable "db_pswd" { +# description = "DB PW" +# type = string +# } + + + + diff --git a/data/var/run/data-manager/template/example/AWS/BUILDER/variables.tf b/data/var/run/data-manager/template/example/AWS/BUILDER/variables.tf new file mode 100644 index 0000000..342fe00 --- /dev/null +++ b/data/var/run/data-manager/template/example/AWS/BUILDER/variables.tf @@ -0,0 +1,165 @@ +# variables.tf + +variable "access_key" { + description = "AWS Access Key" + type = string + sensitive = true +} + +variable "secret_key" { + description = "AWS Secret Key" + type = string + sensitive = true +} + +variable "region" { + description = "AWS Region" + type = string + default = "ap-northeast-2" +} + +variable "zone" { + description = "AWS zone" + type = string + default = "ap-northeast-2d" +} + +variable "vpc_name" { + description = "vpc_name" + type = string + default = "mcmp-vpc" + +} + +variable "private_subnet_name" { + description = "private_subnet_name" + type = string + default = "mcmp-pi-subnet" + +} +variable "public_subnet_name" { + description = "public_subnet_name" + type = string + default = "mcmp-pu-subnet" + +} + +variable "bucket_name" { + description = "bucket_name" + type = string + default = "mc-data-manager" +} + +variable "table_name" { + description = "table_name" + type = string + default = "mc-data-manager" +} + + +variable "db_name" { + description = "DB name" + type = string + default = "MCDataManager" +} + + +variable "db_user" { + description = "DB user" + type = string + default = "datamanager" +} + +variable "db_pswd" { + description = "DB PW" + type = string + default = "NAmutech7^^7" +} + + +# variable "aws_region" { +# description = "AWS 리전" +# type = string +# default = "us-east-1" +# } + +# variable "aws_access_key" { +# description = "AWS 액세스 키" +# type = string +# } + +# variable "aws_secret_key" { +# description = "AWS 시크릿 키" +# type = string +# } + +# # S3 변수 +# variable "s3_bucket_name" { +# description = "S3 버킷 이름" +# type = string +# } + +# # RDS 변수 +# variable "db_instance_identifier" { +# description = "RDS 인스턴스 식별자" +# type = string +# } + +# variable "db_name" { +# description = "데이터베이스 이름" +# type = string +# } + +# variable "db_username" { +# description = "데이터베이스 마스터 사용자 이름" +# type = string +# } + +# variable "db_password" { +# description = "데이터베이스 마스터 비밀번호" +# type = string +# sensitive = true +# } + +# variable "db_allocated_storage" { +# description = "할당된 스토리지 (GB)" +# type = number +# default = 20 +# } + +# variable "db_instance_class" { +# description = "RDS 인스턴스 클래스" +# type = string +# default = "db.t3.micro" +# } + +# variable "subnet_ids" { +# description = "서브넷 IDs (RDS 배포용)" +# type = list(string) +# } + +# # DynamoDB 변수 +# variable "dynamodb_table_name" { +# description = "DynamoDB 테이블 이름" +# type = string +# } + +# variable "dynamodb_read_capacity" { +# description = "DynamoDB 읽기 용량 단위" +# type = number +# default = 5 +# } + +# variable "dynamodb_write_capacity" { +# description = "DynamoDB 쓰기 용량 단위" +# type = number +# default = 5 +# } + +# variable "dynamodb_hash_key" { +# description = "DynamoDB 해시 키 속성 이름" +# type = string +# } + + + diff --git a/data/var/run/data-manager/template/example/GCP/BUILDER/main.tf b/data/var/run/data-manager/template/example/GCP/BUILDER/main.tf new file mode 100644 index 0000000..f41d159 --- /dev/null +++ b/data/var/run/data-manager/template/example/GCP/BUILDER/main.tf @@ -0,0 +1,35 @@ +terraform { + required_providers { + google = { + source = "hashicorp/google" + version = "~> 6.9.0" + } + } +} + +provider "google" { + credentials = file("secrets.json") # secrete.json path + project = var.project_id + region = var.region +} + +# Firestore Gen +module "firestore_database" { + source = "./modules/firestore" + project_id = var.project_id + region = var.region +} + +# MySQL RDB Gen +module "mysql" { + source = "./modules/mysql" + project_id = var.project_id + region = var.region +} + +# Google Cloud Storage Gen +module "storage" { + source = "./modules/storage" + project_id = var.project_id + region = var.region +} diff --git a/data/var/run/data-manager/template/example/GCP/BUILDER/modules/firestore/main.tf b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/firestore/main.tf new file mode 100644 index 0000000..5457063 --- /dev/null +++ b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/firestore/main.tf @@ -0,0 +1,14 @@ + + +resource "google_firestore_database" "datastore_mode_database" { + project = var.project_id + location_id = var.region # Firestore region + name = var.dbName # Firestore DB name + type = "FIRESTORE_NATIVE" # Firestore type + + # DELETE Policty and State + deletion_policy = "DELETE" + delete_protection_state = "DELETE_PROTECTION_DISABLED" # Firestore state + +} + diff --git a/data/var/run/data-manager/template/example/GCP/BUILDER/modules/firestore/variables.tf b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/firestore/variables.tf new file mode 100644 index 0000000..11a6b04 --- /dev/null +++ b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/firestore/variables.tf @@ -0,0 +1,19 @@ +# 공통 변수 설정 +variable "project_id" { + description = "GCP 프로젝트 ID" + type = string + default = "spatial-conduit-399006" +} + +variable "region" { + description = "GCP 리전" + type = string + default = "asia-east1" +} + +# 로컬 변수 설정 +variable "dbName" { + description = "DB 이름" + type = string + default = "mc-data-manager" +} diff --git a/data/var/run/data-manager/template/example/GCP/BUILDER/modules/mysql/main.tf b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/mysql/main.tf new file mode 100644 index 0000000..8503caa --- /dev/null +++ b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/mysql/main.tf @@ -0,0 +1,27 @@ +# MySQL Instance 리소스 구성 + +resource "google_sql_database_instance" "mysql_instance" { + name = var.dbName # instance name + project = var.project_id + region = var.region + database_version = "MYSQL_8_0" + + settings { + tier = "db-f1-micro" # instance reesource flavor + } + deletion_protection = false # Delete protection + +} + +resource "google_sql_database" "mysql_database" { + name = var.dbName # MySQL DBname + instance = google_sql_database_instance.mysql_instance.name + project = var.project_id +} + +resource "google_sql_user" "mysql_user" { + name = var.userName # DBuser + password = var.password # DBpw + instance = google_sql_database_instance.mysql_instance.name + project = var.project_id +} diff --git a/data/var/run/data-manager/template/example/GCP/BUILDER/modules/mysql/variables.tf b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/mysql/variables.tf new file mode 100644 index 0000000..cf88182 --- /dev/null +++ b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/mysql/variables.tf @@ -0,0 +1,34 @@ +# 공통 변수 설정 + +variable "project_id" { + description = "GCP 프로젝트 ID" + type = string + default = "spatial-conduit-399006" +} + +variable "region" { + description = "GCP 리전" + type = string + default = "asia-east1" +} + + +# 로컬 변수 설정 +variable "dbName" { + description = "DB 이름" + type = string + default = "mc-data-manager" +} + + +variable "userName" { + description = "DB 유저" + type = string + default = "mc-data-manager" +} + +variable "password" { + description = "DB PW" + type = string + default = "mcdatamanager" +} diff --git a/data/var/run/data-manager/template/example/GCP/BUILDER/modules/storage/main.tf b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/storage/main.tf new file mode 100644 index 0000000..c9b0727 --- /dev/null +++ b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/storage/main.tf @@ -0,0 +1,11 @@ +# GCS Bucket 리소스 구성 + +resource "google_storage_bucket" "data_storage" { + name = var.bucketName # BuecketName + location = var.region + storage_class = "STANDARD" + + versioning { + enabled = true + } +} diff --git a/data/var/run/data-manager/template/example/GCP/BUILDER/modules/storage/variables.tf b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/storage/variables.tf new file mode 100644 index 0000000..0dc4727 --- /dev/null +++ b/data/var/run/data-manager/template/example/GCP/BUILDER/modules/storage/variables.tf @@ -0,0 +1,20 @@ +# 공통 변수 설정 +variable "project_id" { + description = "GCP 프로젝트 ID" + type = string + default = "spatial-conduit-399006" +} + +variable "region" { + description = "GCP 리전" + type = string + default = "asia-east1" +} + +# 로컬 변수 설정 + +variable "bucketName" { + description = "버킷 명" + type = string + default = "mc-data-manager" +} \ No newline at end of file diff --git a/data/var/run/data-manager/template/example/GCP/BUILDER/variables.tf b/data/var/run/data-manager/template/example/GCP/BUILDER/variables.tf new file mode 100644 index 0000000..6106f81 --- /dev/null +++ b/data/var/run/data-manager/template/example/GCP/BUILDER/variables.tf @@ -0,0 +1,13 @@ +# 공통 변수 설정 + +variable "project_id" { + description = "GCP 프로젝트 ID" + type = string + default = "spatial-conduit-399006" +} + +variable "region" { + description = "GCP 리전" + type = string + default = "asia-east1" +} diff --git a/data/var/run/data-manager/template/example/NCP/BUILDER/main.tf b/data/var/run/data-manager/template/example/NCP/BUILDER/main.tf new file mode 100644 index 0000000..98742c9 --- /dev/null +++ b/data/var/run/data-manager/template/example/NCP/BUILDER/main.tf @@ -0,0 +1,106 @@ +terraform { + required_providers { + ncloud = { + source = "NaverCloudPlatform/ncloud" + version = "~>3.2.1" # ncloud SDK + } + } +} + +provider "ncloud" { + support_vpc = true + access_key = var.access_key # NCP Access Key + secret_key = var.secret_key # NCP Secret Key + region = var.region # NCP Region +} + +resource "ncloud_vpc" "vpc" { + name = var.vpc_name + ipv4_cidr_block = "10.0.0.0/16" +} + +resource "ncloud_network_acl" "acl" { + vpc_no = ncloud_vpc.vpc.id + name = var.acl_name + description = "M-CMP" +} + +resource "ncloud_network_acl_rule" "acl_rule" { + network_acl_no = ncloud_network_acl.acl.id + + inbound { + priority = 100 + protocol = "TCP" + rule_action = "ALLOW" + ip_block = "0.0.0.0/0" + port_range = "1-65535" + } + + outbound { + priority = 110 + protocol = "TCP" + rule_action = "ALLOW" + ip_block = "0.0.0.0/0" + port_range = "1-65535" + } +} + +resource "ncloud_subnet" "subnet" { + depends_on = [ncloud_vpc.vpc, ncloud_network_acl.acl] + vpc_no = ncloud_vpc.vpc.id + subnet = "10.0.1.0/24" + zone = "KR-1" + network_acl_no = ncloud_network_acl.acl.id + subnet_type = "PRIVATE" + name = var.private_subnet_name + usage_type = "GEN" +} + +resource "ncloud_subnet" "public_subnet" { + depends_on = [ncloud_vpc.vpc, ncloud_network_acl.acl] + vpc_no = ncloud_vpc.vpc.id + subnet = "10.0.2.0/24" + zone = "KR-1" + network_acl_no = ncloud_network_acl.acl.id + subnet_type = "PUBLIC" + name = var.public_subnet_name + usage_type = "GEN" +} + +# RDB Module +module "rdb" { + source = "./modules/rdb" + access_key = var.access_key + secret_key = var.secret_key + region = var.region + subnet_id = ncloud_subnet.public_subnet.id + db_name = var.db_name + db_user = var.db_user + db_pswd = var.db_pswd +} + +# Object Storage Module +module "storage" { + source = "./modules/storage" + bucket_name = var.bucket_name + access_key = var.access_key + secret_key = var.secret_key + region = var.region +} + +# MongoDB Module +module "mongodb" { + source = "./modules/mongodb" + access_key = var.access_key + secret_key = var.secret_key + region = var.region + vpc_id = ncloud_vpc.vpc.id + subnet_id = ncloud_subnet.public_subnet.id + acg_id = ncloud_network_acl.acl.id + private_subnet_name = var.private_subnet_name + public_subnet_name = var.public_subnet_name + vpc_name = var.vpc_name + db_name = var.db_name + db_user = var.db_user + db_pswd = var.db_pswd +} diff --git a/data/var/run/data-manager/template/example/NCP/BUILDER/modules/mongodb/main.tf b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/mongodb/main.tf new file mode 100644 index 0000000..71b6426 --- /dev/null +++ b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/mongodb/main.tf @@ -0,0 +1,20 @@ +# modules/mongodb/main.tf + +terraform { + required_providers { + ncloud = { + source = "NaverCloudPlatform/ncloud" + version = "~>3.2.1" # sdk version + } + } +} + +resource "ncloud_mongodb" "mongodb" { + vpc_no = var.vpc_id + subnet_no = var.subnet_id + service_name = var.db_name + server_name_prefix = "tf-svr" + user_name = var.db_user + user_password = var.db_pswd + cluster_type_code = "STAND_ALONE" +} \ No newline at end of file diff --git a/data/var/run/data-manager/template/example/NCP/BUILDER/modules/mongodb/variavles.tf b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/mongodb/variavles.tf new file mode 100644 index 0000000..f98803e --- /dev/null +++ b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/mongodb/variavles.tf @@ -0,0 +1,62 @@ +# modules/mongodb/variables.tf +variable "access_key" { + description = "NCP Access Key" + type = string +} + +variable "secret_key" { + description = "NCP Secret Key" + type = string +} + +variable "region" { + description = "NCP Region (ex: KR)" + type = string +} + +variable "vpc_name" { + description = "vpc_name" + type = string +} + +variable "vpc_id" { + description = "vpc_id" + type = string +} + +variable "subnet_id" { + description = "subnet_id" + type = string +} + +variable "acg_id" { + description = "acg_id" + type = string +} + +variable "private_subnet_name" { + description = "private_subnet_name" + type = string + +} +variable "public_subnet_name" { + description = "public_subnet_name" + type = string + +} + +variable "db_user" { + description = "DB user" + type = string +} + +variable "db_name" { + description = "DB name" + type = string +} + +variable "db_pswd" { + description = "db_pswd" + type = string +} + diff --git a/data/var/run/data-manager/template/example/NCP/BUILDER/modules/rdb/main.tf b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/rdb/main.tf new file mode 100644 index 0000000..2128322 --- /dev/null +++ b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/rdb/main.tf @@ -0,0 +1,19 @@ +terraform { + required_providers { + ncloud = { + source = "NaverCloudPlatform/ncloud" + version = "~>3.2.1" # sdk version + } + } +} + + +resource "ncloud_mysql" "mysql" { + subnet_no = var.subnet_id + service_name = var.db_name + server_name_prefix = var.db_name + database_name = var.db_name + user_name = var.db_user + user_password = var.db_pswd + host_ip = "%" +} \ No newline at end of file diff --git a/data/var/run/data-manager/template/example/NCP/BUILDER/modules/rdb/variables.tf b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/rdb/variables.tf new file mode 100644 index 0000000..59b21fc --- /dev/null +++ b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/rdb/variables.tf @@ -0,0 +1,34 @@ +variable "access_key" { + description = "NCP Access Key" + type = string +} + +variable "secret_key" { + description = "NCP Secret Key" + type = string +} + +variable "region" { + description = "NCP Region" + type = string +} + +variable "subnet_id" { + description = "subnet_id" + type = string +} + +variable "db_user" { + description = "DB user" + type = string +} + +variable "db_name" { + description = "DB name" + type = string +} + +variable "db_pswd" { + description = "db_pswd" + type = string +} diff --git a/data/var/run/data-manager/template/example/NCP/BUILDER/modules/storage/main.tf b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/storage/main.tf new file mode 100644 index 0000000..5d08a89 --- /dev/null +++ b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/storage/main.tf @@ -0,0 +1,15 @@ + + +terraform { + required_providers { + ncloud = { + source = "NaverCloudPlatform/ncloud" + version = "~>3.2.1" # sdk version + } + } +} + + +resource "ncloud_objectstorage_bucket" "storage_bucket" { + bucket_name = var.bucket_name +} diff --git a/data/var/run/data-manager/template/example/NCP/BUILDER/modules/storage/variables.tf b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/storage/variables.tf new file mode 100644 index 0000000..00d29da --- /dev/null +++ b/data/var/run/data-manager/template/example/NCP/BUILDER/modules/storage/variables.tf @@ -0,0 +1,25 @@ +variable "access_key" { + description = "NCP Access Key" + type = string + default = "KR" + +} + +variable "secret_key" { + description = "NCP Secret Key" + type = string + default = "KR" + +} + +variable "region" { + description = "NCP Region" + type = string + default = "KR" +} + + +variable "bucket_name" { + description = "bucket_name" + type = string +} \ No newline at end of file diff --git a/data/var/run/data-manager/template/example/NCP/BUILDER/variables.tf b/data/var/run/data-manager/template/example/NCP/BUILDER/variables.tf new file mode 100644 index 0000000..ee5e18d --- /dev/null +++ b/data/var/run/data-manager/template/example/NCP/BUILDER/variables.tf @@ -0,0 +1,69 @@ +variable "access_key" { + description = "NCP Access Key" + type = string + sensitive = true +} + +variable "secret_key" { + description = "NCP Secret Key" + type = string + sensitive = true +} + +variable "region" { + description = "NCP Region (ex: KR)" + type = string + default = "KR" +} + +variable "vpc_name" { + description = "vpc_name" + type = string + default = "mcmp-vpc" + +} + +variable "acl_name" { + description = "acl_name" + type = string + default = "mcmp-acl" + +} + +variable "private_subnet_name" { + description = "private_subnet_name" + type = string + default = "mcmp-pi-subnet" + +} +variable "public_subnet_name" { + description = "public_subnet_name" + type = string + default = "mcmp-pu-subnet" + +} + +variable "bucket_name" { + description = "bucket_name" + type = string + default = "mc-data-manager" +} + +variable "db_name" { + description = "DB name" + type = string + default = "mc-data-manager" +} + + +variable "db_user" { + description = "DB user" + type = string + default = "datamanager" +} + +variable "db_pswd" { + description = "DB PW" + type = string + default = "N@mutech7^^7" +} diff --git a/docker-compose.yaml b/docker-compose.yaml index fd7b252..fb45f3d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -30,6 +30,7 @@ services: restart : always volumes: - ./data:/app/data/ + - ./scripts:/app/scripts/ - /etc/localtime:/etc/localtime:ro env_file: - .env diff --git a/docs/Datamanager-Demo-Guide.md b/docs/Datamanager-Demo-Guide.md index 34eb2df..6385070 100644 --- a/docs/Datamanager-Demo-Guide.md +++ b/docs/Datamanager-Demo-Guide.md @@ -9,6 +9,9 @@ **GCP**

+ +

+ **NCP** @@ -17,7 +20,9 @@ * GCP와 NCP는 사전에 인증정보에 권한을 부여해야합니다. 사용하고자 하는 서비스계정에 Storage Admin 권한 추가 - * GCP : https://cloud.google.com/storage../docs/access-control/iam-roles?hl=ko + * GCP : + * https://cloud.google.com/storage../docs/access-control/iam-roles?hl=ko + * https://console.cloud.google.com/apis/api/sqladmin.googleapis.com/ 서브 계정 사용 시 Object Storage 권한 추가 * NCP : https://guide.ncloud-docs.com../docs/storage-objectstorage-subaccount @@ -30,12 +35,12 @@ 3. NCP 인증정보 * [NCP Object Storage 인증정보](https://medium.com/naver-cloud-platform/%EC%9D%B4%EB%A0%87%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EC%84%B8%EC%9A%94-%EB%84%A4%EC%9D%B4%EB%B2%84-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%ED%94%8C%EB%9E%AB%ED%8F%BC-%EC%9C%A0%EC%A0%80-api-%ED%99%9C%EC%9A%A9-%EB%B0%A9%EB%B2%95-1%ED%8E%B8-494f7d8dbcc3) -### AWS, GCP, NCP Cloud DB 설치 및 인증정보 +### AWS, GCP, NCP Cloud DB 메뉴얼 설치 및 인증정보 * [DB 설치 및 인증정보](../docs/Cloud-DB-Installation-and-Authentication-Information.md) ### 프로필 설정 가이드 -* 위의 생성된 인증정보를 프로젝트의 아래 경로에 저장해야합니다. - > data/var/run/profile/profile.json +* 위의 생성된 인증정보를 프로젝트의 루트디렉토리에 저장해야합니다. + > ./profile.json ```json [ @@ -93,11 +98,23 @@ } ] ``` +* 아래의 명령어를 실행하여 프로필을 설정합니다. + + ```shell + bash ./scripts/init-settings.sh + ``` + -## 설치 가이드 +## 설치 및 사용 가이드 * [Data Manager 도커가이드](../docs/Datamanager-Docker-Guide.md) -## 1. 오브젝트 스토리지 + +## 1. 서비스 생성 +1. 서비스 생성 요청을 한다. + - 해당 요청 이후 약 20분 정도의 대기시간이 필요하다. +

+ +## 2. 오브젝트 스토리지 ### AWS S3 Generate 1. data-manager server 접속 후 좌측 메뉴에서 데이터 생성 -> Object Storage -> AWS S3 순으로 클릭 2. 사용자의 프로필과 리전 선택, 버킷 명을 입력한 다음 생성 할 데이터를 선택 및 용량 입력 후 생성 버튼 클릭 @@ -143,7 +160,7 @@

-## 2. RDBMS +## 3. RDBMS ### GCP RDBMS Generate 1. data-manager server 접속 후 좌측 메뉴에서 데이터 생성 -> SQL Database -> MySQL 2. 사용자의 DB Connect Config를 입력하고 생성 버튼 클릭 @@ -174,7 +191,7 @@ 4. 성공 및 실패는 아래 로그에서 확인이 가능합니다. -

+

### Restore NCP RDBMS @@ -189,7 +206,7 @@

-## 3. NRDBMS +## 4. NRDBMS ### AWS NRDBMS Generate 1. data-manager server 접속 후 좌측 메뉴에서 데이터 생성 -> NO-SQL Database -> Google Firestore 2. 사용자의 AWS 접속정보를 입력하고 생성 버튼 클릭 @@ -236,5 +253,7 @@

- - +## 5. 서비스 삭제 +1. 서비스 삭제 요청을 한다. + - 해당 요청 이후 약 10분 정도의 대기시간이 필요하다. +

\ No newline at end of file diff --git a/docs/Datamanager-Docker-Guide.md b/docs/Datamanager-Docker-Guide.md index a57205f..43f593e 100644 --- a/docs/Datamanager-Docker-Guide.md +++ b/docs/Datamanager-Docker-Guide.md @@ -3,8 +3,10 @@ ## 목차 -- [사전 준비](#사전-준비) -- [Linux에서 Docker 설치 및 실행](#linux에서-docker-설치-및-실행) +- [Data Manager Docker install 가이드](#data-manager-docker-install-가이드) + - [목차](#목차) + - [사전 준비](#사전-준비) + - [Linux에서 Docker 설치 및 실행](#linux에서-docker-설치-및-실행) ## 사전 준비 @@ -89,6 +91,7 @@ - "3300:3300" volumes: - ./data:/app/data/ + - ./scripts:/app/scripts/ ``` - 실행 ```shell diff --git a/docs/image/pre-check/gcp_cloud_sql_admin_api.png b/docs/image/pre-check/gcp_cloud_sql_admin_api.png new file mode 100644 index 0000000000000000000000000000000000000000..c138d993b5d111c40378c80ce81f17a03fa5b1b7 GIT binary patch literal 19628 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

(?{4j{U#9F!%~qk5%Nw*wC_Dw)5h3pO&G zMt6f}s(I|6vTX}(RG3Ioy}l&BE7-`a&~HpE5i=-?IlAc!k7W+AB6ahDiMz5$hkN=^ z74}}5dwN1tCPHLTu*$-QG6>a~d%(6LqaV8#&_A~C3>m+=M`qdnFf#n^o#Lxo4za## z^)vl37$s_NSUd04%^27LvCL`f@*cikMYK8haH6S14zt&ht3 z`fmK$DWgO1c0g|3rR~46#u7hUR@f~?y=t>~)w4^q*9(JB9yk0{c2W%(`tUnJn_|6i zc+#xm!Zq=)7*Zs;`5Xt=nE|uMtga758OTSUU%ejxEGjEP`G$vMJ46}eqlZ5QIX`+8 z{Nl+9Y#LaaF~ujg=BpjWWvJ#3_w97x9QrX1E7J^~1XeJZ{72+`{Ur8E-ocgy$a26*O&E zB-8T4P4*MDjf{-3n1%-{tQy{o&2)NVV&W;eOJ4Gmq|Yd@Q3SLs+#A ztD-on+bm}-di{_K6}c%bYNF}xYjIeit(vW54|Osj%n;^y(y8@&o$MK9#>|#-l6xn+ zE@FTDov2#?%MB1K8@@`Gl+Ddb!5UTU-qAb+RKG< zYaQp57hZ9kYrFf9BV{;XdNVsokgbWu(N#4b^Eo z$uf1n8zl1&Xh911akdWG(>8Iqk1?^q>CXcUo_c|HtQ( zuKGrH##O8Y$0_&lS(b`YElME{wCm)C>}d*WkBqw@X$LSvUbxorqgEq_fmmFwP+WKX z>BjcyuEI_XnP1;hH(1L7cUOOBd;*;WYeT$kg5W0rFGsIy#q=<+A@NF{>Vl@K zH)Ts%-bRj@%BL7_axvcg7#?S0_qK*f`clo>M-Rr)aD~Oophl6#W``SnHR}xQ z>Oe#*=GDQOv@MShvL^=K{y3ymtlNZV++ErVyV_V*;}_Av0Ra3>V2nS{`PS&Atmd0D zY}sPgHlZ`mHQzH3mVdoJwA<(pIb~<<^Gf2!Y5g%Td;C>9PDmXC=dEVw;?-HJVqC4K zWm9-Vfy33l!Y0*Amb;?HFh!S{)Z%|4bTUME==sKshz-USXtPr5mhs5%k)@K(#tb$Wu+NV?(l{r!?XjkjFQpDi!Eqt>CWFB^k8% zGe!U3Z)s*5TSEPFp++nZ7-*B+Qkq)%(9CqPiqKIyHoiKB83X>7^^Q^_gDIcb&$b+l z(7gRr)-YD|*f3c=Ku3Jklv!?W;*@=y{jXZ(zYDvMC;@XRj$z`o z+9oYF_BFr-C&t>{HniFN2VtOA!ze3Cmc6-W!w|()514C)5Yr2ke9d>+lA$){#MJ}% z2#PSub3B9%`@1<0ahge8;X#OPh{%&@kmgUWXKYjoj4^3y>I2#r-6KWrT-b(3jX#`grKlN%dq!gkT&b(w-U% zkQ-}aqeD%jag6g7Ux2U+T(A`kF>-7?f#sXfkg&<+hj#Ja>C zw_sFjbdzuKj_}()QSERZ*qPx!9PtUxYS!&@3dYO0H}S+oePS;H@0X$}t4}?>Kg!XR zN|e_9V%#6hN;zPdk+j2|(kN_81kAk|>qwYFLg>K$cb2;z4P(#3=PaF9WJ>sr$V-BO zdrPyM>sZ#>LnfbY$>fSs>C@YuX>?NNZR3?G4f63VnZ5nf)(RHsd+NHXCfVby&q4fv zyvK|KBd>B6t<0o9R_=MSNUTIG&`$G-?XJT1+g-SKskqbtX>uyB+bwK+HrCZS^^it@ z{aqdM@&i}O_iq$nbhW&|y=u3v!bd>IlvGhyS$yD7&`26cYP1TgE=KP>Rozy*Nu`DT z!6jqm=@*;o{Jx?iCi!I#{vdD7PdIz^?Q93TO=4j6`P?Mo$o+=;dT%5qmt3&Ntm{F} zB6+$PRr22cJjL~{8ekLmc3mpPl`ki(r``Q6Bts6?Lrg{VSGBQoR`#q)b;7_BS> ztJB0WAUA=th4Q%$p5U(1HXh?| z&e*#rRC9d>?tD4_YS4qM+l|{<2@D#j8yFX#dp{$F0v|q4*lnQ}%H!hA$R7WX<{n@R zPQ7upwO=&&`gqS{x6XgA%gyIikhQBqWMuGo`+@flh$Hb&(1f>FRwN#8m<8UV42)|~ z#%m2#R9{f+B&oR__-S7XNmzgHd@OFB4Y{QwOF(wO%7`WElMk2L5rv1Vzuo!$QyUG5 zVZMo?*skZLpPDJPGR}JA5;~eu)}~~2Hjgi?JIk}p0kE&$cCz;JxHl~@YF`-ClA;)H zLEWl$${81~tBm9_=6{hBHBm7*wk8=+>+?>=If?(iq7E`kp$C~OL~t&`BO-te%^+JY zIob{gx{zBOLcok8`4r4!MVW+kt(}bp3`uT6=7+Oa*bm#D|ptnB4dxku=_gnvt5_T`*tVpZ#*=l zjAOMO1%GVq+2txa*bJQ1G>ARpg_JoQ49bV?Ch=YajP!3grxD^qAzT$0*DV-B4bJ}w*(uD~V z{*;82O=ZX$J3*$;75tm#r$s7d!amC6Iwe8Q1+N?~Tm2{uNEdj168)hzW-k}}SW_x7 z!2Kkkm-U~)*$zjYa<~z{#ZuztcCu*so6mS@((XFZ0VP>HZwJx-=vgE#kTZ;5>x@t_ zQ3dCkWN$)Drv{hW_dvMXB=tY?mEk~jrjWKs-`CEn;8r>GmpY@?JznHfVi?x*2zv_pueYm5=sqhm3xWmm5+o<8rP}SlY{jn9B3DPr{lSQ7F zI4I{gc0GcxCCqu<$Rc|M*eApk;QC{;LP#iQR6ka87gLj zON++3wKym6!^Lt!Du{CU8%n2S4~(F2O|l*Kt<8c;zo#2UzkKjfrPt&*(%@}3cfUjI zcc+DrLt8`a?qmc_`3e6MQz&R{n-ktpo{9Q9bVsM2R}@_Zw_FXo;yvmZP(`i{rp#U#92&NjZ^KWhSkuKBTf~YNHEQv=zQy(_~Fv z{&?JMYl=}qP=#kuJ{$=00oTCJA(nVK&@*GeSzXhVsIdOTi-BdsR(irAw+M3x`GhQ4%h5Gaz4Sj1h>+t(ugwtxkY=|5&nVsq z&qgz&>)oTRVq_+<>!p#c)s1x1R`SV8Y#Z*}7te{qjc2}NX8X+9_@3>w3aAln+TV6#hFT!s7C9BLfa(1QAf;Q*M$kH7_W zR3Ph>!=DyIyt6hYJQ9W7zBNDKBOR zJ~|iT_VgQks?O1gVF>tEK__p|fJP~|VeCxg%Q)U26`JXc`AR^sAsIH#E zER&wt&a00;aj%ML^ue6;l@p^pga4i=)?`F$hzj{D$RwR7v96_%m@I&28u~q2S|Xv0 z3;TtUDj~#@lzMeq(%a`#-23;p?_Ypj1*NePjAfZd&YcBlP&63W!6F=zL;THm*XNVO z`l~;P2cjCV?)_C_lS1W*(dSd+3^w{dy%cH3@`j}QH(=}H8Nw*&!E)WP0#}J{-!5M@ z7R}Zq>j%IXH|c4H37LRcG9&IXoM+0z_m!>)RzfWR2#hT{;O}zjPO!FT zEt-J*XJ(NMX6@y2ubiZRD(4N3D~fr-Q4H$vWYGlZKeuxjx3w5Ms6*(_o#Y9dnjr@H z8pa@BIYq7N7|!D=GAZ@zYT*Q7k{iZQlPBZp_l+a-jHO16JRDukn$WF5Gu}94ym3D% zDd}T;e4R6)=-%>r?1Vy1;=jJGYXKi3QrAZfrI0CE-gjP4FxN=A=X$(iL=Fs^9%#N0 z_SNuiqgK3t0y{PEMqjd6)4wMkpJJ$efHAY*{n!1bnLpc<0QD__dk=p<=wfE%%rKZX zwv2cF$G`d7s+wL`XjT-76^d1e$#7g`W^~IChHC-#DA4kw=Y$M0!upH#sAT$oJ-}F` zOqL{EoaaQ-(N-UiprE7Mw;~4y2x2L3FU*+W0psTQ!D4Q%fan05_-w2D=zo#TY>5b? zf3!41;y}@cOx?xr-@pGHa+dvyDmYmzaAn|0y<5F!z442GjI)Rq{sKa7ID*UQ9lPLo zxwSZh3`C?3vqdhHq(51{yU|Lh?5iBBoO<5D=$nf{Vw(j2OVs&K7K0ZoJNpX!L8wJ{ zqA-CGvIQ;lUk<;0Ny1o9R+AAOS)-j)!{5JuZ&s)izp8>fNW09)rF(zjUuxaZ(jX&! z?Iq}~Uf#tk#4l!v>}{5inan)v%)#&Xlxn3PLPSxcBA_db51Nr3ap3B)d`W!zrti2I z$RNjRpmFSU+fm2gcL=ZLTe@&J3E?3zwJQtH$5}0H^r5%FyGLS&#)hDdeeeoyJ+(#_&pv9RGmDRG?ajj`$;e3a1aKx^A9QY(V>Znfav!L%dfZC|r35ekc*| zsaYRo@zC2RtKeXJQAM-5D_FHy0g;Gf&3&6O9^ymb?JPU?hU4xi8*oyxm*=m#%)7?Z z$n2eTwF&3e?rc>g0lGJP?>$xZ#Lv%?fc~EigMo1=3l+qHvqj% zA{SYzT;{^yhZF#tN24ZLUE=pC`8$)5%}G%ng$+%j;C`HL9sSLPsc(bXwRF$Qu6bw& zm1AQiTKn=!=HC<@CqkEVYdukRYm*cEeB%*v|GOP()SD0!b;Wx6y)F(NSkWAyrflTB zdly#@ch9t(Y*=zz^HH_66cVg#sK-l7PL-weB$P~FLz>#S$P3OIa6(oPMYMklP}%m0|utJwwJ zaNF#Hf$j%9%{SU5=G1xVsO=JDAxQA+Wqk8=nAoA}t7-^pRATQEDYq?$QX^*LM4bcDtti9K&!T5%lY%$|3Dz$&VyZ{Mo!VbgQl?{F}A8&LCOg_UIuWt--8P=)f zT_}-8lGq?L{JlG&)~yH1sris?cp|y(-u)~4_DoyRb z9tqfwxTSD|dWOSr(_7s;KB5h;5c>BL=`)(PeN=zo&LOlau!qMCHu#UG*Fit{zLtab z9;eUe)&|%6{{7|On#xQojQ+U|asc-QN(Z<4e*eYU`iDZ=udc3+ASsix|Kb(sOzfzg z_?j-}M5A5g^pPn^y)CGo=gHJI{%BJi`l^_9VG7g5Bmo%>Be9TvarU$ZJA>?|=y(jR z?kw;?bRX#claJ`2X_IW z?O#}M>jcsXja`{^$5xYV)rB*m`wdMleg&@OOqPk^MJE9{cq z>6i-@vZc1UQZcR9ySEd3x6WWv=-cg%Gq*QY*EhrcS~qeBLkI)1!6~a#e$x_v;~n2! zcSmhQx5xBJJ=X`1nA258KFTi>rf z$KeK(%*TxiKNYqvlN&OnBU%O(pc%nej=||sujT|IdJz3+JF4GzWfaMGPx7F!ZXi=2 zJFxZ7_DFi#GjAF6dK(e;Tfimt{>=gPCRwVr1u^x-^Vdi0c_9TiFIK@v(~KRs{X5X( z6SWcWDPw|jm>yYSeS3)g(-)7*V>BfE63To*G*c~EZoO+Xgv}k?(MwSd9aD^N`buIW zmTx~X7UC&^#sY84VcbORPYGQvi6jJDVs;W??&(!ufnb5)#4zQW`1cjMUi4T?xrRV-ZEc;~ z*gz>q5?*;--Brnun|CsN(&O*->$rglAM`t+s`@5vvOEk}3|vtNZgo#wE0#CD&dupI z&^CLgqWN8bLnu4#NefnXFtjZ=+ee_Vhr_NfOS#VpUA&>?(cUt6ziOeIO&F1*OTrxv z9c@UB;P8j*_Xx|dZFKHoa9YT!5eDQ&^YB)|#{O2`ms0l#>|g;;b&TIESgPLxLQ6d8 ztM`Gbx?)19!~5NpsGcdejT5 z8i}yEC%wb<>1U=dLl-O~)+zw4DZL5uD@w?lXRjB*wXS6niiYG*eMRQ7@LX zCx$s8R&nIoLJh?}h|54MYprX~N#nMP8lF%CamOi$9uXCUS>way*YK$9igipcxrkr0 zYBUIZGnhVAr%4G; zJ+0I9LV~zzX=!I?@gDY=WsF^BJ1xM9n>HK`~7K& z2?u!(3`KpZ$@CAcM0sTcsHj}$bX@DZ!*bz;i}Bdi<4~K=@_cp4(i{^=*#kH6;7-=C zx#Vwwy~cBAP6#XBR1CJ7n9$u;LtiVzt;Zx8GDqsRFfKvx zvPF}8sPJvzuvj^}z2l@EC$mM}^>Gk;WTTafjw-5->6Bg{>)Ktvruj;zY^;-bajV__ zh*s0_o}(LPwU|7m!qv=zZ96D-prFWyo*IiDw=OwQogT3om2UJ9s$n&{O?!QZn%|Z0 zzJq|fN93`gW(sxwr?gvvKhJv`g+8ph5=SY#i?d$1@>%*;<_+Ql5vtHjA_wxcvj8qJ4X z=>g(77>v!ZbwsR9Qi^4q^aMKX7Z28@WGdSnSyw@29M2V3*y|WB_RqG50vs5Np{N>q zA;*!a95ywKhRxa;QLpQ)-L=Z_a3r;*^EWFP*3gskS6814PJS_{;VmjB4!`=yT9<`g zd!jmg%Rm5RjQeJKMDCes)0Q#{wQHK<82d$j9igG+jE+>09d4>|_oPLF4^}lNzXYUF z=pp>_R|lQG3tzPHEVHbS<8U4p7yemubaxFIDG4FZXByVcRn;YQ02}l|J3gvvFAbZ% znF4vta@Fjt&uE$`S=KSWtYRIz+2M6uqS;WmPWkq$;;@KAi{eSQKC_jIMDix2C4iCCoJ{r7L_4RIw zPp0r~q2e^Q(K;_WYgmWl-k_B?rWd#HxI{^D^c)&^0LeJeHHORDY+nK=k{&OiL4hVl zQD0G@ZMs>;IyFSNt#Wx|HE@Q1S^A5bc$DRM@$I)%C@X z5V&N$#&5^N>8JumNZCV+ZMMBr+P7|iPnnghQ=MqbF;8sG+Zmjbr4B_4r_S-^H;{(# zZ%J2hqq@j>-FV#2UZL!h6;}#)O=9$EmC)LlMcFou9C3uaO<|R=X$j#!NR3GGdh zd?*z$VRxM_-P_idq$(G%axa*^#dOowO<2Vj^E)OhFFRi|ghjSn%x(_VKg_!8&tLqO zFwilXJNks$9B(mw8%%F=aNCbE7TsYF2y`s%eGG|?Vm4F3 z-A~-tH!uj$Igxjcs$?x?8fm|=5Hyz27H2sWz@n#7EKQtx74>WW`S=)Q$b6^JPIW&3D9{p*|)f@gf3544qj128^;~dAZ zdQz$4X#;?ES#n0klHtEqdo|g?X1W0SMQ+cvPNjYo+OPRlTVSn@SMh) z_IoYl+?ng!V{GQ0)P$7{a2r9lDPj40Smk>@UoL^pqfz6Q#rk6@j|X0(t#aE*nGG;|X-#Q)-eI*Ht!4pryNI zNDap;s#Qw6n~@m<(YvZ~O*l|3WBXgS@T)~u0Jj!H3Rg95WAOCySjigikK~eyjdw-= z1&;c#x|pBbn|jM+pLQWmNvi*VvzIaB-G4K_FC4SZTp)m`Usv-B<)Fgj)hM7~TJgyqcpNTyBqf#7IxhfQl`@QS)o_jMno1e|3ltaQNf( zu^m|Wd%TvR+Ow4GlV&QM*UZInf6`Ka@5b}qOgXd2_VNi!QYp@B^j%>(RD}B~clIs7 z$A7sY|A8aN?Rh48r8n{oWj$XwfF#sqpnXTqy!;>SXJXBE%ak#9Y0If-N)Mkd{L9fo zOQ;!9hbB()>v)sP)7YG}f27t@bF=Sqa?2`oD59)i*kn>YHrzK9f&Rx;3-{k8&@A^9=elwMHl8DpnwyKC-_z?SfNRK$)f*i@m6pZpeS!R6&Le$mwL24gjo#TJZN>{mkCER_-jMr2>C%g zo$RDNjxJPknW`}F!0yT=aSTjUxBwf@kKe5Sl5?o3(sX{)G%DX@jo;yE30y`&ooiv{ zcwd*cyk2jR-8O^*VfqNuaMfP~Ndp|ysxHMd@KitSq zvNwg3Z^ChrDHEWyFwqi?ofz2pQ_Q?d^BFD8k&#p6`e?i#%(w^jkNK=qH`eAj(VuA_ z!YJ|cPFmy!3|~B(^13nh5TZ~&9xE_|c+`)jM&j(pzFCu!7%>rQ}6uw#UX&uG> zJT>TDJ6<>4&Nul-*kl8d1b?0Z2%W>x@qZG4?Q-+->akoeyo+0oI_Z0jW3QR?EW4f% zJkvVK$NMH@d{9PVK}*BqQ#Sx9Z!esE;rcrMY#h2J$`(vt=CED>je;HUI1oA~xL7i=L%84Zb$uXJQ2f zd2JfC+t(-=nkF_YVr~weMz$T%pEcECo?JTbI->$Q_!=QHc;4lV;}c8-Zv^^mnZszp zAADP**e%;7anpr_Ag)g~#v4{XCq~Cxlpr|`i`R&@zdoOl*lfAH#KULN+*$2+;+l*QvoU*U?6 z?62-hDd49S$cE5n>U$a9X|%FDE}MBu#ih6-Uhbcz(?VWEU9h|C#rW?912N-%xBi^L z$i2|{-zMLw?FFyJjdNNOu5zQF9 z5>8+{ne)GzIro32_c)G!Ws50iPD+hzne%W8%dMgIU^~dQ-0dti)5(2VjFfxQLFJN$ zwh9SZ6S|E^F6l_pO4y>wHJ4#2RxZQ&s&mfc{C>_4{R8jE=l%J79*@uK^L{^HZvlx6 z6CNy8Y)@A>M!<-o$Q3~(~**Rbrh%x@D^qz zU|(@Hj5zrS*f_+pZDjYl4;@Q4@-u|z%Q$9w_O&?yQ%Jlkj&|jK_ zF`LNGb1+jCdPn)USWA*{adO;kxKvaJioW92L}*|lduX8EwSkS6| zn*1}VyHWd1a#f(ZA!=Iey@p_i`rH* zmbYbqa~3I(t&Qe{(k5qOBmbH6LpeYmEN*}|EPs) z#$R}bcpXdLb)RcgQMqt3U3~RUJ7UKz|G^Du)jbH99cM&X{fj^kQE2LK&jsslFgPab zc=NCzg6a2itb|BZ*V?+}*6?!KRYcOw~2kXu0hBOikiG~My47zezF8YwJ1|>umH~%a`^^i}BF55eH z6UC{q=^7rWJm3|cGP{m`)IwVmxW>7T!yPJrwC~`^%4@{V*NGT4HhDWH{YEjp6E2#5 zu;}HVatVp#lF$EO`do&E=ozh@eR4nOU1W(^x6__QDP4Z%dDrJ`j`TRQhpFN;6Lt2I z%9GgEmT)i6AJn&d1j+y&5RJR8TLq4LxAPG?yk?Vl*N1c4${57$u`?>;xtIeyh%Lgt zFCWkDJb9xl!i!_%x}oEBz~k$<)UL-%{9$ICeWmQc8HGR)aC*8N>>Ds(8Tr@wnf zb5F%+%%tvmfNc!&KK%_>@Bw{Y?VPDg<|-43C1Fk0{nN8@JgN6&j;W4qk6HPR#m-pD zN6b;I{X=6qE;&(dSD0cEELE&;9jZ}jHPUMPYjYe`o;@^}?jRg%n1Z5e$wLYNTj7D0 z;bfa6%_jVOv{~VJdEO^RMEA_qiJxRUip^Hov>m3sb94FRdn`mD?noMpTp-b`4Z`a2 z|L|qM(@#VcT%k+jlu@_yE?;Bg(i62qY${-G4!=#|7)A=cF>Xy3K6aAX3799nH%aLO zuafzGN=enitoyBFmB^g9j*+d#PfTv<7y1UqLQaX&ln}6t1*zL4by!&=34 zS{)R>ymIGbb^LfPl}bukuiZj^1fBb!N+hsnt4KCMNaYjnxc05CBHV}hTuk%RCwJ!~Ki5YjCF8UCHy#Xe=Uwojs>-tlMq0K}k@%Q5k1g$dcR6am4@{t1LrEA*t+8KFwfI2M39PB9*4h9BseK!7_20*WP@)6I zjYSlm&PIRm3%v&fuL!|54qvM__YR_MGLTc>29Vsd9A-F~kN>aJNRW0b_!tKTq4><` R3ixONc6%MI$}PN4{|VLIT6+Kh literal 0 HcmV?d00001 diff --git a/docs/image/web/DelService.png b/docs/image/web/DelService.png new file mode 100644 index 0000000000000000000000000000000000000000..bab3c8891b4ec2986fb010e523dba07fd4ac77b3 GIT binary patch literal 71182 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�*{gbUTO$%#07s{Lp8`$4} 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 cW@G<|^=0RbJ9Y-s2j3gj`-9tAHteiIRF3v literal 0 HcmV?d00001 diff --git a/docs/image/web/GenService.png b/docs/image/web/GenService.png new file mode 100644 index 0000000000000000000000000000000000000000..bd3316bb50cc145897217c56ae64e5562d9cb020 GIT binary patch literal 40880 zcmd3NWl&vB(=7=aG`PD3=ip9ocXxMphXBFlK!D)x?ry=|o#5{7dQYA_?_1yZ^ZvM1 zcd97%p$>b`^zK=`x>rw_ysQ`kEDkIf7#MMjN=`GK0ufW$OwReRRiH(3?MOHA64T}c%!D2T(A8qQ(ZQe=!c zcK|9EO1(>fHvAq%Wz`G$$dUHn|5>HR*H&&SY{eOO#khL9JrR6yWJ6621(NHn{3WuPHcjEK>z2F^mt`s7cWU{!@UNR5e*`z2U(=ha0M>PxDibTV~g) z7Tk`{E$d;iuKLW(M{&uZk(z!Svi!^`(xK5`D{AB0PA2tf(7xJhP~gt71g1Cg%$MTd zn3wBIv_c&R4xQ6lrqwl^h5s2*V(?3zTNNp&qI{2Z`65W0mNAB-4wPFCdW)=h37K(J zFHmm1PFDor+9$|7S?CmDdv z>T#zz|4wO4K`e3EuNB8h+G(B$o0qGH;5f|gISg7gz=%7S@ecabRblX9DCGCnkZ!|) zp%&FQrJ}BhSj@`{MDoCm>@#tgDt}2WhGLY%H77$xHQENZzTr={SnFM|hzZeic_tg_ zxBHi8CMH7l&e*(tp;D~=i4jyxhTBtzuVf~jS>3;{y|yIeHne|0>8#}6t8wNQj{8il zss)anYl}=nAn_dLmN2r=Zacze`0g|Ls?M9-dQ41nS{1k(DyB*X)zM6PRS2@~n@`tV zT<$r!-`3R#T%B0^wVfGJ@Hd84-z|RL0b|Iw+eaiAh+(K7`MYG{sPg(7qsOJ#v*8p2 z!V^hBL(%M-`74%#o1f}_v{=-(p(1Tvm{(HRmwd(6$^7!z}X zK??UCMnZC@)q}KOwJrI6xM(P+bk}%(&9T_VYH;_G)Z#fZf`qO`A*0;g*w3|icyuK0 zwJ1?VRR6sEDR;*x%IQ%Mktt6t?r$A8YKU zbqfkdOi)ux@rlh16HLe+2ACljA8|CbZkImeZIIu~v=rQMX0~RXkp0C3%a0`AuFVWP zYE%;z)fR{*25l|d_^NH9Wbm9?%_k!XkkudV#u~6p>2#62ApUFojZAENv`B3I%>9w`HHam*Sr9bEB z;TB;{b?WrjRnF82Fk!k`Kk}b43tQqm(LI)WX8;B+?4 zG%wr3f6W|Udu?dQ9fA+Vu5GtYd(Ezj-5hfk>ot5`xpX?XxA@tnkvK(46W@W03-Vot z?GW2?)rP&Q(jG?f&6FF4_HIKV0hxd7l(V;~Ct$N-tmP0t9F=DHLV1-^qsmSaqol)V zwm_Kd*s8-~E-D9!UXkXHIiFUEwS!Er*N;rzu)SfdWYbO%D67}sV?_V7KWDB;U<#&Yg|0k=)>CBIRt{HZ6u~5Hk8k*J%BTV1As>+IbrZl7Fk9(n zRG*otCdLjQmv|$w|Kgb;knwx8NjKV^<5#|Hxty2QuJymGlYnr(>oeUvspn}9+kJxa z_1-9qq_l6As{ds29enZ5o ziH0=}A0NLSPV~vU(e)s?q#axr6St)$s}rjrZ%AMVqdJ?-!4?^_O7LdcCj5G0#5$&Cty}TtWa0J9LQO}h~}s&BaEIn`wrRDS0;^!wP6@G zZy2iBzPK?Y=Hsx*&s$AC3oaL)oZ-3HU77%icl2EGCfyH+?K89tG(ZCD`IvVsQJV4{ zo;D7tNS5@bFRNwMY}>>{J12q;@+dx7b~q1Pia%?XeG-3`S~yGZWt8|=jR zSwJJSdRJE+*8X^&{*sv4CW+3B)0@gk>HYaEtv5m8nB?X4Wp}Rb))?CMU~$THD^4jx z!rUvLLu%#LHCgOYuHZ#(hdSykY+OKFl~r`n1gXtYLa-N zzY`C&g`WReki<0zIT2+WB?jH9{OKmt#xRpZ6i-X9(Fx=#lV2xt{g>gfvOagdXHYN< zx!4AONhXpgPP&`-X#1S(Z|w-QLYZXDA&h7m{XkNR&weXl3qNK!!-?toSn7O2UPVfDEpyK zS~#ftOCgd8B8Ts+qth(;l!_mPVU<7qs6;1PorOP(Hm#~*43fm8r=BG;w4xQfk01=+ zUGQ{m;MYwI!A~GMGo*;tVek*ErGs*oPryVTAL%Y-I6@##nZ*Bezc{GDno}_`ahY%L z1bx@;^x?c4Uu(@W!eHw<=FEeI0y+_HY_cN`AF7TT3D2arKX>MN_~jJJWAkegTuT<# zbA#}ve+{uFz4}EFZyQVVgSKDNG@4#sxS4!*JdRez>JF?z_i+xRConWI$kacZjmW;l&dS%weRDhKB#a16i0 zCx-3y{@ofW{Ye>!j@aQ(i++4?+_LL0k=l)Mp2jyx-Q`i}Elpa#1jvKg6TZg90ezsi zFE_Lb6NuzQ2)&cPg(}DXFob2W6O+c7gw1VJ`KrkE6TiG*e6*qT;UR~OdULX0fNKD` zXSo!aMbuiNdnMGlH*6Jy8va7f^wJSx{M8pd6}1<@PKrJfSs^mB=rdJ3;N$ud#BNxh ztbkZ<%_z+$*4b>>rL^j>r*VHpn?B=!RYUxVpHgB!IVC#+cz6B7>|Qb4LX3h%IpyEX zU~25rzRWLuDwXrz)dZ9x$UMWBc(&q$p~g zJOR01q~R`|9?spH$~YPb5~DfZBx&5UuO?alQW_G==p%r0L<)56)w0Cg1&%>J{1UZb zO_D|AKL{Ken!*a@sab}nJ&sn1f#s@)*@mxAYM0QwxVa9vk{>T&@V|}WgU=3oN_=AJE07PvuKzBGaCh1n-mEqKx$ti&B_YY#i}26j{-!s< z=03X)8;yZsUrQ_OC<}Pw@c~cGt-;zL{(DfzlJw%o9@<*-!mJk{6eSNfU*iDJ*sbL0FFxI^;k~@m=yZ^ ztua{%S!&Hv$BWs6il$0E+y{4#?%DW2)q{B&Dk_1KIp-Jq7aYFjM@kgd2F7|9g*!Gr zD9^u(E7Cv~$Y|wC+Vp$J`$*|BV=DD|t}kj-`{lJA{NYs5Ar8_D>+CNx%`p{%pRp_- z?lW^bH;f6f_1fa5?kL^jra=N&e?$l8&6jip60@E%7gY@W#V6!B>De6*Pir@hMGY#g zP+PmLR<7+e+bg$5D#rg9Hw7UU9Z;c%YZ6uD@p*koD{kuFH92$B(24G|Ar8YTToZ){ zvCoa#qelQn7-$EjXYulaZuaU?&=g?7(;3r$ZXEjm{;mCAd4>3o zucn@b(M>ALiu^mo1=(@M0z1t z*9OPa=#YWI0U6zYlJ$*l} z9bF8Lt<>`~c=rMbFljKI3&jyE)7R zKS46cZ`2cNWL-1Z)rL3Wf6XrTtpzP)a8PfDXkyq+RsW?t;Z<`+t@v*N$?k3T1e|{S8>kH&K`80J`h~?0I%dLj*LxAhJ>0i7<8cI zkdPv=_}~kD-|>lo(jv3P>#=ch5rn=g{@0lF!vg~u{J>Xe#I1)*R1RMzSg*UYxZ}&v zZA3y&>ho6b#~N=rz^K*r&vJ38R^m*W06snM`cH6r8sEhTUR%AR3k#v|PWiu?nZBd$ zkM|7^d?G1gIkW?AEUbE6JQyiWRRZ}Nd^&YHI*K5bwG|_~y9H@Iw&|MBNn%(IyTUja zZtaGRW_ElPM!Ns&tFhYJX_u9Lv` z7hBa|mPa05{4%o=lxSWkPdcj_s{1iB-;wU45r0f*)EuasyqQ3Ez`nyXXL_Po@p}{g zad@aPq;=d(UiKRAIE(EHk5(81y|u5w;sYNnWMpj+1;Vb|NL$QIhM zQW)v_?}DoPBN4mD2|E%)*vTmiH{SO;zkdh}F*t3J8~(^AF*NjGvS532bLx*w8a(9U z0uhTp(+K1@G@2mgq|#WMk0J1K4(E}Uf-gt0xybUra@FY+R@i^|4#C06m17iwc*W+B z215}>OAvcX8oFtib8wyC#PQe;v&HLtIt{tEw|B)=j|YGAw-PpmUoMk6?|vLbzSw!M z#>0M}$;iwMGUt1g8YV-m)lObP9tkh6&Uk^w<@x*I5`W9xezViy*ocU!>QBe|{#>}> zUY!nFGwd*FGBIdq6(cD2@0WPB+Q~{YHzmJ3y%J~r~EIW+mx~-dbt7y0>si|(xqth7|gD`9GAYF8`HDG zKgWBBk%sF1gykh?p`Tn9Y}@YNpbzHjX++_1DF`W_UKVGm9!v(1U|yfMA08L<0DB#m z?mW(1)67geMn${-MNx5JqMFyu)wPhWZb#aXk&zL2LIV2A>Ppo{pNG5AP!6ojY@fw? zN4lfy3`)-sm)qI*&bOBD)m`^ScWL{K#*;*4j~AWxE-nhu(D1Kr@HS$(7r7E1v6J zU6s)&5kJlP2`-9YbJ_xo^(Dn$w|j)DHp_L`yGMn2p6Hyau+iFuu>l;ewDFiARMpn@ zp!)gYAu49l>xG4g<|^FDOa1z*o0^_wT$tJxDS5ZH}WYBh=w0RR#e zo1`Db5G|oONe@m4{WgAe^)$KCAtzR9#{%22Nsh(Q)G>q_K(S+3)6~>sEDN8T6yW?I zUZ#5;%OlhFWvlIaUoR#-J&<6vb*SF=f4q$|4#W9kzp+PXz6U$3mDSbDb2qiEjH!F# zhd1b5>;{7LD@N6}_A**Hvsqr!YTs2HbuEqUutT|AvvXe)T*H4^8WHn|PzDE*=O(;CCC)V)z4(#(jH3EG5rlD317OR>SQ_SWE zp*4H!{9yj~kpiR1wO43INGtpw&dZ-Zw?9K>75e#kH|>$~Jp6i10=$M%yMz>ZFoQUh zI8|-AcNMG8FPFEAM-yU8+G2y(c=A60oWm{V?9B4=@)BPkOv{kk9@Jsq*OcJ<6uMJVdIriT|;AtIW)h}EGw@L!nL6xiYY#_WI=s> zbvWri z#p>-QH|Nh>9$tyJoi0{xkw_hK9U*)U{M9meJw$RNegAPV1!m)X#jft@kI%lp^|G_- ziay3$5g{bd zC#rYTHe`HwN;H0|Gu;j%OEP~r(Cp-qeC_}|ZwsekRUs@Q1_fgrA`LyQ=vBS6aN3X% zmo>oSJI*Oxd=Gg`fSicN5)5~IP{->EV@*PmX9X7K1euXkz#>gLW>IjWv##eAg17f@ znRR} zNI62J=h zDPqf0wyu7H49i{3y@CtpY9&|Yyw;!28bJ+6^|yfs<4zc|&|wr>2Q7Hlu%Hpa{>G^!t0&q z)b!HV@(_Be+}VoB6W;g-me6Tb*S&1FlAMe{mf8qC>_8+z$v5mjG#Mcpn|D@wRTZ1p zt-kvE%S>4j7-a$xFvfWksv|y-$Av89r}V~D2fF7VuB|G7-ZI`j!C8k}?$R>&%@R5P z0}D1}6FtT#-DGiXTUcm{;+_cJO5H~}h+BbQqqiJgO;rC7dWBp@l1U>dF)4Cp%1)R> zk(hxQg6-F|;blh7s+@r}jEN}A!2LjBr#^Q#lU7*)WG2ZxwFGo1=NVfj@s{X2oH=bV z!+ndWE?!N8AF0i*LI!{z!l#6|+*2|VR279Lq%yLz0DmW%o}NZaV`2W#K@O_UieEe5 z^xOKm)c&Rd2;-q&f#k|9IIQIPp{SLzst0=(I`f{*S|hCpsP(q-eM}-8$;xC5%~Jcn zho$NP_V}o9&gZ+|4RlrQF^0H1UKal#A=94Qn4mp<>8GxT1>eno zV!H7SJ<~V+kc5sAj6_qH2%sT@@kuYiE>Q7C&gA7oWH{SpnfZ4rL!n>g2x{QsMXa1` zVs<1c8s2@u_e*JNQW65){5pc&NJM7FDpV9)mFX+O)q(jzY~n_t&iJRSCC#!H$n=zG zL}D6q#(M@MA~s*m^3HM!Ft8ZA!MkiF>xR2OuHn~3h?bTU3cJ-c9I&&&7*W?zx%*mR zb#Qv4nEAo>+z8MQS3fCMA0ASvQ;Grq^S)~sSK(djz{?6liKx4)Dmo%cUL-SA;gJCs&agqWvx@%R&&X3_ zN*>S#U4^lW&E_0CemuA6nSC{wJq{uo|3n{>oKz#_EJ}JVq{M`>4AoPeOYJP047{UY z`nf(S>$3dUX@DD5c_&W7$ODYS6latA%pigT{wk|w(|GJmv-l4q-o1l05rhZzZV`GK z<;Xl5_KVl^oczt4AO3lYTG^GZQyijqfuSY2g8NjZ)egRHCOQ+BjAbPQpXp^xsVmaf zBJd4y-16~x5+S45iYwn7YpHeI7z|PJj;UL5!}t0{@Mb&34117_W{mquP3?@@kr0@a zZq|jsdHsA+X!FR@`fS_1SeD~or}ur|V$S$N9QbAiDOC=iYo48XB6$=3q~b*YEcW&m zeWQp=pSc55JpfzY(74!55d2AtsSaOzOSiBaoeUp|uS{UNt){cdYh>NX)BvQMYr}Ue zbrloO+hJ-wF+1v8-PaX|N*59bur00~|@hld!{2D_ll{2DX%a`H=msl_4)}H){hg|WrCIz2f;ZywY zOLla9&hN|T4&>ex1g{4HdwqKUk*@Ph$R+mtwY zc(4Pdm2DyT!5=Z_0N4FD6YNF;oy*-~8XQeK$kMN6JfG!p7h3l>$VamTlTG2pnWPr#k~`m&X8rC~W`9m8>_5dl%dhaD za5|^FzFH#GD4Ea%BsSEmfZDIv8)EgeM7)Aw)s6@~6E8uIv-eAoP8C1lDx+1+>N-md zCf&G1cL7O%eVEl}3Ws9ebbT{&wAgBeL_nf~P(Q;*15$95yI(GUZzS zVO3bQVDQL2Nz`GSW(NZ;u>SWzv4p0WWM1u72z|jpvQbU40!O5NeW9M>@Z5`K?%28a zFF-Be0-uzMDw?7BOs|LfqXh)w`FccpCjCG_3|QSvr}wdh`*ZU*&5#s}^uCh)c_LAU zuQ`sE5w34<2gipW>$|KImCL-`m=)t$bBzl~M9!m1(%JwV?kIwJW@sooNcGv{;f9Ov zntE1%lcXxKi{1js2?_buEV~#-;8DSh9Q*((lH|Fb2CFbD%i`AyxfXA$UEWbo>cd+3rQGwpM|B<=tPT}^WApLy zfmsO}`y54mvy18WMJ&Un1_hbSuovBcx3ESGnJ)d+*KpQJwBoGkP9G5E>~s?e`j%dH zYfr0-89dOUd}MVda-x1G7dVkB)ChugTUjT(78PaX?>9H_Ny*9GQ&ZJ#88&oG%(XF< zLm`2hbgxT!N134NZL`at@8f82SIQ3m$bh??1C?9`+Wp{uB|UC(coX48P-4Sg!B9JA zbU@ibQ?!BdlFXUEjLFA{$=CNKi6Dn^wRIr6*bFyAF$}C_c2h%n zKpeIZpI7`cQeo1(+Y+v;F(*^$EW8}6Os#Hmj1l|%s`mt`s_Mb_t6_qq#N+N#{oZqz z2za9_*nRPOH4MtJf?SOfH&Ru)R0^i$G&&)UEwM!Rxu1~X5mQ3!?g;wXBPg)puV6~( zvmbWGO6;~a#(5Kt_^^e7IFr@#4k8La#Oxh_ z+1%VON8GX##r~%Vd$Lxmw)FAwWp?)1@#4TVoew{d4;*T<*@Gdgu7HVtw(L*gLS|yp zo;(WbaoEtLV`gEy=kRR~-f7wl_$e+RVb>8l7hxzq5xw04E@vT=m%P%~$ylA*;K{=IO@CD(sMwAAEyJj8_)=@n@ z@DAx%!Eyy&3s1?UZVVky9gbD&s^F?~7(JQv{E=*l1Tg%bX@m#F79Qn^q;zBM>y zG@Q{QAtBKhh{PKyBK1=hCaun90b^ucI~Y`kE|5*;R4U|&R5>pfmRr9%^2g!I$Dg$U(}Pp2(4r6v4Xk4| zCh&(y@bysLWUG{$)n~(w$?Y8WiW;*{TOsGAJnRcp*;qNh!ELc?)F^DqVidQFOmQGQ9v0ZC|N{b}khLjVAKS1MJq1zf9N14m$ zE)TZcXh#X{a})=NOGybIEi3W6a(1@=I$6{TFuov4N{!$wi`rgq#q3|>#>vPa7{=JB z?4+lX5)S?&=ZvN7iBc;n(r;~mk}l%<3BITzO>OnjnmpPgTyM8I16F`twCJx;T_dy~E;sE!T^4J$UgcI6_B4vTP)8S2Cot0W>?6?>HK+2W+u?5^K>A^g^-k; zU9MxTTMc7~Zf{hhmy&F-r;6{%o!54y$^V{Tovt$C^r_cHwNfXf@#ni1K}P-I@tDbi z_{3n$1h?;1o;Og1u;S;vPt_CYi`yKuyU!t$c8B(*Tz5jH8#AbqRdrI1-eh*;gT-w7 zaqUqqsjZyp@~xN8A=3O>S6%*&w)c6#{D>(6Y7QDCiOhPN*W?jCZ@TX{%SRFrfSuFx zPV(w=d<=#%I!fbo7qzVPah*TVq$_FF>lzMIfqN);X@OD-x&QXwo~_=X(W1L+9c@~n z6hckK8``YQS%d~$bQ;cy)&TRSF`HH{<$i+v5@9mFu(M<$1_ZJxl*nyiFT0pc zElpW|ogFYO`vhbZGJDxn5@6LV$ zd&Hu1s;WLO%uIu13E~redwImFymj$JaKX;AWdtcHsmF}t_j_zae7+oQo#U5BIQ8o( zE>MN|qnH>p9@>2ZA)6KRVcT7?e84_GXbaZT`-yN{Fs=7Kh#QF8*n0{AM zljP$1@(ICYp|nz|Q_N`PJM@Le1Lnoy$|wBxw!GsvB%?E2V3ATMjo61zpVTfdW(Rh+ z`=i>`Z28}xXk6c3YG1T_pH1nq`u|8?tj#nInDOMiyj&`JBY7Nftv!OsM6Vl!uMdi4 z;T)0IVW8Nskih$KedSx@8QV)P|MiwZnU@91ix-ss%Zq(l(a2=h?__{bTi!&`QQ;0O zJ9up(c0s`M*Y@<3BSe!kgr3<=pAAC1@C8+ojg98n-=u@8`ADl%GhcZf{_NNclnULx zp(3R}@ zZWD2*20GcTZEUKZ0^f%h-p_~K^1a{_pYf_+p^c5>-=h|*Q7LzqI^cCC)N`6{0uuFt zM3uhP6LtWR)Y>W6pJ#55cU~Fjz4K|c4pQwJH@5T=^UN*-w1EeiwV8cZ3=Hwl8w|Hz zdy$7#H8nqg`Tafr*ccA8MAl_h_6aFY;16-l2IHwdVpOzzn5wj0#W>}81(;gjw~RR& z??uJT#V(?EW*sp#$&9`U<^~72{XrC5OqVdeq=f$y%HO45qRCdLb33V5|vEc-h>e?HZNYo;PFW#Ivy4TV=kb5pm3M~X%&M@ zTw5MtM9P?inKj#7ZdbwS>E$mx$zwAtAca4N!WCoSo+iSx1Q*uHaEXPMyS(h6XxY$y zkf-d0TF>~p;v<=qMFK*$8-g3(V>0NumL!`p?#2|Qe%e&vy=;N*t)gERzB z6TyD!r9FKhwn`MyZc1!WIgp`mc2}j~Ua&Pgu1f#W^JK*j%M6t3ZB@5Vo3){?m!*U} z^CtA*q{FSilY6heSQmf{=8QXu@Y~VRS(wt!u6a*d)RY2LIE`c0KqTa)CQM9^BQ<;D z;O5T#BP2DX5(jIpa#Iv_e+D3vaXQ`6LLuOVHrO2Bh2VqK*5(d*0|n#;-$oh4BJD7_ zm_oVp<8!_2Bqtr6CU*s2+0_=8@)&fov!&9)2Fp#z;&a2*rRD@}{x5WNGHdkOa;?O6 zR;Onb*4h32e;la1mb<##QHQ&B6U#8`DqwrkTK@9>fUs2rxkF!1$O3xK$URL_dgk(@szz#T6`S8Vl527f1xb+W z=E)i==QBg4S0{$W4=3xJ=(TyH+Kij4;wK=AHbV)ORa?r7bD?Al)<25_+Oj!&8iG*O~8_^e@1)oUqe+W_q0MsL&p?jT-}NHz9X_!c8PUbSkge>H!eOC-dA~NO)mE1T5bFGc?CCQG z?tr!{KP;7`3-ziSrxg37gMq`=bz1g?uv)2$n@bwHaaFTd1)lu2IL2lv$)6`2K_#r_+Q_i-aQ^ybda7qgMjY*qf3Iw8&y zYG`QaMRhG2D^{gqE$MYjf zZAd5UNc58PGCpCO8e7<>Yps>tXs26CC(G?(Yx@heg>9!G=D)SE+4Eq0YMJ)<3Sl@Q zO8QcZ@J9!&^+@^rhl;SEkY0?=Se2MwJ12(~2EZeYPAL}$lHjY|)6PTb0|9c<#fs0A zeASQnH`<@{qVN-r;aqT{x^#zYGJbglCgeM+@xcw)l9J$2b}VV{)~c=&e*ZO`ndz@7 zrrM~HZKNmU2iL&-vDGPIHw6uok?0Suq)yLO9j=w*a(TEZH~d5uKt--ws&yk|frNBF z8j|-YQd#s~Ac!}^RY)WYTNF{B}q!%^3Cm$^Sa#OnOLAtM6|o8#kDq1;GM zgXpRgP@(6SaKku||FmpcSYOH*OU6?_N89-^2$Eq0TPTOldzUrsbz4q4jZv4LmTqT% zcgW}2WP#xEG1QuB3Pc;b1V?55q5H--+K&!YqR?Xl(ZdeN%$U-8FD!NM8by*SkI;VA zH-zDu1srmm7%Hqu%IRAXiw)z08g(ohgYp65Ezmo5Z7=g&HGcNMnq79uB+@^yf4SCs4~c|7%~TeN5tlx-H83D1 zoEfQX;kQsD`>0yG{{mP0#@Q%{+B4kCs+ace=YAOEaTQZFWfZteVF?>{$}sBHL7Q~5 z5r{ekYG>fnu2uErYe^A%{TQ5c{;SIo>ND$~PO+j*bgP(TdkpUR_JCr6Kt@AZj&Zd| zkut&cN8GBc%o@vY%NcE^TohO# zF>9)fw(rp^t@fgPd2JK9n7Vb_I9RYMMR4A5No7_{d9D{>dzHttEbznkDOIldMq9Rv zIR%C#n`ufZ3|_bupfYRsv^g@|Y2g9GEzy=Ycs%)I2jznTIwo8%tEK$KjvYT?a5@5} zNcFl9jrezh_1W-%asc^4iy3L@iZf2}2`^iD#1t_cXt=6}aCo_5UypgN_L#xEI?;Oq>EzOD?556-nM1wsn!g*o zN%gc=j7Appa#TuHhjp`x#Gj!%HhazjjPj3F3XT&i*c5gPS}VWo(K4mT67YtSLf;MD z^SU0ek0!kdFU?+&l!`8}47moZYww)}4nUHIl_;~EilRLsCu@YfI{NaFrhw!+8p#L$R);#Z>&(bz;Yxq#S zjoAq=BdiDw=7{eTD*ObD-?2IUR;@H?A!&}+;o zp5|l5N)dI#KfZ5fyF2JWxE`#FarwIKKG$V@M@ocHd89RY6KLwZif&@X z;`gRli{+0{&P(Htv@sFr8EZ7QeC}}CGm7-zC*u!!n|9-+)qck7?ztEZoOYA&T>FiZ z5co%$=u;>?-PPnG!7~0LPF5g?`P?U8`81lPg6kmTVB>(~z<>|nku)9))#U3r!?CQg zV;6$(1~oYCK8Jf9pw3K0q=*GVAqW$`ubB*lu^pYYPBq6hu4Mi|LEN;o2I<)fGm35l zH!fb6V|ac&{4ci%DZxun0aPG8u4`o=a94S53OF%PBNO5vf+@%3B+#m9wi`ZhCKFNu zzcif|@vG)B8;e)@DSNFQx&<13AQXCEf37m2##s4H{o;I*n$^pey#9^lIvLY}(GWp5 zl^J?sRL@`Lc^d&9Fm0;b?&7vvRy=%y{7^91#w0IBb;-y^mkBhpYyonC!LiW_=(`X$ zXn++=uv`#Rp7l{b)?!6}+mIhEM`LlmwcN6%c41u8HEA;EV45%-D9K;muQEq)O`C^< zm0VBgXw>@pCqLCJ%iA$NS!zV$_3_HmS{Sa?XQ2lrmd)v0=uu6ejz3kKf(cAL-=KpT z08EFSbyQzovB5tzt3MKKw!vbpA2SAgC0$e2493hmGm;O&f@Ou^F8cSrb&;*>$z@-S z#=h@=^N;kXHdk!qq9=2Nf`zom*HMR_F!JZM0bM?$l0vkDFSC^v5w=R6^G-mp9 zyAH)(!CP^IxAlCbuGuv3&_Cc6{;41?wi4GZFUv-W_}n`Rx8cI88NDl3fNGp;Z3K3! zZdyJXf4l+`wcd4W8qTAu2kdbFzB*-=0^NW`y2|oLs$q7#b=6WY~c$aRyv$P4YL+R(n^Wc~| z0(nZ_Q6IWrP@FBjxqX-*py1Fs- zV&GUKT7*OH&x_?JLU0oQoNOHi<7{UTkkJd}^3zCp8xe7)6h|n{4tIddABr4!Ec${6 zN`Uq^qln+qCyUhxo$u-@wI*}8nu|j@T~RJAE;)QpNSJK;c$d5DXNYc2$yRf*Uv~p3 zu1RE1_`iccPmuK0bBo>`1`@ojnHTc+9-Ho%ZoZs{*b^%}mrW9bz4GWxS;X*jaj*9B zvS>7+c%e{&YE%AFU-#dpZ@JvW^fDXFiz?W$R`1E*;9b)tf~2ZyVl0-xR2eSJXU ztffFsZtmv(eqk9hE1}Hos!3KzQF06FzumO|ibXnztDpqrpJ7S-Kbyq=f4G)TGb5x{ z!Kh~l2wST$7B};%b88T8Ri(Bl-{KQ`Yf1@O%=3PUjSqo-;_4Y#m0Zivl8?L)T8RCr zL{^Ea@S6X>d#Q&}6t1^H=AdOI$oXjuH8aB~)_+6WaXHaD+$Aw%b zkO5IoZT_f#WP~8&%P)V9sG1;SODlM1_7D#TWJ88MVv!|jnNlAbDKxZ15DK-jiE(v)W+dq0ZTwam-H53}w z>B`|ontDE?BPu|~H{-#)iq#tKs>(s=V*^cU@nKUj9ivSVTT$_I2Rqx}rlqXK8tK+IsjA3+%^Dg$*8R4Kr#(y;WJBZieeFC* zLwC43DhKV8S}$+DD;1%dQ@FvVdDJiB(<;ZjD92G7B090(18~ja@@xt-k`r{@x7Ick zz=sYuE1iLJkVN}uD1e*)_zE1fSAW}9dGRQx*Fc<4Le2^<UoED-+!aO*;^u?{x8mK6KTa8_~cttR2ErX~ID>#^&!x>k_ zkWXFtbyjNFin=H3+CwI%B%HixD4NBcfp-!q@rH=C+>b}K?-ctbQ?J#xqkOWf1dZww zdliGk(w89_CLsoX+$IgM!{S4Z_z&>d^BC`VMWO@UB+hW=fqsZiU3t1}zlv#Jh|{;1 zhahXu9eV1(iWz*;J}<7J^jUB=C6%_D_WAxcaFw^>VXZ=^xT_JvEEPPF`|@2)&aI7c z7$10R7v!*NGu1(cB&H-;SNPmyaJf2;wV)A{#_wb=Vy*Ps=xDY4a#V-jy$E=hCOiGy zY+ny%(ij9QK$`!C=+@WclW*j?nA@uJX}s^4P^f>H=1Z5!A@}*N^(R~@=0`6--d31m zMJsp`sc2Ay2|bXFOG|@yb8`b7Z+J8>IX|=EZhwkFq#h)9oW81BmB-H*J?0>R<^nYv zX{t#Ne9S1P-8?+}ZbF*QD8HPRp#-0l+EbfOY8t6RGq4KJtUg>_p@>F3^_dd-Fr!@g zV5*X}zrGfNrSA(Zwg2F${po3#$vsE+`V<=HA!JjE(#L`MI~e@^Fb9*>spCeD`2sAe z$NZ|gn(uz+^XhC}a1kMkJw0_WhkX=P^^M(=#5RmQN}Q|19|^WzR59#-urKQOx7#}E z(X!z57JwRXOoIGKmH49u!?F- z$SLvya$K>F45!XF<7$1wj~+kV0aA03<1m%eZH%RY-+CY_GR~4%6)lZ^8}^Z|C9Th) z{QLrHc~ussURa}0f3aXYT{3wt zXx);HfJVd&{l1hK#^FJZS)II0tQCFtG!t+*L?__yUe6?kskU18fFn#WH+SI>A5s(M z)tg4`Cp#!Drd-l+r;vCy%vOSleDb)R!d67FcqE4{2FhnaV^%!!={7luI0RwGVt#*B z%L!Gf6plUK8h6uBl23MEf4C<(G9fpfwYsjvcQK;WV(d0x*!bsgPm#U>lpOM4m{gBg z>yHcH1XujlJ_i%&jrnCna4zxkde{opua1Un4QCR+a4AbE`OvLTG>pq6Q-sJXR9 zGgk;`hErJa`f{t{pK^I~49N3{nJQo)bJTBnbsxU;qB47G9h>lKbWbUIQUQcQK0Liz zGMGJv-rE@E!hKfofj_m@Q~fQ8M*Obx^!D$0Bvv+1tbrak8<}y_lb9jWtvo!iL$#S8 zOy+Q^fB8S${Z&w0QUCXeCIkzb#$AJ3fZ%R{;O?%$o#5_HaCdii2=4Cg?gZD_B+vhO zr_OnAPMxW#sp%`O8rZvg?X|x0`30Org)H0=vf~CNiuwnGUSx^5!e=S(XCl4o3@=S3 z9j?2Y;Rc7hKnKq_1(Q`n)oS`Afo$&Yr)G~9g@#w+lnFWVN$Yk+35rBri%|{^AVfsy zVvNpB9R23owvaTJY(EIg25V>5ebe?N>%_b576hGKe4R05#{8uf=vxD(j@s2#ph*ek z)D}`C{rze7(Vn}d`HI|h<-<3?Y~c4`f~)yWWEg}$0c@oWiUd2YC!-lt%r43{NL~XzIzDTZltqAC_?+R{JMWID54L-pt2*^cdJ=ouuAem$Msetu8RNf-4NtY z1>+*J&A~hWdxBzDpjl@JL7~Ft|(=<-QJ->Yr_#>*)uxMe3-lDuwOXxJdAW*R;g3h0D;1 zqL1mzE6Dr{T>}j_w1ZGa0K|GxZ;d47yyzoL73?P}uBBR|Kij_}^!k{U3G=dUr90-9 zJ~EOze&1tLf+>+PU!F!Aq3qWSEE+;7aitJZ9qg=&U_OEmm?qe{GHm&yPW~+drK{ze z-X&ndjk|%OyWQr;3dl&g6e@z?A{KqK^2;cw+qVRuy1 zEG8OPP-MyGjZcWU#v4bpy{ryGawW-kn;~>9k87Vif0OK3J}1{#3}npLy`?NnFTNoX zLI&zb+@w@}+{kD_F@yBRdTRo^LS`_@a_%%cD*Y16Vr=4^b5uP3u^N_k`&4(wjy=B> z23MITolGk@NMOl2V_*DA_(H4F|1Hv0>=4d3Pl*(WBSnQL?a~(kgS6J8I>zbK-4Sc1 znD+f`L1MivT9cq?1sE|7DsTk5zGE+hb4!C@?-EYH%7Gt}S{W4xy{x!NHl25`{RF{0 zi^0|X!IFF3Yn{X{g|DbCMc*|uX%28TffmS z9|5#3WBrqiZ#H`}yXaqX;aP+5CZEB^yKboKXp+1)=uT!}hqt$$Mn~pR@chZVzikE0 zps%yna7?Sn%vYKqc*o%=hDT#O;xXLnmR-SV#gxrB9P(T|P1iM4s5A+8W9kP!8(5!H zAE)8_f^28kePelm>J@)}40Ov)KlyMN_3O_cFO8}5H3u%P*SlZEHLIW!aXB|kOe07o zKK*T?W*PRpl?V;OZCWu)#7z=Lit^lMipJPt8y2+#v+M3`WF)!6)y)l=^rvSr_AL;c z@XEZwZ~{#Wyla`pn~fyKhTo1Xx@fd9M8t(Qd?rmAf6qXNA}D%km|mk}!rFUNvDG?) z@3$wE9cHn|UQxVMbboHD9822wtf$eA!$XHU8GY?74-#Gz0yH0#6LFWOBO+Ef^flB( zK6b2>HGGJxkGw`JA|1ofoXB7BIppOk=noCx6q%KBu5uj_+7j&{qxS@LJBt{VDQHu% zgNzZ;2MT-nEs9Mud!Qrn->nD5UV9ox%6%mG*pFafyAo zMndurRPrXkPs0cw=!)M2_r4ft+<`_3z`DoN?abM$qQui%@5|ET<|{ zj3FU%4+;je^i8&?1X?WCnn$P5(?EQ(&FyJt4!KWqu$)OQ^N)1vyP%94;da_d(^JBf zFIhL$&Q~a$d60GHVUdhBUtNeQvKwglNg?I;%I!ZVmu0gOetavn*6Ud=+ z=u~`onb!oNC~ncGITVk=GYPjDd{07AD_db{ZZ$yi>tv74s2`Uz$3^kt&SFcaP>Rp- zke;NUIKfG;^X_!=`evOsm%9$u4Ppv&`(OE+_-p!`w?`1mV!_kfYGQA3X zV0m$0q*zR!FFG!c%|&u;^!)Sj60%fv%?GB8mgsl1C)ES-WZCzlNwMbHra>iiYt@we z;J%2V>%&_S^BGNgGb+@99Y0rnw}(4yxF7!>gbHugY%CRbF+6_;GJ6QW>@OfLO0fQ- zR6$!tgQtcP&h?16bzG!-^O+ zjv0G=aExv8#qghv{;#mVuL>8b$+ry$RlYA;r^MDE@{06-zB0`&`M2wu0RdWyJn5f4 zXftG3K0XX;S&`t|&F3ANaYujMt=*jj?mCXe#>IF<7KYAP37z>EXmHxq@Gv@wj&)jE zD}^DU%)`93&z!pu$C_0r9P1H}KJdeJB*!XY27OFF(3|kq=n#7n(#$swbD9c6F|yYL zmO#*$1Xa!mIt$NTpieC*P+a-zT_?pC2}rCyVOR*8_XZA~-93O{K3Q~9nYQ>Jn#y4? zpqo!NVT2o@35mi2CT=Cc$*|-Fx)tBBok6jGQ=LdqGT9R2^_FE~_Ty8IMJ}J?N`+UzxF7*G4*@JxJg0YIdaTr5?jcfWj~WF16d`2Yy{!Y9rXQwv;HAXCMk*P4qg?S<&13JF?ymCLUZ99mPPFW8xTv2+|reao$yA?(6Qt8|6f%3(9%+ zgCF+0kjLDey_#goI}HsCsZ^{SLRPpEIbY^f>z zGcPUvsVAXFT&-!CTxfymNO?Qy?dgWa+cxbEMlE=*U)PdLDZrP8Q&<|gm@S)3Qmd7l zC#ApRO29-9E~ekzLd#@*OeKrlk(9JQ$ht^b{s0HzbU29)szK^|5;MWhA!Uda%~4#q zm3`o7GCf4>{ zgA&nqt^)ZPbUuH1fb|hwygFG|?EEIZl5kYsB#4ydUAepOW2j>_*P@fcf%8XsjuL1d z#D@SnKaUAtqH7KIl$Efx*#{HTomVzLoQ!9Zb&**GbJ|6fGj4_+6&cI$K9YSDF^S({ zT2HWXZ*fpSqp7`+U7}`^(c`NDTwF>fT)qGPb%23dUXCbaBmtiGasR_>R5m@o$@}L= z?W;i)@KMCR-oz%Nxwi$(PHo&^E|9;kw?A$XsW3=8wBIq2u-0!9@u-pa;OFEeTj2rn z0w8|M=~@BbTX1%ociLxH$7uSypioKg z(w{vYuW3d9Gok5=);s+sp6TJ;w`Y4(>t~Acth*}is8k|PhzI+dPw}-Cf!zYmFTw;2q)cOh2EL|nqKTzD=PZ$-xn#!l}-B|gOORp!l$`` z*F5`}_-z?m3Sl6ml#Q7iEaT@eI|y|^-HW{s61)j^ClHx#qKH(rpPK+NVMDA`6eL|m zEjs_+6f3-j5bd@q6wV>_rsmgpoYZidVfp6lK{RjA-%N?P#7LWW8yQu6m^5vjymq=S-O3QFHcu&yae=LwJ4mmB7achxg zRVt2*3TbE54j2%0(X!ygMlXZ>!+ScD!yHp3>>N6x?C<)!fg5VNie+xHM+CJ=hRpG& zYVx03fy^#kW9(Sa|9Zn1XuD;26wOG@utazhaBUsJR*R`J=HRj1n*fJOFi;?9fjJAh zYFyea@m)-gXgNq0xi%22yB7=Y{jlK4fMsnlBvX%VmdV@aUOR5%Y2O*<)*bvR($o1C{0FlAPzBhS3W zR{p-4s#~Fy1K$lgWmq*$cVF%5#ucL&KNe2{wK9=Pc^9*Rxj}1LDo|grr*NUG;Bycb zbNcr=^ja^;{cD5Fnp1Kn(ASHoBuRlQA@B%06;6%Z-CT{5s0PbGyK=Wlu0Bx-@BsIi zB)eCJu=|vPZ=|Euh!hdZ@}jc+3eiO}Q*9yO{sw zzv1Wq@YGI1w6p4|omhWko~Rba)CNDAAS0)T;7b~jo7!*f7$8catn;RPTaZn}Rveb@ zswP0hX8Ek$Ts89r^~sG|$4B>b_b!p-g0rddqwf{9U@m!b!Gg)!AQD7RuE;RCeBIZw z=?eG3zof5;RAP2^EO&SJK`fa+6K~EKgYzKJM&8rb%cI5|n0a4K>Y~?mHR@;^%3&B` z9B_`AdNHB@6TFeKZ#v{dUU*Cy%Oq-tiGiGeO>M^~e3v`y3E?@(GG)%(=&QCxown)x zdqlf$cXpN~7zgj@b}&?M%f8pgB`<;@LN%;k5SH!FE~+kw{`;y-*M!1csedn~&CYYc zZ0s5Q1!`HY&~2geulv;$Th1qMhIZ4pyDn=%VWze~eC19zT=eN>D zmnPjCk)Ps6#+hb?{`uIu5mufNxRGhUd{&GYD_?c-kb=cG4z_~heQ;wx99c;;?M&K+ zSaGQ(4=`p%Ap8778U3u#a$kV}68q;JhqZ%oNvNpb+sVrE2g>V34Gq!WcFPmfueUra zc%fKL3VafeMFzucfN8cF#4AidMuL0f@x8}O+yI^W3vB~#o^t|NBb)N$J=1Yq{hYzR z;uaSAG0iO<8#99KPX!)3qy7YhgcE~sumi5PIuZp-=tOu@gleHte2PGMe``z^i6$=A zr9?ele6j-t?1UwUOUM_I;plkm4*?c$hq8&(0>Xgy?cLqY!o+H;^Kl)gmBB&aghzXR zX%Zp)g65qe^RsJtS$$OrooJl6?9pRvq^FwEh+M5Wn9UZgoYon)T{!)lbtUunEHQNa zmYYj3I2a7_=clrBuCL{kRFQG$%c-7?Q2_9~Z`0 zuGZU4HTvCb8cXXwpgJpRir=GWw0Z(NNlYe2)M?w`_#v|0X$_up;Xz?LUTLL$FdI`{ z2;6m(t-&Fmev;s(9}kYh=CJCV>bo4wyP7S;g?<=REI6UJFF^KhQv3aly;fQuNhn`? z<{(%`TnSOw_v)u-do^44*j;CeD-Kt5aBaRq0vffsWv+KJs&u59XN;@$xA!+5(SfD9 zG7+?na*>X>Q*|rSb&7e+n@N=5@U|WM;gjuw!#OWMV5|>BA-UJ`U(>t@yB0U!|0KAP z$FgB>Ca9=|pbq|1c|8SgX0JfptrhmZEY3 zttg$e!*?WF&E7%eMT0p>TIdsEH-sC*Nfp2#P4hW{iXQYW5YGA*t^(Q5$%rEMFQntd-keiuuA-xx9|4NZ{>%`f zwRL>ui$^*U;RfX@qD%ev541A*?tQhULHmHdk(So9_BtJDQH;eUp(6r?y3HqM>@;sd zP9EumD=aIT1A**VLyN!qxw@veo6zJ=6_uEz7}_rm?fk;JXLG>fTmb>p0W+o;CtK|q zT?JtxOr5eHZhb z&VIPD1*M&Jt#5Yjjk4ImYT3==u3-k+c+^*O!|>c1TZ^$n6Z{zm3G88Lhm=kdt&#&|)*jN8qVWe|8Ci$oZpO!>(lI z9P4bmk6oy^S)wFR7rU^^^88qBDbOkM7L5)}a=AJu#UD$$ZB-p2h@WsJqM~WJ#!`@2 z>*|E}S*1cvLz_hEGmjR8=AADg1FYY^Lm(z%=2>PSaDvlu8`eVwtJPT^#j`muZp`X( zgUHGAD#S)GJbc^N85BhMye#mQHz#-x23r=WYM%RwePJp=D@# zrF}gRJ|=4?(d&^?qWW4Xaa#x>hbz*KJewb2sT$uGH3- zvt(9I)I`5+q~BGsT>KAI0rEOth1n?^rVyXCM0zLb%CtM;h8%Cut;;A}U7GpAQ;Rgt z%iU+KzM|fWbhexiCDb1v+B1k%-LyRgQ!Ro;@jI~?;bWyLq*j&=Nz z7z|1UeB0qv%56tjXl7#Z5!E%6LNRu$m)VoSmnmjqFqIx!V7nGkY57+vii1$9dYc*u zgAi)m0v&0RL`-inb0BCALGOFCU}V_8KqDN1+joIX7R#jyV5780ZU2079K#TIJSTK* zyMW!^8|wNJ8b|V+h743)sNg25Dl7S3-Q9M$_lr-`hy;FYP=#2r@4~q+R?2bjTFT*d zxtx{%stC*^`h>vIls$Mo~H?uH}aS?6)j(F2n zhp79;21Z_Fr#4+JE?ksJPAYY6oQ`ye>ykSa*|jrTnZaVC6C=o-3JFm*e|MNB+#2Jo zvZe&hQy<(XsQsP;A_c;OEahGnB1)iNW5$f%22;q#A#JEfCNgDZrJS967P%N|x%j;o zb$7N>w-1hczTRYEI6$cML`I|Jn#MtyOpD@+Mn=pvwR#X>X zF%U!30ph-!TebMQcNNX+6M66mIP9U=2ZM;L0|!$^pYYQO&VJgJBoPpvHt%1vXdC2q z?qPHH9wNR_)ocBH39OH!@d~T8_u)n~VXc=)>d+F+>6>V3YGV4$tHyZGMArPUp}}sj zz%yg;zEE6R<5Wh+;XTr14Me2*NNq=Mr!J`U#}B_iw%E|QwuaDKJ=kqCoci$5grXJW zg#5y~H4>8kLWZv;7>zc^!p@cket|`VhsY9E@upYvyL(&vg(xkrwqQ5$ueRl=$>HSm z)5C*Ugoq79{eADJNSl7IebYbN)(%19n&cvrcM{JPk%~_PWNBdj69L@IdcCN3OqobwUZo2a`8Ug{oXJ;V;5b&ewF}qe*@$gGE z{a(vl(Q#W^-uk6qOomy-VVnf=sGn|LEW2gWs$Bc!krD zMlHk?)-XLm+~YmkqsA)rBo{ zn?6VFNQ$weUWxHk5N5Pm*G;=gl#dJ`R;uMAhb4pZ4Y%w0flhF50?B+VMlpm0tPGvQ z;vdFjP1K@eDK6BQA)WrN$EtX-q7ZU&aw$9>d#4GO8 zKb?b>k_9-~d`gV-!Aenu#Fho8NwV!b;&`@p2Qu_TDD!_2^v&;N6sp`PC*f-;si}+D zbBe*xeXpcD7#Ly8-E8pWW<||cgoeXJD9RB(2eo8HJ(?exL=-YX6sdmspQ{wd6APCR zj?13W(177|?_{IhH7%b^ldWfD8uCaM+UNQ597AJI48~2=|7WN7b)YM)s@k?e(Yz?No5mFaV74DXio0^6x}r7Qvpb$9c#hy;c5iK=WqbxmR+N?df;q)lFM zX;glhmqCC*%`wswuI0l^7fE28csb9L%k)}+C`qT=1n9q z-QT}SAbHr{^2J1E*Y2{T8mcWYEdrBctmGX9-sm8Rn~J0qV3g1yY$I_{bmVnE+mU$qF({P3QQ#IV=W+oh7q)X5EuwW|e=eYmN2JlzPHwpT>DJELx;K*V{pEQn&&!=0 zUfs_AJ^_?2Tq@NA;VIQAU6lvi1nyMAn9pI~KJVB>yUpJS>0LMW#LZJw(0mTNWIkGa zs8f3mF=;VMoP*-qPI=)2?)usw3WSQ&eB&!tTsp(2hJo4jqDH1~fTV-J`A&-ic{|5I zXR9oyieeBxXyGR&mDCPlV>eD4mj?Z-mqP+i_s0)H6K#1)$=NJ z6a%Eq;fTv2*MoCK8H#rrHzL1uI= zGIsD5U{G+jWZtYk|DBBJDB@NZ9r8tuRZ&a7nWTS|F75+oe%bby{=d@M^l;F-z9PiA zb^U1yIGk~<(LfNGFq{v7(yg-yiHs z$<-ue>YatQ4;{mc;r&@nrrLvTF0Fx}dIu~Wor`0zEIR}Q>nA0)4+HR2h6NickpW@Y zNYd82Y_NCEY8`xS8uUoIw(y8XvTAx6&1{0J;ug+mSw$$X6V2fr-1~AJYkf$IEty!S zDnm>|tF~`(WyKWk6^t@Ghx5uV$5HB6+E{YSl792poH>5*eJ8W5;?VcNt0v9s+fW*vV% zGnZ_Ae~Ef`d+K+q*hY;0br$#am}gh_tZnVf&c>%Fy_@RGFC_HM(_`(&o!;@gLvpbp z;sn+!uPy+gIh9R-TPdBq?rD11XvYN(mjPoc9Xi(N4rxx~Wz=K)(e>`d1%v*n46@ls zQ4x(lJ&9uMl7!mh2wvR%{JoP(!aof`p~(^hNLv(HtwnhepHIU6(Ka*;w#T=OOq0P; zEO(Yd0LPqSnKbD?vyiY@cEsS+*1%UTxbg=1r0^OW{rRjdrP^uJ#JIf;d z4^eX^DCw}z##}ISJ5>Bc%Q1vH?l2f_4nVVtN{#V;H~vUHJhHLBPyW2k{PftEd8(q+ z^q2&YLTlXwTeAi&6xNcEA)T=Tj{wP5T80fQzHk?^6sEP(z``1V>pC;|fUB)u!P04D*E<+>?b0^wxL98$XbR;{ z`|sk~9bv>yFj|%bROQIII7qrCL2BVNmX&;DO3AM4tKl^QZ%P#Sj`V8>c*0JleHP3k z$JR%~V3>y|)F|CBEHpz3h5^|!!2@O7vF7LCtA&APy|BTDTIhpDp@y_l_!f!%Enkb$(j9|; zrcqX&zI=x8?T0$rUyNa#eSM&pQgKgyc%q-`9hYtc%FR?DOS7iHoj!)jKgyJKQ~{l1 z@W@L^A4vRIZOGsMAwsG&Q9@Gurrs+Tl_)|EX2zv{UQP(ld&q?@_d*8+%|$(iWqg)evASHSO$^4~B1hM-Z&;KxiY z7n}m4SLRuOJTPyinq8uzofN@jmYaK3d@!$ErvZu&4U4aRK3d;_({d{G`u_Uc@{a98 zcQ)Tlx{roLA zJ`js5kCgQ8;RhD?6VrF+)^L3Hb}udu{Xz4`LhQRkE6Prya-HOwV{LPPmnKXVLbkGZ z6eN?yeyCtRS75{ntQlfd7plHu=nRyz8#02p1Hx6x74_ZHPGZFUE#bsA0q+riqTi#s zrzxWyd-Ecqn!&g)VXAE|p4s$XH)=YqJgifZ)Y($KvSUwCmwGkZ@>Hw| zZ_-BjENnocC1M~q){kd6EnfYMnDc3dK{}~4xkd(%kI1qf(bX4n@)S)2&s2QF6CsW- z`PlPVsbR|2Bg?Y$=-Zn^8gu6h18{=9Ia|M?x%}A^yG9n_lE-!jZ%-$CKDHj`8YLzN zlya2o-V+|Uw;K_+hp8@Fz_195Jz2A3Q;>IF=pwVO^>-$ne7{pYl*_4EDM|g%w2;^} z(FDCTCT2PO25gN_E4FJ51AUzTluB{U2$h&8#A-*59W=@Hp$`}VY09|$dG&WQ2Y|z- zI7kQ~*`Mu!#LYePd%lP3O7Fv^EYARspMqI`>q{M^N0*tGL?x&MVzUVig5dSsV~Gy_ zJ~e2xY-|_+=6q~zvK%lk1@-I+YRwJb>rE~?Yrmy+zQ2A0<%A+&`4Rd+eJ{WLJu-s| z93StvH=&$<%n3x}`KG3(+QjC~HPvzex+SG4pel7N@Vxwv&h+SO)%!NI)a_DHXVK7Z z*Ot2KVLKDKwvsg6s2vJ@8JH1nsfG=AUKj1d!^LU7PV&57Up))yaY$)0W-$Cnf-7@C z;@QZ?ZfDnd9KfMtPyy?|kK|(~&=M>fDLaN)j+GMhvF2ie)9jT7VyXPlzwZ0yWt1#I zYm(~k>UsycFr>-K4c?xGmaJdFfFe8{r*Qb5gzU4P+`=6@@#w*pp1i87P$9M`i%`DBR ztCuD_r8*hRsD(d$wU@uMN?+`3{$5c#wZJegIw&VsS9ZPAl!c0_$uN`g!?kj{7LHl& zXvyPy*n~gJoZzdBkjQwh(CL;>{CEg?#9*SE2_%*+LG)Xs{e2^jhH)(tS^$h+`EHQt z4H}>Ba2!*9T~86Q0n8>C1YO$_Ydo~xAM7POoljSBTfA=MQ`!eowns$FSr*vuFXDT= z1OWpqI$pV#0=>cR=SWs`zdb*+{8GHN3mcj{x_O_kF4A);flg0GgxZV@DRkn`1T_pjJKOj%eL}?qHQ$KEUrCCEI%WAiJ{RF= z{GztG1X1>9axapEu3G8}eJ{diHN6Ys)%lEO!#UAZQ4s-sbr6g=&6g`YI#-m&2J(0NA$@LfC8qvkV5eU2iK@P6KUJ5-38rURFgeD zxmur(gM2v|P=NtA{e93uK|yz$#S(Y_)#mj_l~t7BcxU{eu^?8kLw8=?(P>Ln0S1;= z|L|}(&n|a>eY%-+xcBty4{@jCvp2F9=_(JN2K&$6!CS?R^w$TT?On{Wj^s!yRNI{A z07QJgjH^`|nxi}71S~%pue7(FPv8DkRTD82s3)PFH6@q_DU7;T{rljIUC9bsfKzkT zwn|M#oq&kv6_y%w)cFTF#s+&-VXO?r4uuy@RKguPC$Ve{BRU3k&lGi%gqoQz^S|aO2Mx)38~8$%4byGJ$>I1l=@{kp_E=IUNQYU`PJzO0_;%es;p8s#ouk-|f# zayWI3jw&Lc?QF|GQN1(^hXd?P7i~ku_Dk}IZl>#P^y8_ z(l+ve{P0{bJ)8o2k|Zsp07_nkPv`xr>I*_RE|1rorb-~U+qN~UUGkSEE0HsYI%v%O z&_4f$3@s=%I|sSUFdqm`9GZiU2?!`9r`0b zE8(#z2ExZ*?l?2l;e{tCI62eOv55acdY>t)9y~P@Z~TK9n2ZhL-ehiUygNx@{=H$G z?G_3lbPs9tfhwObyhFxn@SMEx%#Y$4Ht7zr1ZDeIn%`4|weiPE)8iNjSFWo(E2)1S zG}5Sl9kc^op}!rp8DGA?QL?Pvo>fgXX;!w}T`ij#Hjfu?ocVj}K7_`)@G`fn0Z0@y zl)*XFYbW0jk7qw6O|{SsVxRS?6{#|>=qMdlflT4sQ-wo_6*w6qVK{tj9&4nxQDbQ@ z&%mOjV^AIkt#}UzR28pfom_gST`X%BQSLX2G<<}s5g3=X2gxHg6()da>uew(vqeui z9<3&=nK3XrC{EkEoEv8EM;c78mJqK+t0X6JC<38~u_6P(;-couxgHkVaSDB496|VE zq5Kp`^(3TD$O6?YN!1a7{Qd5ssP5hQIQ^EF|`}V5cN0WgE_nU79IL zSH~zsg?NRENh!40x{i&}5n&vULuq==sq;g&Mh=~o7bFK_9+B+5(WRZg!*Z^gsgd|q zmA@qmpq(!d@`j~xs*fPQMkZ(Z)Kh`Ao_winCw9#}p}6GXK|B9w<=q~@1O`>p8|*$a zw{QK&H~qVoe`-&mr+0Pmu{=s|f$Z%B`HW;Ng|Cc`ShRFr)3oRvBMYKrCG}5%&wY(E zYKmHIrx>i3&@10h!p#8uA#VkKSAK7Gv&E4SRHN5BWbF34qE7dwYasOH>P~=~e4$l+ z?U;nl>TG0w;U?Xz2-IakNOc`MP(O-K5ikJeQi&1e{5CmaaqqGg)0} z{c3OSFKY*e_C$K!{2M%tdo%%i839(9jab@wA0jXBJht4E!TN1{zvELux zU^luBB$T;vxVf~-4?_07==~+6u=qBaOj8q&`nCDN+N% zs^QFCxmk;HjV&$58->_qv1xt1 zKpzcBhLnF5bRwNXax#43!MyKuYnqRb@dc&y<10A3feh`R235q$&PhQ~lkIKv!4z_vm`zpuzCs<^145 z9^(J_n*~nDe7K-x5Tjhs;#Vo2N5m9XYgxS0tJO#R^~?bLo+_63Ep@XJn{Pq@)ru0) z3+a8jP&u8DtWA}=vPww^!9duR9c#hN{&FEQQuMF$KXmPbk3yg=zjE5Lx^Geflc=Jr zFI`e1-@nHOXtolz<`WA?3@ky=`@})di^C*(1M?Dh-X%D4Su=>zE-%kkx9kQ1hcM2s z5&-;;j-Qk#aK+_z!}LRSz(lD`KJS=04I{4QlOyWcnP}$&PsqkVC;dN(P#%^(R8)Ua z+~r9Iht&}}8b2*qhgf){y_nlqOG?Yvqwc*%vz<(MS$}Wuw=_wOlt;ivp}#BRy}QQr zT(C_OkhGw^wE2@ETXG${s z2HT+~+dc||(=QuvZ6l)qU=$fl5?Gjeg$hatS~<~>uz25Un;XYYf3P6rcy#8}_Hi1b zl83KYd^gItUGa?Zz9K~JNqH79Qpd{?J2jQ0Q%qnlbnLa>+kR|hfY+z zA78Qb^-UP<1baiE!48mB7&aGsNP2AIBB0+f={|5@$|Nn^We?{;jjUr$%qnAM|l39A8Japy+&3yiUnehMb|D+Z(b+*PwMmFF} z$8^3cn8>dsNhuZ2WT4||YbXFuYT;Lx9PDZP<0PU~r=-81Bq)#nzZrAKl(m};*c`n^ zSM$omcR)t=Nc-(@wpJ)#a(7^&vgAk!+isNfJKG024dc|ejd{>%Br-mp%ij^mxU0Uc z-Ec@6%F``pO?)afSs(9!*i!xR7S;ePW?dyur0OK?Wd z1z+477#EG!eitD-4Kk-DF*yGd>S?^T=fQ_p6b_a_C!ke@#l%EEHZ4+s61A*7eUpH; zAIi&Ot9;1ipHf3@wixZ(55rRPJF>$9`oIL9rBKY^zfOR{ar)$KN^zkhWv5k{oWjl+ zP?oAd@k`=YZ;cC*=$is?E5`-IN{AeH^I(|Y7p|N9p|8ZRzr=FqvmV$|%Ga$f0EmMG z=4l1Z)xR}FgP#E=Y5fj3)3-FjL)XBIokF%mPjJh3&YG_ z`O;L&7Fo_Wy&!%ZKJrc6`Quvz-Y$i#mqIw0V65ShlYVIo%VL*Aq#-Hnxl)DIruH3M z9@_b}ZC{nP@DGnm7GI)n(YZCcYcl3m=!#0;hzM9TNs|C$%|Sx@uNCFkz_z8UJA4qb z$@o8}fb;*iDeyE-)3JyZ?Y(^A=m7ELm^HdD^%Ccus8N?<1vd8lgUm;~e(~e5#dtb_ zf|P5iK2j0WZWZ>6e@1yuq>Qm%l-!!2LLeYD`wQs48`9a>ZO7m9#X6AJOrCxIv!P*)SSh zX5-}{SOOeNVj~DE>NFd=n%>=a;(`Kxb>zP{iXjFU*qPv0ssOnZy8#uQfKLx{PciOC zd{Vdo=HMv;Lc+E#yc=^rYp&yoAy9*>%7>N0+Dp6N z-419K)D-;FFXB&`W@t#|I|P)C$|}{rYns)^S0F{CM7mrauOA5q`uT#ZuQ*eN*MFFY z^GF(*23S$J(G3sw-0ofO2$<$`B3A#CZLtihuU@i|#3zc2nNnzIG8A(+;;9xj%J9M+ z?R=^5u(yK)a*gOG*4}?e6}5i(bxF;MOaC(m+ZA_M+rSV^4T=NqY}a!lRiXc$5lSiN zc5i73g3%u+VRX4Nfd&G*qSf?| zPj1sX64>ZB0d<;riCZ; z*A@rWab?$$4U#|AYJ_{*Rz#g3NE)cQkm-!X=9QB&O|ebY$7uPBrm?!7D)Ii?N?~Ke zJU!hph7ueR`dj*6%&e;8bw7r8y;eh74QWx##Q4+9L#8`pSvYUg27Wrr5=F188e9O2 zh4LHc15|UD(t=q6yrFN6(2t*{j!AD}_fLM5Vs{Qddy)~GyR_Jf6s;jdKo{V!RN#d*GoU%-35G|C8rFd?BLJq( z&+oFjpNUBr3SX%Or$k?vO(ol>8UiO)pIGhSk6mqiQYvOj&b9SzZCB?zCfC%FNaED= zUvhA;9H{;X7v20Hx}aBFm%mK>A9bB|Sd(wq_f<-zL8McpLr_qV5JpLgNY@5}fCHo% zA%etU#E_a&(j612Q4%9Ym*nWtAs`*TQ-8k4^ZfB#e_!`~TybAH4M%JmKR3?xH2(emL+n!8@G9Tl~T)`o^R}6=9`X?vVr>bYFb*{do9tYX}7a4&kC&Taz z?ccVWu?R#q*s(DJ26MUaVZvMM#0$Ig7S0Zo$Q`Z@n}qB&>thCl0}Ojm6B(v>z)fUr zG~aH+iz$%9lLPq$f{q%_fkDDfO#38M198-ABU2}J<4idaR4Hp4De+}M$M&Wq`u3A0 z_F4~jbh3{7w=W#8$O`;WF+?nAT0wr5J&CPc0dWbnSlW+0^OL4CLwr@Q>?@Rn^lc}7 zo($TL`|uDj-&y!ELZ4LGzmNo$T75Y+$u`_3mRAPaKHY%Eo*4!q7U}OfHjK2CbpeK} z($!o0h70!Km9;}B`;z7@7#J52bkmZZKtIfNzx;q?O)fdxTK+f0PWi`E>8e++?>Ut@Ui%=*ZC&6VMP%A`)~)Co?%p)xbp1n_yYIbQn`=uv9%+AeqI~L{?Cd{i z<;=Spx+W%aJ2Y71^;@fh*)~>ZIoIsKj`w=-7$npf!T!>6GP7NZcS$C8zC#IPG2vqofEI3w8_V_A1ytF^`~ZT5iY& zrIvYU_J=2vAaa16W?_|<1|7DhmWz+)$jn*W+?3jU@ggYRr_XzIPE+%@wtD?AM0=A55N@v-i*Y-LrJGMf*>su}@=G&u6+H-Ry@*F>wfhGep znm%ZwiSf7Uw2%U3*!9D6ml8ijTFK=Lr@!~|C=Lk;{nMv@b>~Jora9V8a_9kJZU#0~ zr4?R`R?SOiTDq_t>a?cBd*}Jfw?-z`W^i)29v6u-#<)c{&8Pl)*UHZz=9chlTjc^8 zZtl+r9#innUzqDpovudc0soI!zYZgDqUE&{?d4qZM@8SY1ca6U3-vq2Q096(4>JDW zq5cfQHe%COg9*bT!n@@!IFq}s0Zyyi7gXz!3SL@bT8(LlEJi3MQSLQBSaQCp~utusgY@5N^fwY88(E?k(oi`Bko)zHXF ziFR`RP$zwaNB6ZEHq1Z?r}jhnjl^QAdEcj$GM^7AWbC%m&k z@-g2L3k;#9qE8ATKoXmzl;X{B`3;AWo~A6zTOYPXRn!W$sAxDE+HWgzpMM)6b23NA z66fo`(ZBYLKcLH$3H``7wwG{eNnl=7^kFf>PQ(*xj;>C0-<_w&zYe#F1Tf;11jnuZ z??6C~CkjcXt4?Ylo&?)l5+11-Ul@_Mkn$}63!9Q#B& zfp`<$h@9&)Pk>jhf*3*>flWuL&NXE8$XkSIvr=x$i>YHE+vB;Eo!yIHv(;7O-Cw17 zoR-q>c_Apoq;dBF;vlO{1+CeFfxPw8;K{MY)y8tIrm~dfZf!A;^6tObvmJ9X<3m~muTpcI&TO390 zp+iSUhd3Nx^j@x=!06}FhFVAv`W|h^**xFjX&R$Cgr3pul(n?R$PmLuBbwx;wW9rh zy4;Lrtsdop%1O5@3tMu6FeS$h8)G#Kdq&50m53%Fb?)?s;OY9%Uws`JfG}K>{3_M> zc!!&t8*XfNdpc_8Xfp(DrGOXyt7-hAs2d*AH8bO4&zo8FN^lxI^|Ai>`O5UzGZY=v zlq9u(NLWAZ>gyQec*C^}vqyFL?+axF3r7af{YWtH2zetHV}6nH1ba=p2u4IHkxVaj z4tF=LoFz;LR%TAkiW8(Tfie~bZnB%{zL%wUK&OaY*$rG!&GVbd13&iFiWr?doo0~$ z_T`-zrE&%pFL$|~o!{ecVcjmb>W`M`IsbB<`HKL2zTBwLTniww`%p8lgAYm9fR2n} z)|tbN(17*j26_y1DDPM82!HGGnD7=Up&_o-^1s4XYXHeNAwO9c9v3-1|5}5e9XMj( zfZ?zF_dtj%-}rP{d~-52w186f-LKr@))vDR&@eso8;|p6^_T6Y;xDO{o>X{ZecC7@ znupM&vF>LjcoTRovgo>NIXO1orv?6(b!Q%w^=v169J9r;JAZw9Q3OPt3&UT+;< z6Pg*y1{c|{C89PGWpmE6#2ZDDik{bBU|H3nk&k%Z-!det>6sZv+m3KZfD4KhR7hG9 zzX>WLmr5Jez`8Lxdflz>1Zs~vf<`;Q7XkHv^Ltn^;7!t&3lJAoVFz+Cr?WgN?UhAM zKymsisjx|#b&^Td?RA?o-S0+4rdaagSjKh(dhrR3`E?M#bdr0Xu30^x(?+zmunb`A zE2_Q{j^IhZ*d-tucPP(Mcq`35_inG^Han`0xOK|D4?FsAaAiV>2^ybbqv7zzn#IGZ zxpjx4(jWT=Xsj1D5QUQVJ3Lttr=sbFYjk6%*w~00EH)j{`ow_w?W7v(P_wMz@dm@u&)zKd(Q4EtE0t^&hMId~?j8J!bI6~iW% z<@ir`WEg^WGsRq@7%g+?t&5mmvhr1Lwa|_5UI_=KK~LPSq}BH}C9uizq=<(n$n{;1 zA#2N56Q(KK14N2ja8GsCaGpBIE-1=~IoPoau?%^}q~4F*asAJ=zG<5V`S8)iIOn zPR8&WJl&F`+JU~qA}!4o<`#$IQZ4S`=jYdLZ}_~AG{4Ux^+9;YTI38y=Dq0`-;tG- zxpcUCa^mQCpgGb=K_bhwIbPoSE*^ZphlzZ_G~UTx?3rHJ<|a+?dDX2$^0>aR%%4`- z;YuBY8Gbzz`hoRKyum6YbGw7hY7w4cURvayc{uCl=ICP0g7!&rh|$4o39{R-2t$rJ zT#W9q#f))IcHC$mrZcK55qm~m1F+al#V(kQGLk~c>MOAVm*tli)*IUk z1_V4_sd;1sEY2=T`Lrgu$RB)D^~Y3R-lN8`USC+cn02f?JQvS2G(;;T9vlvG*(>td znwP1j%IuF)E!0g=U6Cj^JxkD4R4aWPK(iL0oV5>=>vv<1Wgu(FF zXCwd@;cHo+{I(59#gFJYPgH$7^&{io+cKbiskG8)72yvCSli<;uS)u;9v3@G85PvC z8MZ;CyeuLNRZh7k8`vPKFr;hxmaOfzOyFJlWMDq+{xz}1y)fo+F6Ug4^M?UfF)2$sm9G;_N7HR5aHi&Wv#hH@YWZLU8RI=N|&lv(1cly@^Ph z8Sg|FJl!7V)(7jUEZ$sBwf`kK5Zd=ff{WL9VGOSv;PY zZBkqbKL#4sWU}Ex5_+p_od;s2BEC@xXEvavhGyz>(;>opUkX2gu`_kIL|HT0{+zG} zY-dM1s$g*O=_vahgLzGVcWHcbz>i%NvYR#n`8|* zzro6y-#yvpGL0(yS9P%!Dig%WxPAsEg9NwlRx|~m8EFqYPaH`ev3|s(~wYs+57nPG*^-No{#M? zZX_vUT(>*6tgK9kHEX69EqFN}P}I?DxawX(CreM{CgGV@sPa~UPF#I`e(gB{4!#XA}?$ARr<87Ea6iW3zb0#jG}9fqmEoTMlwnj`og9mUM0&%<6bK#~pMR z*?TtQFW;#$aO2?&hvj=;3z$S{*7K5yKu!UkX+0r(@kKsp%po8kpy%TSi&H(w3Lww1E8}MQ zDeQnffNN!@Q31n)Rrjhd0(Cv_n-(s^a;-2+gqq2xaA^TdslX3R5os*S zUllfo21{n0_b@&Z99w+*wvoK(ElW5sf5tWO?rhKxLP(#Lsnj|q^}OK44jtgh;~g$885X?y$xt<1 zgpBwv!$V1Fr5WqR19ENQ7V>vvTqt7=)V1cBL+M)I^IYJzt2C*vIM)ge3oEF=KZ9@T zdhU4EpEJ)Vt8{a4Sl5cTgy18IuCaZv!A4Xd0SU*qbek6qtiE`=>p#T!=y>y|A*Y+%47>t_>Xl@txMVbmo0-22jqtV|Mf&^1aR-)2yv}*GW>fn z^#K)`&)*m(6zX&R|93}8mhj)}*Cox&&2`PqOWrDv$l^D0$hIf(zj`B%_`X2~HAhmR zZU!lJse%96;lb?Fz()N3YGq~R`t?C{uR|q10aGpQf7P(k57y2DXlqmS*j7lZySvcX zgf5uTtq2+ZYg}cf^K9c@=E;xwRz4x2;6XbjfB%M4KHagxq9TBe&E1sW?*{^nXnMMdZ89I y-O^EGLC7Y4L_GBV4Miul#&1*TKgEY|?w6-*E&)yB*O4pu@>E${sZ /dev/null +} + +# Function to execute Terraform destroy +destroy_terraform() { + local dir=$1 + echo "Starting Terraform destroy in directory: $dir" + + # Navigate to the specified directory + cd "$dir" || exit 1 + + # Run Terraform destroy command + terraform destroy -var-file="secrets.tfvars" -auto-approve + + if [[ $? -eq 0 ]]; then + echo "Terraform destroy completed successfully in directory: $dir" + else + echo "Terraform destroy failed in directory: $dir" + fi + + # Return to the initial directory + cd - > /dev/null +} + +# Function to run setup for all CSPs +run() { + run_terraform "$AWS_DIR" & + run_terraform "$GCP_DIR" & + run_terraform "$NCP_DIR" & + + # Wait for all background processes to complete + wait + echo "All Terraform setup processes completed." +} + +# Function to destroy resources for all CSPs +destroy() { + destroy_terraform "$AWS_DIR" & + destroy_terraform "$GCP_DIR" & + destroy_terraform "$NCP_DIR" & + + # Wait for all background processes to complete + wait + echo "All Terraform destroy processes completed." +} diff --git a/scripts/init-settings.sh b/scripts/init-settings.sh new file mode 100644 index 0000000..8eebda7 --- /dev/null +++ b/scripts/init-settings.sh @@ -0,0 +1,9 @@ +# Load the script +BASE_DIR="$(cd "$(dirname "$0")" && pwd)" +source $BASE_DIR/set_credentials.sh + +# Call the set_creds function +set_creds + + + diff --git a/scripts/set_credentials.sh b/scripts/set_credentials.sh new file mode 100644 index 0000000..fa3a216 --- /dev/null +++ b/scripts/set_credentials.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Define constants for file paths relative to the execution location +AWS_SECRETS_FILE="./data/var/run/data-manager/template/example/AWS/BUILDER/secrets.tfvars" +NCP_SECRETS_FILE="./data/var/run/data-manager/template/example/NCP/BUILDER/secrets.tfvars" +GCP_SECRETS_FILE="./data/var/run/data-manager/template/example/GCP/BUILDER/secrets.json" +DEFAULT_PROFILE_FILE="./data/var/run/data-manager/profile/profile.json" + +# Function to determine the profile.json file path +get_profile_file() { + if [[ -f "./profile.json" ]]; then + PROFILE_FILE="./profile.json" + DESTINATION_FILE="$DEFAULT_PROFILE_FILE" + echo "Using profile.json from the current directory: $PROFILE_FILE" + else + PROFILE_FILE="$DEFAULT_PROFILE_FILE" + DESTINATION_FILE="" + echo "Using profile.json from the default path: $PROFILE_FILE" + fi +} + +# Function to check if the profile.json file exists +check_profile_file_exists() { + if [[ ! -f "$PROFILE_FILE" ]]; then + echo "Error: $PROFILE_FILE file not found." + exit 1 + fi +} + +# Function to extract AWS and NCP credentials +extract_aws_ncp_credentials() { + aws_access_key=$(jq -r '.[0].credentials.aws.accessKey' "$PROFILE_FILE") + aws_secret_key=$(jq -r '.[0].credentials.aws.secretKey' "$PROFILE_FILE") + ncp_access_key=$(jq -r '.[0].credentials.ncp.accessKey' "$PROFILE_FILE") + ncp_secret_key=$(jq -r '.[0].credentials.ncp.secretKey' "$PROFILE_FILE") +} + +# Function to extract GCP credentials +extract_gcp_credentials() { + gcp_credentials=$(jq -r '.[0].credentials.gcp' "$PROFILE_FILE") +} + +# Function to create AWS secrets.tfvars file +create_aws_secrets_file() { + cat < "$AWS_SECRETS_FILE" +access_key = "$aws_access_key" +secret_key = "$aws_secret_key" +EOF + echo "AWS credentials saved to: $AWS_SECRETS_FILE" +} + +# Function to create NCP secrets.tfvars file +create_ncp_secrets_file() { + cat < "$NCP_SECRETS_FILE" +access_key = "$ncp_access_key" +secret_key = "$ncp_secret_key" +EOF + echo "NCP credentials saved to: $NCP_SECRETS_FILE" +} + +# Function to create GCP secrets.json file +create_gcp_secrets_file() { + echo "$gcp_credentials" > "$GCP_SECRETS_FILE" + echo "GCP credentials saved to: $GCP_SECRETS_FILE" +} + +# Function to copy profile.json to the default path if it was used from the current directory +copy_profile_file_if_needed() { + if [[ -n "$DESTINATION_FILE" ]]; then + cp "$PROFILE_FILE" "$DESTINATION_FILE" + echo "profile.json has been copied to $DESTINATION_FILE" + fi +} + +# set_creds function to perform all steps +set_creds() { + get_profile_file # Determine profile.json path + check_profile_file_exists # Check if profile.json exists + extract_aws_ncp_credentials # Extract AWS and NCP credentials + extract_gcp_credentials # Extract GCP credentials + create_aws_secrets_file # Create AWS secrets file + create_ncp_secrets_file # Create NCP secrets file + create_gcp_secrets_file # Create GCP secrets file + copy_profile_file_if_needed # Copy profile.json if from current directory + echo "All credential files have been successfully saved." +} diff --git a/web/js/scripts.js b/web/js/scripts.js index 6957d50..94b965b 100644 --- a/web/js/scripts.js +++ b/web/js/scripts.js @@ -377,6 +377,84 @@ document.addEventListener('DOMContentLoaded', function () { }); + + + +document.addEventListener('DOMContentLoaded', function () { + const genServiceLink = document.getElementById('genServiceLink'); + + if (genServiceLink) { + genServiceLink.addEventListener('click', function (event) { + event.preventDefault(); + + const userConfirmed = confirm('정말로 데이터 관련 서비스를 생성하시겠습니까?'); + if (!userConfirmed) { + return; + } + + fetch('/service/apply', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + }) + .then(response => { + if (response.ok) { + alert('서비스 생성 요청이 전달 되었습니다.'); + } else { + return response.json().then(data => { + throw new Error(data.message || '서비스 생성 요청 중 오류가 발생했습니다.'); + }); + } + }) + .catch(error => { + console.error('Error:', error); + alert(`오류: ${error.message}`); + }); + }); + } else { + console.error('Gen Service 링크를 찾을 수 없습니다.'); + } +}); + + +document.addEventListener('DOMContentLoaded', function () { + const delServiceLink = document.getElementById('delServiceLink'); + + if (delServiceLink) { + delServiceLink.addEventListener('click', function (event) { + event.preventDefault(); + + const userConfirmed = confirm('정말로 데이터 관련 서비스를 제거하시겠습니까?'); + if (!userConfirmed) { + return; + } + + fetch('/service/destroy', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + } + }) + .then(response => { + if (response.ok) { + alert('서비스 제거 요청이 전달 되었습니다.'); + } else { + return response.json().then(data => { + throw new Error(data.message || '서비스 제거 요청 중 오류가 발생했습니다.'); + }); + } + }) + .catch(error => { + console.error('Error:', error); + alert(`오류: ${error.message}`); + }); + }); + } else { + console.error('Del Service 링크를 찾을 수 없습니다.'); + } +}); + // for m-cmp/mc-web-console // message Info diff --git a/web/templates/header.html b/web/templates/header.html index 0e39d6e..b5608c3 100644 --- a/web/templates/header.html +++ b/web/templates/header.html @@ -40,8 +40,11 @@

diff --git a/websrc/controllers/serivceHandlers.go b/websrc/controllers/serivceHandlers.go index 9059177..d747221 100644 --- a/websrc/controllers/serivceHandlers.go +++ b/websrc/controllers/serivceHandlers.go @@ -16,11 +16,17 @@ limitations under the License. package controllers import ( + "bufio" + "fmt" "net/http" + "os" + "os/exec" + "path/filepath" "time" "github.com/cloud-barista/mc-data-manager/models" "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" ) // DeleteServiceAndTaskAllHandler godoc @@ -35,7 +41,7 @@ import ( // @Router /service/clearAll [delete] func (tc *TaskController) DeleteServiceAndTaskAllHandler(ctx echo.Context) error { start := time.Now() - logger, logstrings := pageLogInit(ctx, "Delete-task", "Delete an existing task", start) + logger, logstrings := pageLogInit(ctx, "Delete-All-Task", "Delete an existing task", start) if err := tc.TaskService.ClearServiceAndTaskAll(); err != nil { errStr := "Clear All Task , Failed" logger.Error().Msg(errStr) @@ -49,3 +55,159 @@ func (tc *TaskController) DeleteServiceAndTaskAllHandler(ctx echo.Context) error Error: nil, }) } + +// applyResourceHandler godoc +// +// @ID applyResourceHandler +// @Summary Apply Resources +// @Description Execute the apply.sh script to set up resources. +// @Tags [Service] +// @Produce json +// @Success 200 {object} models.BasicResponse "Successfully applied resources" +// @Failure 500 {object} models.BasicResponse "Failed to apply resources" +// @Router /service/apply [post] +func (tc *TaskController) ApplyResourceHandler(ctx echo.Context) error { + + start := time.Now() + logger, logstrings := pageLogInit(ctx, "apply-resource", "Apply an Data Resource", start) + // Get the directory of the current executable + execPath, err := os.Executable() + if err != nil { + errStr := "Failed to retrieve the executable path" + logger.Error().Msg(errStr) + return ctx.JSON(http.StatusInternalServerError, models.BasicResponse{ + Result: "", + Error: &errStr, + }) + } + // Define the script path relative to the executable directory + scriptPath := filepath.Join(filepath.Dir(execPath), "scripts/apply.sh") + // Run the command and capture output + err = asyncRunCommand(scriptPath) + + if err != nil { + errStr := fmt.Sprintf("Failed to apply resources: %s", err.Error()) + logger.Error().Msg(errStr) + return ctx.JSON(http.StatusInternalServerError, models.BasicResponse{ + Result: logstrings.String(), + Error: &errStr, + }) + } + + return ctx.JSON(http.StatusOK, models.BasicResponse{ + Result: logstrings.String(), + Error: nil, + }) +} + +// destroyResourceHandler godoc +// +// @ID destroyResourceHandler +// @Summary Destroy Resources +// @Description Execute the destroy.sh script to destroy resources. +// @Tags [Service] +// @Produce json +// @Success 200 {object} models.BasicResponse "Successfully destroyed resources" +// @Failure 500 {object} models.BasicResponse "Failed to destroy resources" +// @Router /service/destroy [delete] +func (tc *TaskController) DestroyResourceHandler(ctx echo.Context) error { + start := time.Now() + logger, logstrings := pageLogInit(ctx, "destroy-resource", "Destroy an Data Resource", start) + // Get the directory of the current executable + execPath, err := os.Executable() + if err != nil { + errStr := "Failed to retrieve the executable path" + logger.Error().Msg(errStr) + return ctx.JSON(http.StatusInternalServerError, models.BasicResponse{ + Result: "", + Error: &errStr, + }) + } + // Define the script path relative to the executable directory + scriptPath := filepath.Join(filepath.Dir(execPath), "scripts/destroy.sh") + // Run the command and capture output + err = asyncRunCommand(scriptPath) + + if err != nil { + errStr := fmt.Sprintf("Failed to destroy resources: %s", err.Error()) + logger.Error().Msg(errStr) + return ctx.JSON(http.StatusInternalServerError, models.BasicResponse{ + Result: logstrings.String(), + Error: &errStr, + }) + } + + return ctx.JSON(http.StatusOK, models.BasicResponse{ + Result: logstrings.String(), + Error: nil, + }) +} + +// asyncRunCommand starts the command asynchronously and returns an error if it fails to start +func asyncRunCommand(scriptPath string) error { + cmd := exec.Command("bash", scriptPath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + // Start the command asynchronously + if err := cmd.Start(); err != nil { + log.Error().Err(err).Msgf("Failed to start script %s", scriptPath) + return fmt.Errorf("failed to start script %s: %w", scriptPath, err) + } + + // Run in a separate goroutine to avoid blocking + go func() { + // Wait for the command to complete + if err := cmd.Wait(); err != nil { + log.Printf("Script %s finished with error: %v", scriptPath, err) + } else { + log.Printf("Script %s executed successfully", scriptPath) + } + }() + + return nil +} + +// asyncRunCommandWait captures output and logs it to zerolog +func asyncRunCommandWait(scriptPath string) (string, error) { + cmd := exec.Command("bash", scriptPath) + stdout, err := cmd.StdoutPipe() + if err != nil { + return "", fmt.Errorf("failed to get stdout: %w", err) + } + + stderr, err := cmd.StderrPipe() + if err != nil { + return "", fmt.Errorf("failed to get stderr: %w", err) + } + + if err := cmd.Start(); err != nil { + log.Error().Err(err).Msgf("Failed to start script %s", scriptPath) + return "", fmt.Errorf("failed to start command: %w", err) + } + + outputChan := make(chan string) + go func() { + var output string + scanner := bufio.NewScanner(stdout) + for scanner.Scan() { + line := scanner.Text() + log.Info().Msg(line) + output += line + "\n" + } + scanner = bufio.NewScanner(stderr) + for scanner.Scan() { + line := scanner.Text() + log.Error().Msg(line) + output += line + "\n" + } + outputChan <- output + }() + + if err := cmd.Wait(); err != nil { + log.Error().Err(err).Msgf("Script %s finished with error", scriptPath) + return <-outputChan, fmt.Errorf("command failed: %w", err) + } + + log.Info().Msgf("Script %s executed successfully", scriptPath) + return <-outputChan, nil +} diff --git a/websrc/docs/docs.go b/websrc/docs/docs.go index 4627c23..a332a15 100644 --- a/websrc/docs/docs.go +++ b/websrc/docs/docs.go @@ -1486,6 +1486,33 @@ const docTemplate = `{ } } }, + "/service/apply": { + "post": { + "description": "Execute the apply.sh script to set up resources.", + "produces": [ + "application/json" + ], + "tags": [ + "[Service]" + ], + "summary": "Apply Resources", + "operationId": "applyResourceHandler", + "responses": { + "200": { + "description": "Successfully applied resources", + "schema": { + "$ref": "#/definitions/models.BasicResponse" + } + }, + "500": { + "description": "Failed to apply resources", + "schema": { + "$ref": "#/definitions/models.BasicResponse" + } + } + } + } + }, "/service/clearAll": { "delete": { "description": "Delete an All Service and Task.", @@ -1513,6 +1540,33 @@ const docTemplate = `{ } } }, + "/service/destroy": { + "delete": { + "description": "Execute the destroy.sh script to destroy resources.", + "produces": [ + "application/json" + ], + "tags": [ + "[Service]" + ], + "summary": "Destroy Resources", + "operationId": "destroyResourceHandler", + "responses": { + "200": { + "description": "Successfully destroyed resources", + "schema": { + "$ref": "#/definitions/models.BasicResponse" + } + }, + "500": { + "description": "Failed to destroy resources", + "schema": { + "$ref": "#/definitions/models.BasicResponse" + } + } + } + } + }, "/task": { "get": { "description": "Retrieve a list of all Tasks in the system.", diff --git a/websrc/docs/swagger.json b/websrc/docs/swagger.json index 01e5e92..cd42e6b 100644 --- a/websrc/docs/swagger.json +++ b/websrc/docs/swagger.json @@ -1479,6 +1479,33 @@ } } }, + "/service/apply": { + "post": { + "description": "Execute the apply.sh script to set up resources.", + "produces": [ + "application/json" + ], + "tags": [ + "[Service]" + ], + "summary": "Apply Resources", + "operationId": "applyResourceHandler", + "responses": { + "200": { + "description": "Successfully applied resources", + "schema": { + "$ref": "#/definitions/models.BasicResponse" + } + }, + "500": { + "description": "Failed to apply resources", + "schema": { + "$ref": "#/definitions/models.BasicResponse" + } + } + } + } + }, "/service/clearAll": { "delete": { "description": "Delete an All Service and Task.", @@ -1506,6 +1533,33 @@ } } }, + "/service/destroy": { + "delete": { + "description": "Execute the destroy.sh script to destroy resources.", + "produces": [ + "application/json" + ], + "tags": [ + "[Service]" + ], + "summary": "Destroy Resources", + "operationId": "destroyResourceHandler", + "responses": { + "200": { + "description": "Successfully destroyed resources", + "schema": { + "$ref": "#/definitions/models.BasicResponse" + } + }, + "500": { + "description": "Failed to destroy resources", + "schema": { + "$ref": "#/definitions/models.BasicResponse" + } + } + } + } + }, "/task": { "get": { "description": "Retrieve a list of all Tasks in the system.", diff --git a/websrc/docs/swagger.yaml b/websrc/docs/swagger.yaml index cf72a19..5efc16b 100644 --- a/websrc/docs/swagger.yaml +++ b/websrc/docs/swagger.yaml @@ -1179,6 +1179,24 @@ paths: summary: Update an existing Schedule tags: - '[Schedule]' + /service/apply: + post: + description: Execute the apply.sh script to set up resources. + operationId: applyResourceHandler + produces: + - application/json + responses: + "200": + description: Successfully applied resources + schema: + $ref: '#/definitions/models.BasicResponse' + "500": + description: Failed to apply resources + schema: + $ref: '#/definitions/models.BasicResponse' + summary: Apply Resources + tags: + - '[Service]' /service/clearAll: delete: description: Delete an All Service and Task. @@ -1197,6 +1215,24 @@ paths: summary: Delete a Task tags: - '[Service]' + /service/destroy: + delete: + description: Execute the destroy.sh script to destroy resources. + operationId: destroyResourceHandler + produces: + - application/json + responses: + "200": + description: Successfully destroyed resources + schema: + $ref: '#/definitions/models.BasicResponse' + "500": + description: Failed to destroy resources + schema: + $ref: '#/definitions/models.BasicResponse' + summary: Destroy Resources + tags: + - '[Service]' /task: get: description: Retrieve a list of all Tasks in the system. diff --git a/websrc/routes/serviceRoute.go b/websrc/routes/serviceRoute.go index 3274acf..3adf85a 100644 --- a/websrc/routes/serviceRoute.go +++ b/websrc/routes/serviceRoute.go @@ -32,6 +32,13 @@ func ServiceRoot(g *echo.Group, scheduleManager *task.FileScheduleManager) { TaskService: scheduleManager, } + // Route to clear all services and tasks g.DELETE("/clearAll", serviceController.DeleteServiceAndTaskAllHandler) + // Route to apply resources using apply.sh + g.POST("/apply", serviceController.ApplyResourceHandler) + + // Route to destroy resources using destroy.sh + g.DELETE("/destroy", serviceController.DestroyResourceHandler) + } From b71bb0335b9fa9f4dbf89b7c397d9f995562b1ce Mon Sep 17 00:00:00 2001 From: heedaeshin Date: Thu, 31 Oct 2024 17:42:38 +0900 Subject: [PATCH 2/2] Fix: init-setting --- scripts/set_credentials.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/set_credentials.sh b/scripts/set_credentials.sh index fa3a216..95d3406 100644 --- a/scripts/set_credentials.sh +++ b/scripts/set_credentials.sh @@ -4,6 +4,8 @@ AWS_SECRETS_FILE="./data/var/run/data-manager/template/example/AWS/BUILDER/secrets.tfvars" NCP_SECRETS_FILE="./data/var/run/data-manager/template/example/NCP/BUILDER/secrets.tfvars" GCP_SECRETS_FILE="./data/var/run/data-manager/template/example/GCP/BUILDER/secrets.json" +GCP_DUMMY_FILE="./data/var/run/data-manager/template/example/GCP/BUILDER/secrets.tfvars" + DEFAULT_PROFILE_FILE="./data/var/run/data-manager/profile/profile.json" # Function to determine the profile.json file path @@ -62,6 +64,7 @@ EOF create_gcp_secrets_file() { echo "$gcp_credentials" > "$GCP_SECRETS_FILE" echo "GCP credentials saved to: $GCP_SECRETS_FILE" + touch $GCP_DUMMY_FILE } # Function to copy profile.json to the default path if it was used from the current directory