рдореА рдиреБрдХрддреЗрдЪ рд▓рд┐рд╣рд┐рд▓реЗ
рдкреНрд░рд╢реНрдирд╛рдЪреА рдкрд╛рд░реНрд╢реНрд╡рднреВрдореА рдЕрд╢реА рдЖрд╣реЗ: рдПрдХреЗрдХрд╛рд│реА рдПрдХ рдкреНрд░рдХрд▓реНрдк рд╣реЛрддрд╛, рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛ рддреЛ рдпреБрдЯрд┐рд▓рд┐рдЯреАрдЬ рдЖрдгрд┐ рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕рд╕рд╣ рдПрдХ рд▓рд╣рд╛рди рдореЛрдиреЛрд▓рд┐рде рд╣реЛрддрд╛, рдкрд░рдВрддреБ рдХрд╛рд▓рд╛рдВрддрд░рд╛рдиреЗ рддреЛ рд╡рд╛рдврд▓рд╛, рд╕реЗрд╡рд╛рдВрдордзреНрдпреЗ рд╡рд┐рднрд╛рдЧрд▓рд╛ рдЧреЗрд▓рд╛, рдЬреНрдпрд╛рдпреЛрдЧреЗ рдорд╛рдпрдХреНрд░реЛрд╕рд░реНрд╡реНрд╣рд┐рд╕реЗрд╕рдордзреНрдпреЗ рд╡рд┐рднрд╛рдЧрд▓реЗ рдЬрд╛рдК рд▓рд╛рдЧрд▓реЗ рдЖрдгрд┐ рдирдВрддрд░ рд╕реНрдХреЗрд▓ рдХреЗрд▓реЗ. рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛, рд╣реЗ рд╕рд░реНрд╡ рдмреЗрдЕрд░ рд╡реНрд╣реАрдкреАрдПрд╕рд╡рд░ рдХреЗрд▓реЗ рдЧреЗрд▓реЗ, рдХреЛрдб рд╕реЗрдЯ рдЕрдк рдЖрдгрд┐ рдЙрдкрдпреЛрдЬрд┐рдд рдХрд░рдгреНрдпрд╛рдЪреНрдпрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬреНрдпрд╛рд╡рд░ 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 рдкреНрд░рддреНрдпреЗрдХ рдЧреБрдкреНрддрддреЗрдордзреНрдпреЗ рдПрдХ рд▓рдкрд▓реЗрд▓реЗ рдлреЛрд▓реНрдбрд░ рддрдпрд╛рд░ рдХрд░рддреЗ рдЬрд┐рдереЗ рд░рд╣рд╕реНрдпреЗ рд╕реНрд╡рддрдГрдЪ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХреЗрд▓реА рдЬрд╛рддрд╛рдд рдЖрдгрд┐ рдлрдХреНрдд рдПрдХ рджреБрд╡рд╛ рдЙрдЪреНрдЪ рд╕реНрддрд░рд╛рд╡рд░ рд╕реНрдерд┐рдд рдЕрд╕рддреЛ.
рдорд▓рд╛ рдЖрд╢рд╛ рдЖрд╣реЗ рдХреА рдЬреЗ рд╡рд░реНрдгрди рдХреЗрд▓реЗ рдЖрд╣реЗ рддреЗ рдПрдЦрд╛рджреНрдпрд╛рд╕рд╛рдареА рдЙрдкрдпреБрдХреНрдд рдард░реЗрд▓ :) рд╕реБрд░рдХреНрд╖рд╛ рдХрд┐рдВрд╡рд╛ рд╕реБрдзрд╛рд░рдгреЗрд╕рд╛рдареА рдЗрддрд░ рдХреНрд╖реЗрддреНрд░рд╛рдВрдмрджреНрджрд▓ рдХреЛрдгрддреНрдпрд╛рд╣реА рдЯрд┐рдкреНрдкрдгреНрдпрд╛ рдЖрдгрд┐ рд╢рд┐рдлрд╛рд░рд╕реА рд╕реНрд╡реАрдХрд╛рд░рд▓реНрдпрд╛ рдЬрд╛рддреАрд▓. рд╕рдореБрджрд╛рдпрд╛рдЪреЗ рдордд рджреЗрдЦреАрд▓ рдордиреЛрд░рдВрдЬрдХ рдЖрд╣реЗ, рдХрджрд╛рдЪрд┐рдд рдХреЙрдиреНрдлрд┐рдЧрдореЕрдкреНрд╕рд╕рд╛рдареА рд╕рдорд░реНрдерди рдЬреЛрдбрдгреЗ (рдЖрдордЪрд╛ рдкреНрд░рдХрд▓реНрдк рдЕрджреНрдпрд╛рдк рд╡рд╛рдкрд░рдд рдирд╛рд╣реА) рдЖрдгрд┐ GitHub / PyPI рд╡рд░ рдХреЛрдб рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдгреЗ рдпреЛрдЧреНрдп рдЖрд╣реЗ? рд╡реИрдпрдХреНрддрд┐рдХрд░рд┐рддреНрдпрд╛, рдорд▓рд╛ рдЕрд╕реЗ рд╡рд╛рдЯрддреЗ рдХреА рдкреНрд░рдХрд▓реНрдк рд╕рд╛рд░реНрд╡рддреНрд░рд┐рдХ рд╣реЛрдгреНрдпрд╛рд╕рд╛рдареА рдЕрд╢рд╛ рдЧреЛрд╖реНрдЯреА рдЦреВрдк рд╡реИрдпрдХреНрддрд┐рдХ рдЖрд╣реЗрдд рдЖрдгрд┐ рдЗрддрд░ рд▓реЛрдХрд╛рдВрдЪреНрдпрд╛ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрдХрдбреЗ рдереЛрдбреЗрд╕реЗ рдбреЛрдХрд╛рд╡реВрди рдкрд╛рд╣рдгреЗ, рдЬрд╕реЗ рдХреА рдпреЗрдереЗ рджрд┐рд▓реЗрд▓реЗ рдЖрд╣реЗ, рдЖрдгрд┐ рдмрд╛рд░рдХрд╛рд╡реЗ, рдЯрд┐рдкрд╛ рдЖрдгрд┐ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрджреНрдзрддреАрдВрдЪреА рдЪрд░реНрдЪрд╛, рдЬреА рдорд▓рд╛ рдЯрд┐рдкреНрдкрдгреНрдпрд╛рдВрдордзреНрдпреЗ рдкрд╛рд╣рдгреНрдпрд╛рдЪреА рдЖрд╢рд╛ рдЖрд╣реЗ. , рдкреБрд░реЗрд╕реЗ рдЖрд╣реЗ ЁЯШЙ
рдХреЗрд╡рд│ рдиреЛрдВрджрдгреАрдХреГрдд рд╡рд╛рдкрд░рдХрд░реНрддреЗрдЪ рд╕рд░реНрд╡реЗрдХреНрд╖рдгрд╛рдд рднрд╛рдЧ рдШреЗрдК рд╢рдХрддрд╛рдд.
рдореА рдкреНрд░рдХрд▓реНрдк/рд▓рд╛рдпрдмреНрд░рд░реА рдореНрд╣рдгреВрди рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рд╛рд╡реЗ рдХрд╛?
-
0,0%рд╣реЛрдп, рдореА /contribution0 рд╡рд╛рдкрд░реЗрди
-
33,3%рд╣реЛрдп, рддреЗ рдЫрд╛рди рд╡рд╛рдЯрддреЗ4
-
41,7%рдирд╛рд╣реА, рдЬреНрдпрд╛рдВрдирд╛ рддреЗ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рд╕реНрд╡рд░реБрдкрд╛рдд рдЖрдгрд┐ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рдЧрд░рдЬреЗрдиреБрд╕рд╛рд░ рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓5
-
25,0%рдореА рдЙрддреНрддрд░ рджреЗрдгреЗ рдЯрд╛рд│рддреЛ 3
12 рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдВрдиреА рдорддрджрд╛рди рдХреЗрд▓реЗ. 3 рд╡рд╛рдкрд░рдХрд░реНрддреЗ рджреВрд░ рд░рд╛рд╣рд┐рд▓реЗ.
рд╕реНрддреНрд░реЛрдд: www.habr.com