рднрд░реНрдЦрд░реИ рд▓реЗрдЦреЗрдХреЛ рдЫреБ
рдкреНрд░рд╢реНрдирдХреЛ рдкреГрд╖реНрдарднреВрдорд┐ рдпреЛ рд╣реЛ: рдХреБрдиреИ рд╕рдордп рддреНрдпрд╣рд╛рдБ рдПрдЙрдЯрд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдерд┐рдпреЛ, рд╕реБрд░реБрдорд╛ рдпреЛ рдЙрдкрдпреЛрдЧрд┐рддрд╛рд╣рд░реВ рд░ рд▓рд┐рдкрд┐рд╣рд░реВ рднрдПрдХреЛ рд╕рд╛рдиреЛ рдореЛрдиреЛрд▓рд┐рде рдерд┐рдпреЛ, рддрд░ рд╕рдордпрд╕рдБрдЧреИ рдпреЛ рдмрдвреНрджреИ рдЧрдпреЛ, рд╕реЗрд╡рд╛рд╣рд░реВрдорд╛ рд╡рд┐рднрд╛рдЬрд┐рдд рднрдпреЛ, рдЬреБрди рдлрд▓рд╕реНрд╡рд░реВрдк рд╕реВрдХреНрд╖реНрдо рд╕реЗрд╡рд╛рд╣рд░реВрдорд╛ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реБрди рдерд╛рд▓реНрдпреЛ, рд░ рддреНрдпрд╕рдкрдЫрд┐ рдорд╛рдкрди рдЧрд░рд┐рдпреЛред рд╕реБрд░реБрдорд╛, рдпреЛ рд╕рдмреИ рдмреЗрдпрд░ VPS рдорд╛ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ, рдХреЛрдб рд╕реЗрдЯрдЕрдк рд░ рдбрд┐рдкреНрд▓реЛрдп рдЧрд░реНрдиреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ рдЬрд╕рдорд╛ Ansible рдкреНрд░рдпреЛрдЧ рдЧрд░реА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдерд┐рдпреЛ, рд░ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛рд▓рд╛рдИ рдЖрд╡рд╢реНрдпрдХ рд╕реЗрдЯрд┐рдЩрд╣рд░реВ рд░ рдХреБрдЮреНрдЬреАрд╣рд░реВрд╕рдБрдЧ YAML рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рдирдХреЛ рд╕рд╛рде рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ, рд░ рдпрд╕реНрддреИ рдХрдиреНрдлрд┐рдЧ рдлрд╛рдЗрд▓рдХреЛ рд▓рд╛рдЧрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛред рд╕реНрдерд╛рдиреАрдп рдкреНрд░рдХреНрд╖реЗрдкрдгрд╣рд░реВ, рдЬреБрди рдзреЗрд░реИ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдерд┐рдпреЛ, рдХрд┐рдирднрдиреЗ .k рдпреЛ рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рд╡рд┐рд╢реНрд╡рд╡реНрдпрд╛рдкреА рд╡рд╕реНрддреБрдорд╛ рд▓реЛрдб рдЧрд░рд┐рдПрдХреЛ рдЫ, рдкрд░рд┐рдпреЛрдЬрдирд╛рдХреЛ рдХреБрдиреИ рдкрдирд┐ рдард╛рдЙрдБрдмрд╛рдЯ рдкрд╣реБрдБрдЪрдпреЛрдЧреНрдпред
рдпрджреНрдпрдкрд┐, рдорд╛рдЗрдХреНрд░реЛ рд╕реЗрд╡рд╛рд╣рд░реВрдХреЛ рд╕рдВрдЦреНрдпрд╛рдорд╛ рд╡реГрджреНрдзрд┐, рддрд┐рдиреАрд╣рд░реВрдХреЛ рдЬрдбрд╛рдирд╣рд░реВ, рд░
рдпрд╕ рд╕рдиреНрджрд░реНрднрдорд╛, рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рд╡рд╕реНрддреБ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрдиреЗ рд╕рдВрдпрдиреНрддреНрд░рд▓рд╛рдИ рд╣рд╛рдореНрд░реЛ рдХреНрд▓рд╛рд╕рд┐рдХ рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рдлрд╛рдЗрд▓ рд░ рдХреБрдмреЗрд░рдХрд╛ рдЧреЛрдкреНрдп рдХреБрд░рд╛рд╣рд░реВрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрди рд╕рдХреНрд╖рдо рдмрдирд╛рдЙрди рдкрд░рд┐рдорд╛рд░реНрдЬрди рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛред рдердк рдХрдареЛрд░ рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рд╕рдВрд░рдЪрдирд╛ рдкрдирд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ, рддреЗрд╕реНрд░реЛ рдкрд╛рдЗрдердирдХреЛ рднрд╛рд╖рд╛рдорд╛, рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░:
Dict[str, Dict[str, Union [str, int, float]]]
рддреНрдпреЛ рд╣реЛ, рдЕрдиреНрддрд┐рдо cogfig рдирд╛рдорд┐рдд рдЦрдгреНрдбрд╣рд░реВ рд╕рд╣рд┐рддрдХреЛ рд╢рдмреНрджрдХреЛрд╢ рд╣реЛ, рдЬрд╕рдордзреНрдпреЗ рдкреНрд░рддреНрдпреЗрдХ рд╕рд╛рдзрд╛рд░рдг рдкреНрд░рдХрд╛рд░рдХрд╛ рдорд╛рдирд╣рд░реВ рднрдПрдХреЛ рд╢рдмреНрджрдХреЛрд╢ рд╣реЛред рд░ рдЦрдгреНрдбрд╣рд░реВрд▓реЗ рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рд░ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░рдХрд╛ рд╕реНрд░реЛрддрд╣рд░реВрдорд╛ рдкрд╣реБрдБрдЪрдХреЛ рд╡рд░реНрдгрди рдЧрд░реНрджрдЫред рд╣рд╛рдореНрд░реЛ рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рди рдХреЛ рдПрдХ рдЯреБрдХреНрд░рд╛ рдХреЛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:
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
- рд╕рдБрдЧреИ рдпрд╕рд▓реЗ рд╣рд╛рдореНрд░реЛ рдХреЛрдбрд▓рд╛рдИ рдПрдХрд▓ рдЗрдХреЛрд╕рд┐рд╕реНрдЯрдордорд╛ рдПрдХрддрд╛рдмрджреНрдз рдЧрд░реНрджрдЫ, рдкреНрд▓реЗрдЯрдлрд░реНрдо рд░ рдкреНрд░рдпреЛрдЧрдХреЛ рд╡рд┐рдзрд┐рдмрд╛рдЯ рд╕реНрд╡рддрдиреНрддреНрд░ред
Kubernetes рдкреЛрдб рдХреЛ рд╡рд┐рд╡рд░рдг рдпрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдЫ:
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%рд╣реЛрдЗрди, рдХрд╕рд▓реЗ рдпрд╕рд▓рд╛рдИ рдЖрдлреНрдиреИ рдврд╛рдБрдЪрд╛рдорд╛ рд░ рддрд┐рдиреАрд╣рд░реВрдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрдиреБрд░реВрдк рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ
-
25,0%рдо рдЬрд╡рд╛рдл рджрд┐рдирдмрд╛рдЯ рдЯрд╛рдврд╛ рд░рд╣рдиреЗрдЫреБ 3
12 рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рд╣рд░реВрд▓реЗ рдорддрджрд╛рди рдЧрд░реЗред реи рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рд╣рд░реВ рд░реЛрдХрд┐рдПред
рд╕реНрд░реЛрдд: www.habr.com