เชฎเซเช เชคเชพเชเซเชคเชฐเชฎเชพเช เชฒเชเซเชฏเซเช เชเซ
เชชเซเชฐเชถเซเชจเชจเซ เชชเซเชทเซเช เชญเซเชฎเชฟ เช เชเซ: เชเช เชธเชฎเชฏเซ เชเช เชชเซเชฐเซเชเซเชเซเช เชนเชคเซ, เชถเชฐเซเชเชคเชฎเชพเช เชคเซ เชเชชเชฏเซเชเชฟเชคเชพเช เช เชจเซ เชธเซเชเซเชฐเชฟเชชเซเชเซ เชธเชพเชฅเซเชจเซ เชเช เชจเชพเชจเซ เชฎเซเชจเซเชฒเชฟเชฅ เชนเชคเซ, เชชเชฐเชเชคเซ เชธเชฎเชฏ เชเชคเชพเช เชคเซ เชตเชงเชคเซ เชเชฏเซ, เชธเซเชตเชพเชเชฎเชพเช เชตเชฟเชญเชพเชเชฟเชค เชฅเชฏเซ, เชเซ เชฌเชฆเชฒเชพเชฎเชพเช เชฎเชพเชเชเซเชฐเซเชธเชฐเซเชตเชฟเชธเชฟเชธเชฎเชพเช เชตเชฟเชญเชพเชเชฟเชค เชฅเชตเชพ เชฒเชพเชเซเชฏเซ, เช เชจเซ เชชเชเซ เชฎเชพเชชเชตเชพเชฎเชพเช เชเชตเซ เชเซ. เชถเชฐเซเชเชคเชฎเชพเช, เช เชฌเชงเซเช เชเชเชฆเชฎ VPS เชชเชฐ เชเชฐเชตเชพเชฎเชพเช เชเชตเชคเซเช เชนเชคเซเช, เชเซเชก เชธเซเช เชเชฐเชตเชพ เช เชจเซ เชเชฎเชพเชตเชตเชพเชจเซ เชชเซเชฐเชเซเชฐเชฟเชฏเชพเช เชเซ เชเซเชจเชพ เชชเชฐ Ansible เชจเซ เชเชชเชฏเซเช เชเชฐเซเชจเซ เชธเซเชตเชเชพเชฒเชฟเชค เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชนเชคเซ, เช เชจเซ เชฆเชฐเซเช เชธเซเชตเชพเชจเซ เชเชฐเซเชฐเซ เชธเซเชเชฟเชเชเซเชธ เช เชจเซ เชเซ เชธเชพเชฅเซ YAML เชฐเซเชชเชฐเซเชเชพ เชธเชพเชฅเซ เชธเชเชเชฒเชฟเชค เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชนเชคเซ, เช เชจเซ เชธเชฎเชพเชจ เชฐเซเชชเชฐเซเชเชพ เชซเชพเชเชฒเชจเซ เชเชชเชฏเซเช เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฏเซ เชนเชคเซ. เชธเซเชฅเชพเชจเชฟเช เชฒเซเชจเซเช, เชเซ เชเซเชฌ เช เชจเซเชเซเชณ เชนเชคเซเช, เชเชพเชฐเชฃ เชเซ .k เช เชฐเซเชชเชฐเซเชเชพ เชตเซเชถเซเชตเชฟเช เชเชฌเซเชเซเชเซเชเชฎเชพเช เชฒเซเชก เชฅเชฏเซเชฒ เชเซ, เชชเซเชฐเซเชเซเชเซเชเชฎเชพเช เชเชฎเซ เชคเซเชฏเชพเชเชฅเซ เชเชเซเชธเซเชธ เชเชฐเซ เชถเชเชพเชฏ เชเซ.
เชเซ เชเซ, เชฎเชพเชเชเซเชฐเซเชธเชฐเซเชตเชฟเชธเชฟเชธเชจเซ เชธเชเชเซเชฏเชพเชฎเชพเช เชตเซเชฆเซเชงเชฟ, เชคเซเชฎเชจเชพ เชเซเชกเชพเชฃเซ เช
เชจเซ
เช เชธเชเชฆเชฐเซเชญเชฎเชพเช, เช เชฎเชพเชฐเซ เชเซเชฒเชพเชธเชฟเช เชฐเซเชชเชฐเซเชเชพ เชซเชพเชเชฒ เช เชจเซ เชเซเชฌเซเชฐเชจเชพ เชฐเชนเชธเซเชฏเซ เชฌเชเชจเซ เชธเชพเชฅเซ เชเชพเชฎ เชเชฐเชตเชพ เชฎเชพเชเซ เชธเชเซเชทเชฎ เชฅเชตเชพ เชฎเชพเชเซ เชฐเซเชชเชฐเซเชเชพเชเชเชจ เชเชฌเซเชเซเชเซเช เชฌเชจเชพเชตเชตเชพ เชฎเชพเชเซเชจเซ เชชเชฆเซเชงเชคเชฟเชฎเชพเช เชซเซเชฐเชซเชพเชฐ เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฏเซ เชนเชคเซ. เชคเซเชฐเซเชเชพ เชชเชพเชฏเชฅเซเชจเชจเซ เชญเชพเชทเชพเชฎเชพเช เชตเชงเซ เชเช เซเชฐ เชฐเซเชชเชฐเซเชเชพ เชฎเชพเชณเชเซเช เชชเชฃ เชธเซเชชเชทเซเช เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฏเซเช เชนเชคเซเช, เชจเซเชเซ เชชเซเชฐเชฎเชพเชฃเซ:
Dict[str, Dict[str, Union[str, int, float]]]
เชเชเชฒเซ เชเซ, เช เชเชคเชฟเชฎ เชเซเชเชซเชฟเช เช เชจเชพเชฎเชตเชพเชณเชพ เชตเชฟเชญเชพเชเซ เชธเชพเชฅเซเชจเซ เชถเชฌเซเชฆเชเซเชถ เชเซ, เชเซเชฎเชพเชเชฅเซ เชฆเชฐเซเช เชธเชฐเชณ เชชเซเชฐเชเชพเชฐเซเชจเชพ เชฎเซเชฒเซเชฏเซ เชธเชพเชฅเซเชจเซ เชถเชฌเซเชฆเชเซเชถ เชเซ. เช เชจเซ เชตเชฟเชญเชพเชเซ เชเซเชเซเชเชธ เชชเซเชฐเชเชพเชฐเชจเชพ เชธเชเชธเชพเชงเชจเซเชจเซ เชเซเช เชตเชฃเซ เช เชจเซ เชเชเซเชธเซเชธเชจเซเช เชตเชฐเซเชฃเชจ เชเชฐเซ เชเซ. เช เชฎเชพเชฐเซ เชฐเซเชชเชฐเซเชเชพเชจเชพ เชญเชพเชเชจเซเช เชเชฆเชพเชนเชฐเชฃ:
adminka:
django_secret: "ExtraLongAndHardCode"
db_main:
engine: mysql
host: 256.128.64.32
user: cool_user
password: "SuperHardPassword"
redis:
host: 256.128.64.32
pw: "SuperHardPassword"
port: 26379
smtp:
server: smtp.gmail.com
port: 465
email: [email protected]
pw: "SuperHardPassword"
เชคเซ เช เชธเชฎเชฏเซ, เชเซเชทเซเชคเซเชฐ engine
เชกเซเชเชพเชฌเซเช SQLite เชชเชฐ เชเชจเซเชธเซเชเซเชฒ เชเชฐเซ เชถเชเชพเชฏ เชเซ, เช
เชจเซ redis
เชชเชฐ เชธเซเช เชเชฐเซ mock
, เชธเชพเชเชตเชตเชพ เชฎเชพเชเซเชจเซ เชซเชพเชเชฒเชจเซเช เชจเชพเชฎ เชชเชฃ เชธเซเชชเชทเซเช เชเชฐเชตเซเช - เช เชชเชฐเชฟเชฎเชพเชฃเซ เชฏเซเชเซเชฏ เชฐเซเชคเซ เชเชณเชเชตเชพเชฎเชพเช เชเชตเซ เชเซ เช
เชจเซ เชชเซเชฐเชเซเชฐเชฟเชฏเชพ เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เชเซ เชกเชฟเชฌเชเซเชเช, เชฏเซเชจเชฟเช เชชเชฐเซเชเซเชทเชฃ เช
เชจเซ เช
เชจเซเชฏ เชเซเชเชชเชฃ เชเชฐเซเชฐเชฟเชฏเชพเชคเซ เชฎเชพเชเซ เชเซเชกเชจเซ เชธเซเชฅเชพเชจเชฟเช เชฐเซเชคเซ เชเชฒเชพเชตเชตเชพเชจเซเช เชธเชฐเชณ เชฌเชจเชพเชตเซ เชเซ. เช เช
เชฎเชพเชฐเชพ เชฎเชพเชเซ เชเชพเชธ เชเชฐเซเชจเซ เชฎเชนเชคเซเชตเชจเซเช เชเซ เชเชพเชฐเชฃ เชเซ เช
เชจเซเชฏ เชเชฃเซ เชเชฐเซเชฐเชฟเชฏเชพเชคเซ เชเซ - เช
เชฎเชพเชฐเชพ เชเซเชกเชจเซ เชเช เชญเชพเช เชตเชฟเชตเชฟเชง เชตเชฟเชถเซเชฒเซเชทเชฃเชพเชคเซเชฎเช เชเชฃเชคเชฐเซเช เชฎเชพเชเซ เชฌเชจเชพเชตเชพเชฏเซเชฒ เชเซ, เชคเซ เชฎเชพเชคเซเชฐ เชเชฐเซเชเซเชธเซเชเซเชฐเซเชถเชจ เชธเชพเชฅเซเชจเชพ เชธเชฐเซเชตเชฐเซเชธ เชชเชฐ เช เชจเชนเซเช, เชชเชฃ เชตเชฟเชตเชฟเชง เชธเซเชเซเชฐเชฟเชชเซเชเซ เชธเชพเชฅเซ เชชเชฃ เชเชพเชฒเซ เชเซ, เช
เชจเซ เชตเชฟเชถเซเชฒเซเชทเชเซเชจเชพ เชเชฎเซเชชเซเชฏเซเชเชฐเซเชธ เชชเชฐ เชเซเชฎเชจเซ เชเชพเชฎ เชเชฐเชตเชพเชจเซ เชเชฐเซเชฐ เชเซ. เช
เชจเซ เชฌเซเชเชเชจเซเชก เชธเชฎเชธเซเชฏเชพเชเชจเซ เชเชฟเชเชคเชพ เชเชฐเซเชฏเชพ เชตเชฟเชจเชพ เชเชเชฟเชฒ เชกเซเชเชพ เชชเซเชฐเซเชธเซเชธเชฟเชเช เชชเชพเชเชชเชฒเชพเชเชจเซเชธเชจเซ เชกเซเชฌเช เชเชฐเซ. เชฎเชพเชฐเซเช เชฆเซเชตเชพเชฐเชพ, เชฐเซเชชเชฐเซเชเชพ เชฒเซเชเชเช เชเซเชก เชธเชนเชฟเชค เช
เชฎเชพเชฐเชพ เชฎเซเชเซเชฏ เชธเชพเชงเชจเซ, เชเชจเชพ เชฆเซเชตเชพเชฐเชพ เชเชจเซเชธเซเชเซเชฒ เชเชฐเซเชฒเชพ เชเซ เชคเซ เชถเซเชฐ เชเชฐเชตเชพเชฎเชพเช เชจเซเชเชธเชพเชจ เชฅเชถเซ เชจเชนเซเช setup.py
- เชเชเชธเชพเชฅเซ เช เช
เชฎเชพเชฐเชพ เชเซเชกเชจเซ เชเช เช เชเชเซเชธเชฟเชธเซเชเชฎเชฎเชพเช เชเซเชกเซ เชเซ, เชเซ เชชเซเชฒเซเชเชซเซเชฐเซเชฎ เช
เชจเซ เชเชชเชฏเซเชเชจเซ เชชเชฆเซเชงเชคเชฟเชฅเซ เชธเซเชตเชคเชเชคเซเชฐ เชเซ.
เชเซเชฌเชฐเชจเซเชเซเชธ เชชเซเชกเชจเซเช เชตเชฐเซเชฃเชจ เชเชจเชพ เชเซเชตเซเช เชฒเชพเชเซ เชเซ:
containers:
- name : enter-api
image: enter-api:latest
ports:
- containerPort: 80
volumeMounts:
- name: db-main-secret-volume
mountPath: /etc/secrets/db-main
volumes:
- name: db-main-secret-volume
secret:
secretName: db-main-secret
เชเชเชฒเซ เชเซ, เชฆเชฐเซเช เชฐเชนเชธเซเชฏ เชเช เชตเชฟเชญเชพเชเชจเซเช เชตเชฐเซเชฃเชจ เชเชฐเซ เชเซ. เชฐเชนเชธเซเชฏเซ เชชเซเชคเชพเชจเซ เช เชฐเซเชคเซ เชฌเชจเชพเชตเชตเชพเชฎเชพเช เชเชตเซ เชเซ:
apiVersion: v1
kind: Secret
metadata:
name: db-main-secret
type: Opaque
stringData:
db_main.yaml: |
engine: sqlite
filename: main.sqlite3
เชเชเชธเชพเชฅเซ เช เชชเชพเชฅ เชธเชพเชฅเซ YAML เชซเชพเชเชฒเซเชจเชพ เชจเชฟเชฐเซเชฎเชพเชฃเชฎเชพเช เชชเชฐเชฟเชฃเชฎเซ เชเซ /etc/secrets/db-main/section_name.yaml
เช เชจเซ เชธเซเชฅเชพเชจเชฟเช เชฒเซเชเช เชฎเชพเชเซ, เชฐเซเชชเชฐเซเชเชพเชจเซ เชเชชเชฏเซเช เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เชเซ เชชเซเชฐเซเชเซเชเซเชเชจเซ เชฐเซเช เชกเชฟเชฐเซเชเซเชเชฐเซเชฎเชพเช เช เชฅเชตเชพ เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชตเซเชฐเซเชเชฌเชฒเชฎเชพเช เชเชฒเซเชฒเซเชเชฟเชค เชชเชพเชฅ เชธเชพเชฅเซ เชธเซเชฅเชฟเชค เชเซ. เช เชธเชเชตเชกเชคเชพเช เชฎเชพเชเซ เชเชตเชพเชฌเชฆเชพเชฐ เชเซเชก เชธเซเชชเซเชเชฒเชฐเชฎเชพเช เชเซเช เชถเชเชพเชฏ เชเซ.
config.py
__author__ = 'AivanF'
__copyright__ = 'Copyright 2020, AivanF'
import os
import yaml
__all__ = ['config']
PROJECT_DIR = os.path.abspath(__file__ + 3 * '/..')
SECRETS_DIR = '/etc/secrets'
KEY_LOG = '_config_log'
KEY_DBG = 'debug'
def is_yes(value):
if isinstance(value, str):
value = value.lower()
if value in ('1', 'on', 'yes', 'true'):
return True
else:
if value in (1, True):
return True
return False
def update_config_part(config, key, data):
if key not in config:
config[key] = data
else:
config[key].update(data)
def parse_big_config(config, filename):
'''
Parse YAML config with multiple section
'''
if not os.path.isfile(filename):
return False
with open(filename) as f:
config_new = yaml.safe_load(f.read())
for key, data in config_new.items():
update_config_part(config, key, data)
config[KEY_LOG].append(filename)
return True
def parse_tiny_config(config, key, filename):
'''
Parse YAML config with a single section
'''
with open(filename) as f:
config_tiny = yaml.safe_load(f.read())
update_config_part(config, key, config_tiny)
config[KEY_LOG].append(filename)
def combine_config():
config = {
# To debug config load code
KEY_LOG: [],
# To debug other code
KEY_DBG: is_yes(os.environ.get('DEBUG')),
}
# For simple local runs
CONFIG_SIMPLE = os.path.join(PROJECT_DIR, 'config.yaml')
parse_big_config(config, CONFIG_SIMPLE)
# For container's tests
CONFIG_ENVVAR = os.environ.get('CONFIG')
if CONFIG_ENVVAR is not None:
if not parse_big_config(config, CONFIG_ENVVAR):
raise ValueError(
f'No config file from EnvVar:n'
f'{CONFIG_ENVVAR}'
)
# For K8s secrets
for path, dirs, files in os.walk(SECRETS_DIR):
depth = path[len(SECRETS_DIR):].count(os.sep)
if depth > 1:
continue
for file in files:
if file.endswith('.yaml'):
filename = os.path.join(path, file)
key = file.rsplit('.', 1)[0]
parse_tiny_config(config, key, filename)
return config
def build_config():
config = combine_config()
# Preprocess
for key, data in config.items():
if key.startswith('db_'):
if data['engine'] == 'sqlite':
data['filename'] = os.path.join(PROJECT_DIR, data['filename'])
# To verify correctness
if config[KEY_DBG]:
print(f'** Loaded config:n{yaml.dump(config)}')
else:
print(f'** Loaded config from: {config[KEY_LOG]}')
return config
config = build_config()
เช เชนเซเชเชจเซ เชคเชฐเซเช เชเชเชฆเชฎ เชธเชฐเชณ เชเซ: เช เชฎเซ เชชเซเชฐเซเชเซเชเซเช เชกเชฟเชฐเซเชเซเชเชฐเซเชฎเชพเชเชฅเซ เชฎเซเชเซ เชฐเซเชชเชฐเซเชเชพเช เช เชจเซ เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชตเซเชฐเซเชเชฌเชฒ เชฆเซเชตเชพเชฐเชพ เชชเชพเชฅ, เช เชจเซ เชเซเชฌเซเชฐ เชธเชฟเชเซเชฐเซเชเซเชธเชจเชพ เชจเชพเชจเชพ เชฐเซเชชเชฐเซเชเชพ เชตเชฟเชญเชพเชเซเชจเซ เชเซเชกเซเช เชเซเช, เช เชจเซ เชชเชเซ เชคเซเชฎเชจเซ เชฅเซเชกเซ เชชเซเชฐเซเชชเซเชฐเซเชธเซเชธ เชเชฐเซเช เชเซเช. เชตเชคเซเชคเชพ เชเซเชเชฒเชพเช เชเชฒเซ. เชนเซเช เชจเซเชเชงเซเช เชเซเช เชเซ เชเซเชฏเชพเชฐเซ เชฐเชนเชธเซเชฏเซเชฎเชพเชเชฅเซ เชซเชพเชเชฒเซเชจเซ เชถเซเชง เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เชคเซเชฏเชพเชฐเซ เชเชเชกเชพเช เชฎเชฐเซเชฏเชพเชฆเชพเชจเซ เชเชชเชฏเซเช เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เชเชพเชฐเชฃ เชเซ K8s เชฆเชฐเซเช เชเซเชชเซเชคเชฎเชพเช เชเช เชเซเชชเชพเชฏเซเชฒ เชซเซเชฒเซเชกเชฐ เชฌเชจเชพเชตเซ เชเซ เชเซเชฏเชพเช เชฐเชนเชธเซเชฏเซ เชชเซเชคเชพเชจเซ เชธเชเชเซเชฐเชนเชฟเชค เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เช เชจเซ เชซเชเซเชค เชเช เชฒเชฟเชเช เชเชเซเช เชธเซเชคเชฐ เชชเชฐ เชธเซเชฅเชฟเชค เชเซ.
เชนเซเช เชเชถเชพ เชฐเชพเชเซเช เชเซเช เชเซ เชเซ เชตเชฐเซเชฃเชตเซเชฒ เชเซ เชคเซ เชเซเชเชจเซ เชเชชเชฏเซเชเซ เชฅเชถเซ :) เชธเซเชฐเชเซเชทเชพ เช เชฅเชตเชพ เชธเซเชงเชพเชฐเชฃเชพ เชฎเชพเชเซเชจเชพ เช เชจเซเชฏ เชเซเชทเซเชคเซเชฐเซเชจเซ เชฒเชเชคเซ เชเซเชเชชเชฃ เชเชฟเชชเซเชชเชฃเซเช เช เชจเซ เชญเชฒเชพเชฎเชฃเซ เชธเซเชตเซเชเชพเชฐเชตเชพเชฎเชพเช เชเชตเชถเซ. เชธเชฎเซเชฆเชพเชฏเชจเซ เช เชญเชฟเชชเซเชฐเชพเชฏ เชชเชฃ เชฐเชธเชชเซเชฐเชฆ เชเซ, เชเชฆเชพเช เชคเซ ConfigMaps (เช เชฎเชพเชฐเซ เชชเซเชฐเซเชเซเชเซเช เชนเชเซ เชคเซเชจเซ เชเชชเชฏเซเช เชเชฐเชคเซเช เชจเชฅเซ) เชฎเชพเชเซ เชธเชฎเชฐเซเชฅเชจ เชเชฎเซเชฐเชตเชพ เช เชจเซ GitHub / PyPI เชชเชฐ เชเซเชก เชชเซเชฐเชเชพเชถเชฟเชค เชเชฐเชตเชพ เชฏเซเชเซเชฏ เชเซ? เชตเซเชฏเชเซเชคเชฟเชเชค เชฐเซเชคเซ, เชฎเชจเซ เชฒเชพเชเซ เชเซ เชเซ เชชเซเชฐเซเชเซเชเซเชเซเชธ เชธเชพเชฐเซเชตเชคเซเชฐเชฟเช เชนเซเชตเชพ เชฎเชพเชเซ เชเชตเซ เชตเชธเซเชคเซเช เชเซเชฌ เช เชตเซเชฏเชเซเชคเชฟเชเชค เชเซ, เช เชจเซ เช เชจเซเชฏ เชฒเซเชเซเชจเชพ เช เชฎเชฒเซเชเชฐเชฃ เชชเชฐ เชฅเซเชกเซเช เชกเซเชเชฟเชฏเซเช เชเชฐเชตเซเช, เชเซเชฎ เชเซ เช เชนเซเช เชเชชเซเชฒ เชเซ, เช เชจเซ เชเซเชเชเชพเช, เชเซเชชเซเชธ เช เชจเซ เชถเซเชฐเซเชทเซเช เชชเชฆเซเชงเชคเชฟเชเชจเซ เชเชฐเซเชเชพ, เชเซ เชนเซเช เชเชฟเชชเซเชชเชฃเซเชเชฎเชพเช เชเซเชตเชพเชจเซ เชเชถเชพ เชฐเชพเชเซเช เชเซเช. , เชชเซเชฐเชคเซเช เชเซ ๐
เชซเชเซเชค เชจเซเชเชงเชพเชฏเซเชฒเชพ เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพเช เช เชธเชฐเซเชตเซเชฎเชพเช เชญเชพเช เชฒเช เชถเชเซ เชเซ.
เชถเซเช เชฎเชพเชฐเซ เชชเซเชฐเซเชเซเชเซเช/เชฒเชพเชเชฌเซเชฐเซเชฐเซ เชคเชฐเซเชเซ เชชเซเชฐเชเชพเชถเชฟเชค เชเชฐเชตเซเช เชเซเชเช?
-
0,0%เชนเชพ, เชนเซเช /contribution0 เชจเซ เชเชชเชฏเซเช เชเชฐเซเชถ
-
33,3%เชนเชพ, เชคเซ เชฎเชนเชพเชจ เชฒเชพเชเซ เชเซ4
-
41,7%เชจเชพ, เชเซเชฎเชฃเซ เชคเซเชจเซ เชชเซเชคเชพเชจเชพ เชซเซเชฐเซเชฎเซเชเชฎเชพเช เช เชจเซ เชคเซเชฎเชจเซ เชเชฐเซเชฐเชฟเชฏเชพเชคเซเชจเซ เช เชจเซเชฐเซเชช เชฌเชจเชพเชตเชตเชพเชจเซ เชเชฐเซเชฐ เชเซ5
-
25,0%เชนเซเช เชเชตเชพเชฌ เชเชชเชตเชพเชจเซเช เชเชพเชณเซเชถ3
12 เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพเชเช เชฎเชค โโเชเชชเซเชฏเซ. 3 เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพเช เชฆเซเชฐ เชฐเชนเซเชฏเชพ.
เชธเซเชฐเซเชธ: www.habr.com