āĻāĻŽāĻŋ āĻ¸āĻŽā§āĻĒā§āĻ°āĻ¤āĻŋ āĻ˛āĻŋāĻā§āĻāĻŋ
āĻĒā§āĻ°āĻļā§āĻ¨ā§āĻ° āĻĒāĻāĻā§āĻŽāĻŋ āĻāĻ: āĻāĻ āĻ¸āĻŽāĻ¯āĻŧ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻāĻ˛ā§āĻĒ āĻāĻŋāĻ˛, āĻĒā§āĻ°āĻĨāĻŽā§ āĻāĻāĻŋ āĻāĻāĻāĻŋāĻ˛āĻŋāĻāĻŋ āĻāĻŦāĻ āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻ āĻ¸āĻš āĻāĻāĻāĻŋ āĻā§āĻ āĻŽāĻ¨ā§āĻ˛āĻŋāĻĨ āĻāĻŋāĻ˛, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¸āĻŽāĻ¯āĻŧā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻžāĻĨā§ āĻāĻāĻŋ āĻŦā§āĻĄāĻŧā§āĻā§, āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ¤ā§ āĻŦāĻŋāĻāĻā§āĻ¤ āĻšāĻ¯āĻŧā§āĻā§, āĻ¯āĻž āĻĢāĻ˛āĻ¸ā§āĻŦāĻ°ā§āĻĒ āĻŽāĻžāĻāĻā§āĻ°ā§āĻ¸āĻžāĻ°ā§āĻāĻŋāĻ¸ā§ āĻŦāĻŋāĻāĻā§āĻ¤ āĻšāĻ¤ā§ āĻļā§āĻ°ā§ āĻāĻ°ā§āĻā§ āĻāĻŦāĻ āĻ¤āĻžāĻ°āĻĒāĻ° āĻ¸ā§āĻā§āĻ˛ āĻāĻĒ. āĻĒā§āĻ°āĻĨāĻŽā§, āĻāĻ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŦā§āĻ¯āĻŧāĻžāĻ° āĻāĻŋāĻĒāĻŋāĻāĻ¸-āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛, āĻā§āĻĄ āĻ¸ā§āĻ āĻāĻĒ āĻāĻŦāĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§āĻ˛āĻŋ āĻ¯āĻžāĻ° āĻāĻĒāĻ° 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
- āĻāĻāĻ¸āĻžāĻĨā§ āĻāĻāĻŋ āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻĄāĻā§ āĻāĻāĻāĻŋ āĻāĻāĻ āĻāĻā§āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§ āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻāĻ°ā§, āĻĒā§āĻ˛ā§āĻ¯āĻžāĻāĻĢāĻ°ā§āĻŽ āĻāĻŦāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§āĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻĨā§āĻā§ āĻ¸ā§āĻŦāĻžāĻ§ā§āĻ¨āĨ¤
āĻāĻāĻāĻŋ 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 āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§ āĻā§āĻ āĻĻāĻŋāĻ¯āĻŧā§āĻā§āĻ¨āĨ¤ 3 āĻāĻ¨ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§ āĻŦāĻŋāĻ°āĻ¤ āĻāĻŋāĻ˛ā§āĻ¨āĨ¤
āĻāĻ¤ā§āĻ¸: www.habr.com