แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ–แƒ” แƒแƒ แƒ˜แƒ”แƒœแƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒคแƒฃแƒซแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ–แƒ” S3 แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ Mail.ru Cloud Solutions

แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ–แƒ” แƒแƒ แƒ˜แƒ”แƒœแƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒคแƒฃแƒซแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ–แƒ” S3 แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ Mail.ru Cloud Solutions
Rube Goldberg แƒงแƒแƒ•แƒ˜แƒก แƒแƒžแƒแƒ แƒแƒขแƒ˜

แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ–แƒ” แƒแƒ แƒ˜แƒ”แƒœแƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ แƒ–แƒ แƒ“แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ แƒ”แƒกแƒฃแƒ แƒกแƒ”แƒ‘แƒ˜แƒก แƒฎแƒแƒ แƒฏแƒ”แƒ‘แƒ˜แƒก แƒ”แƒคแƒ”แƒฅแƒขแƒฃแƒ แƒแƒ‘แƒแƒก, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ˜แƒกแƒ˜แƒœแƒ˜ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ˜แƒ› แƒ›แƒแƒ›แƒ”แƒœแƒขแƒจแƒ˜, แƒ แƒแƒชแƒ แƒกแƒแƒญแƒ˜แƒ แƒแƒ. แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ˜, แƒ—แƒฃ แƒ แƒแƒ’แƒแƒ  แƒฃแƒœแƒ“แƒ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ“แƒ”แƒก แƒ”แƒก แƒ“แƒ แƒแƒ  แƒจแƒ”แƒฅแƒ›แƒœแƒแƒ— แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ˜แƒ—แƒ˜ แƒฆแƒ แƒฃแƒ‘แƒšแƒแƒ•แƒแƒœแƒ˜ แƒ”แƒ แƒ—แƒ”แƒฃแƒšแƒ”แƒ‘แƒ˜, แƒ แƒแƒ’แƒแƒ แƒช แƒ›แƒฃแƒจแƒ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜. แƒ“แƒ แƒ“แƒฆแƒ”แƒก แƒ›แƒ” แƒ•แƒ˜แƒกแƒแƒฃแƒ‘แƒ แƒ”แƒ‘ แƒแƒ แƒ FaaS-แƒ–แƒ”, แƒแƒ แƒแƒ›แƒ”แƒ“ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ–แƒ”. แƒ›แƒ” แƒ’แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ— แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ แƒ—แƒ•แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒก แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒก แƒ•แƒ”แƒ‘-แƒ™แƒแƒฃแƒฅแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—.

แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒกแƒ˜แƒขแƒงแƒ•แƒ แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒกแƒ แƒ“แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘. แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒจแƒ”แƒ˜แƒœแƒแƒฎแƒแƒ— แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ แƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ˜ แƒฆแƒ แƒฃแƒ‘แƒ”แƒšแƒจแƒ˜ แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ—, แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜ S3-แƒ˜แƒ— แƒแƒœ แƒกแƒฎแƒ•แƒ API-แƒ˜แƒ— (แƒ“แƒแƒ›แƒแƒ™แƒ˜แƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒแƒ–แƒ”) HTTP/HTTPS-แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—. Webhooks แƒ–แƒแƒ’แƒแƒ“แƒแƒ“ แƒแƒ แƒ˜แƒก แƒ›แƒแƒ แƒ’แƒ”แƒ‘แƒฃแƒšแƒ˜ HTTP แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ. แƒ˜แƒกแƒ˜แƒœแƒ˜, แƒ แƒแƒ’แƒแƒ แƒช แƒฌแƒ”แƒกแƒ˜, แƒ’แƒแƒ›แƒแƒฌแƒ•แƒ”แƒฃแƒšแƒ˜แƒ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒ—, แƒ แƒแƒ’แƒแƒ แƒ˜แƒชแƒแƒ แƒ™แƒแƒ“แƒ˜แƒก แƒ’แƒแƒ“แƒแƒขแƒแƒœแƒ แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ แƒแƒœ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒฅแƒ•แƒ”แƒงแƒœแƒ”แƒ‘แƒ แƒ‘แƒšแƒแƒ’แƒ–แƒ”. แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒฎแƒ“แƒ”แƒ‘แƒ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ, แƒกแƒแƒฌแƒงแƒ˜แƒกแƒ˜ แƒกแƒแƒ˜แƒขแƒ˜ แƒแƒ’แƒ–แƒแƒ•แƒœแƒ˜แƒก HTTP แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒก webhook-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒš URL-แƒ–แƒ”. แƒจแƒ”แƒ“แƒ”แƒ’แƒแƒ“, แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ›แƒแƒแƒฌแƒงแƒแƒ— แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ˜ แƒ”แƒ แƒ— แƒกแƒแƒ˜แƒขแƒ–แƒ”, แƒแƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ“แƒ”แƒก แƒ›แƒ”แƒแƒ แƒ”แƒ–แƒ” (แƒ•แƒ˜แƒ™แƒ˜). แƒ˜แƒ› แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒกแƒแƒฌแƒงแƒ˜แƒกแƒ˜ แƒกแƒแƒ˜แƒขแƒ˜ แƒแƒ แƒ˜แƒก แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒ˜, แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ˜ แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒก แƒ แƒแƒ’แƒแƒ แƒช แƒชแƒ•แƒšแƒ˜แƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜ แƒ›แƒ˜แƒก แƒจแƒ˜แƒœแƒแƒแƒ แƒกแƒจแƒ˜.

แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜ แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ”แƒ‘แƒ˜, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒแƒกแƒ”แƒ—แƒ˜ แƒแƒ•แƒขแƒแƒ›แƒแƒขแƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ:

  1. แƒงแƒ•แƒ”แƒšแƒ แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜แƒก แƒแƒกแƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ แƒกแƒฎแƒ•แƒ แƒฆแƒ แƒฃแƒ‘แƒšแƒแƒ•แƒแƒœ แƒกแƒแƒชแƒแƒ•แƒจแƒ˜. แƒแƒกแƒšแƒ”แƒ‘แƒ˜ แƒฃแƒœแƒ“แƒ แƒ˜แƒฅแƒ›แƒœแƒ”แƒ‘แƒ แƒ“แƒแƒฃแƒงแƒแƒ•แƒœแƒ”แƒ‘แƒšแƒ˜แƒ•, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜ แƒ“แƒแƒ”แƒ›แƒแƒขแƒ”แƒ‘แƒ แƒแƒœ แƒ˜แƒชแƒ•แƒšแƒ”แƒ‘แƒ.
  2. แƒ’แƒ แƒแƒคแƒ˜แƒ™แƒฃแƒšแƒ˜ แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒ”แƒกแƒ™แƒ˜แƒ–แƒ”แƒ‘แƒ˜แƒก แƒกแƒ”แƒ แƒ˜แƒ˜แƒก แƒแƒ•แƒขแƒแƒ›แƒแƒขแƒฃแƒ แƒ˜ แƒจแƒ”แƒฅแƒ›แƒœแƒ, แƒคแƒแƒขแƒแƒ”แƒ‘แƒ–แƒ” แƒฌแƒงแƒšแƒ˜แƒก แƒœแƒ˜แƒจแƒœแƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ แƒ“แƒ แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒกแƒฎแƒ•แƒ แƒชแƒ•แƒšแƒ˜แƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜.
  3. แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ แƒแƒฎแƒแƒšแƒ˜ แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒฉแƒแƒ›แƒแƒกแƒ•แƒšแƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ (แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ’แƒแƒœแƒแƒฌแƒ˜แƒšแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒแƒ‘แƒฃแƒฆแƒแƒšแƒขแƒ แƒ แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜ แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒแƒ•แƒก แƒแƒœแƒ’แƒแƒ แƒ˜แƒจแƒ”แƒ‘แƒก แƒฆแƒ แƒฃแƒ‘แƒ”แƒšแƒจแƒ˜ แƒ“แƒ แƒคแƒ˜แƒœแƒแƒœแƒกแƒฃแƒ แƒ˜ แƒ›แƒแƒœแƒ˜แƒขแƒแƒ แƒ˜แƒœแƒ’แƒ˜ แƒ˜แƒฆแƒ”แƒ‘แƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒก แƒแƒฎแƒแƒšแƒ˜ แƒแƒœแƒ’แƒแƒ แƒ˜แƒจแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘, แƒแƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒก แƒ“แƒ แƒแƒแƒœแƒแƒšแƒ˜แƒ–แƒ”แƒ‘แƒก แƒ›แƒแƒ—).
  4. แƒแƒ“แƒœแƒแƒ• แƒฃแƒคแƒ แƒ แƒ แƒ—แƒฃแƒšแƒ˜ แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ”แƒ‘แƒ˜ แƒ›แƒแƒ˜แƒชแƒแƒ•แƒก, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒ’แƒ”แƒœแƒ”แƒ แƒ˜แƒ แƒ”แƒ‘แƒแƒก Kubernetes-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฅแƒ›แƒœแƒ˜แƒก แƒžแƒแƒ“แƒก แƒกแƒแƒญแƒ˜แƒ แƒ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ”แƒ‘แƒ˜แƒ—, แƒ’แƒแƒ“แƒแƒกแƒชแƒ”แƒ›แƒก แƒ›แƒแƒก แƒแƒ›แƒแƒชแƒแƒœแƒ˜แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒก แƒ“แƒ แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ˜แƒจแƒšแƒ”แƒ‘แƒ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜.

แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ•แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ— แƒ“แƒแƒ•แƒแƒšแƒ”แƒ‘แƒ˜แƒก 1 แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒก, แƒ แƒแƒ“แƒ”แƒกแƒแƒช Mail.ru Cloud Solutions (MCS) แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒก แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒจแƒ˜ แƒชแƒ•แƒšแƒ˜แƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜ แƒกแƒ˜แƒœแƒฅแƒ แƒแƒœแƒ˜แƒ–แƒ“แƒ”แƒ‘แƒ AWS แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—. แƒ แƒ”แƒแƒšแƒฃแƒ  แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒฃแƒš แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒแƒกแƒ˜แƒœแƒฅแƒ แƒแƒœแƒฃแƒšแƒ˜ แƒกแƒแƒ›แƒฃแƒจแƒแƒ แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒฃแƒ–แƒ แƒฃแƒœแƒ•แƒ”แƒšแƒงแƒแƒคแƒ˜แƒšแƒ˜ แƒ•แƒ”แƒ‘-แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ˜แƒก แƒ แƒ˜แƒ’แƒจแƒ˜ แƒ“แƒแƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒ”แƒ‘แƒ˜แƒ—, แƒ›แƒแƒ’แƒ แƒแƒ› แƒกแƒแƒกแƒฌแƒแƒ•แƒšแƒ แƒ“แƒแƒ•แƒแƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒแƒก แƒแƒ›แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ” แƒ’แƒแƒ•แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ—.

แƒกแƒแƒ›แƒฃแƒจแƒแƒ แƒกแƒฅแƒ”แƒ›แƒ

แƒฃแƒ แƒ—แƒ˜แƒ”แƒ แƒ—แƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ˜แƒก แƒžแƒ แƒแƒขแƒแƒ™แƒแƒšแƒ˜ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“ แƒแƒ แƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ แƒ’แƒ–แƒแƒ›แƒ™แƒ•แƒšแƒ”แƒ•แƒ˜ S3 webhooks-แƒ–แƒ” MCS-แƒ–แƒ”. แƒกแƒแƒ›แƒฃแƒจแƒแƒ แƒกแƒฅแƒ”แƒ›แƒ แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ”แƒšแƒ”แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒก:

  • แƒกแƒแƒ’แƒแƒ›แƒแƒ›แƒชแƒ”แƒ›แƒšแƒ แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒ แƒ˜แƒก S3 แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒก แƒ›แƒฎแƒแƒ แƒ”แƒก แƒ“แƒ แƒแƒฅแƒ•แƒ”แƒงแƒœแƒ”แƒ‘แƒก HTTP แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒก, แƒ แƒแƒ“แƒ”แƒกแƒแƒช webnhook แƒแƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ“แƒ”แƒ‘แƒ.
  • Webhook แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฃแƒกแƒ›แƒ”แƒœแƒก HTTP แƒกแƒแƒ’แƒแƒ›แƒแƒ›แƒชแƒ”แƒ›แƒšแƒ แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜แƒก แƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒก แƒ“แƒ แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒก แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒก แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ”แƒ‘แƒก. แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ“แƒแƒ˜แƒฌแƒ”แƒ แƒแƒก แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ  แƒ”แƒœแƒแƒ–แƒ”; แƒฉแƒ•แƒ”แƒœแƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒจแƒ˜ แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒก Go-แƒจแƒ˜.

S3 API-แƒจแƒ˜ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒœแƒ”แƒ แƒ’แƒ•แƒ˜แƒก แƒ’แƒแƒœแƒกแƒแƒ™แƒฃแƒ—แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒฎแƒแƒกแƒ˜แƒแƒ—แƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒ แƒ’แƒแƒ›แƒแƒฅแƒ•แƒ”แƒงแƒœแƒ”แƒ‘แƒ˜แƒก แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ–แƒ”. แƒ™แƒ”แƒ แƒซแƒแƒ“, แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ›แƒ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ›แƒ แƒฃแƒœแƒ“แƒ แƒ“แƒแƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒแƒก แƒ’แƒแƒ›แƒแƒฅแƒ•แƒ”แƒงแƒœแƒ”แƒ‘แƒ˜แƒก แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜แƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒฎแƒ”แƒšแƒ›แƒแƒฌแƒ”แƒ แƒ (แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒกแƒฎแƒ•แƒ แƒ“แƒแƒœแƒ”แƒ แƒ’แƒ•แƒแƒจแƒ˜, แƒ แƒแƒ’แƒแƒ แƒช แƒฌแƒ”แƒกแƒ˜, แƒ’แƒแƒ›แƒแƒฌแƒ”แƒ แƒ˜แƒก แƒ“แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ”แƒ‘แƒ แƒแƒ  แƒแƒ แƒ˜แƒก แƒกแƒแƒญแƒ˜แƒ แƒ).

แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“, webhook แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒก แƒฃแƒœแƒ“แƒ แƒฐแƒฅแƒแƒœแƒ“แƒ”แƒก แƒแƒ แƒ˜ แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒ˜ แƒแƒžแƒ”แƒ แƒแƒชแƒ˜แƒ:

  • แƒฃแƒžแƒแƒกแƒฃแƒฎแƒ”แƒ— แƒกแƒแƒ’แƒแƒ›แƒแƒ›แƒชแƒ”แƒ›แƒšแƒ แƒกแƒแƒ›แƒกแƒแƒฎแƒฃแƒ แƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒก แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒ“แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘,
  • แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ.

แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ˜แƒœแƒกแƒขแƒแƒšแƒแƒชแƒ˜แƒ

แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ’แƒแƒกแƒแƒจแƒ•แƒ”แƒ‘แƒแƒ“ แƒ’แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ— Linux แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜. แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ— แƒ•แƒ˜แƒ แƒขแƒฃแƒแƒšแƒฃแƒ  แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒก, แƒ แƒแƒ›แƒ”แƒšแƒกแƒแƒช แƒ•แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ— MCS-แƒ–แƒ”.

แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒแƒ˜แƒœแƒกแƒขแƒแƒšแƒ˜แƒ แƒแƒ— แƒกแƒแƒญแƒ˜แƒ แƒ แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒฃแƒšแƒ˜ แƒฃแƒ–แƒ แƒฃแƒœแƒ•แƒ”แƒšแƒงแƒแƒคแƒ แƒ“แƒ แƒ’แƒแƒ•แƒฃแƒจแƒ•แƒแƒ— webhook แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜แƒก แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜.

ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install git
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  bc dns-root-data dnsmasq-base ebtables landscape-common liblxc-common 
liblxc1 libuv1 lxcfs lxd lxd-client python3-attr python3-automat 
python3-click python3-constantly python3-hyperlink
  python3-incremental python3-pam python3-pyasn1-modules 
python3-service-identity python3-twisted python3-twisted-bin 
python3-zope.interface uidmap xdelta3
Use 'sudo apt autoremove' to remove them.
Suggested packages:
  git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui 
gitk gitweb git-cvs git-mediawiki git-svn
The following NEW packages will be installed:
  git
0 upgraded, 1 newly installed, 0 to remove and 46 not upgraded.
Need to get 3915 kB of archives.
After this operation, 32.3 MB of additional disk space will be used.
Get:1 http://MS1.clouds.archive.ubuntu.com/ubuntu bionic-updates/main 
amd64 git amd64 1:2.17.1-1ubuntu0.7 [3915 kB]
Fetched 3915 kB in 1s (5639 kB/s)
Selecting previously unselected package git.
(Reading database ... 53932 files and directories currently installed.)
Preparing to unpack .../git_1%3a2.17.1-1ubuntu0.7_amd64.deb ...
Unpacking git (1:2.17.1-1ubuntu0.7) ...
Setting up git (1:2.17.1-1ubuntu0.7) ...

แƒกแƒแƒฅแƒแƒฆแƒแƒšแƒ“แƒ˜แƒก แƒ™แƒšแƒแƒœแƒ˜แƒ แƒ”แƒ‘แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒ—:

ubuntu@ubuntu-basic-1-2-10gb:~$ git clone
https://github.com/RomanenkoDenys/s3-webhook.git
Cloning into 's3-webhook'...
remote: Enumerating objects: 48, done.
remote: Counting objects: 100% (48/48), done.
remote: Compressing objects: 100% (27/27), done.
remote: Total 114 (delta 20), reused 45 (delta 18), pack-reused 66
Receiving objects: 100% (114/114), 23.77 MiB | 20.25 MiB/s, done.
Resolving deltas: 100% (49/49), done.

แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒ˜แƒฌแƒงแƒแƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜:

ubuntu@ubuntu-basic-1-2-10gb:~$ cd s3-webhook/
ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80

แƒ’แƒแƒ›แƒแƒ˜แƒฌแƒ”แƒ แƒ”แƒ— แƒกแƒแƒ’แƒแƒ›แƒแƒ›แƒชแƒ”แƒ›แƒšแƒ แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜

แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ“แƒแƒแƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒแƒ— แƒ—แƒฅแƒ•แƒ”แƒœแƒ˜ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ API-แƒก แƒแƒœ แƒ•แƒ”แƒ‘ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜แƒก แƒ›แƒ”แƒจแƒ•แƒ”แƒแƒ‘แƒ˜แƒ—. แƒกแƒ˜แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒ“แƒ”แƒ‘แƒ˜แƒ— แƒ•แƒ”แƒ‘ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—:

  1. แƒ›แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒ“แƒแƒ•แƒ˜แƒ“แƒ”แƒ— แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒงแƒแƒคแƒ˜แƒšแƒ”แƒ‘แƒแƒจแƒ˜ แƒกแƒแƒ™แƒแƒœแƒขแƒ แƒแƒšแƒ แƒแƒ—แƒแƒฎแƒจแƒ˜.
  2. แƒ’แƒแƒ“แƒแƒ“แƒ˜แƒ— แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ–แƒ”, แƒ แƒแƒ›แƒšแƒ˜แƒกแƒ—แƒ•แƒ˜แƒกแƒแƒช แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒแƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ˜แƒ แƒ”แƒ‘แƒ— แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒก แƒ“แƒ แƒ“แƒแƒแƒฌแƒ™แƒแƒžแƒฃแƒœแƒ”แƒ— แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒแƒ—แƒ แƒ™แƒแƒšแƒแƒคแƒ–แƒ”:

แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ–แƒ” แƒแƒ แƒ˜แƒ”แƒœแƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒคแƒฃแƒซแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ–แƒ” S3 แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ Mail.ru Cloud Solutions

แƒ’แƒแƒ“แƒแƒ“แƒ˜แƒ— Webhooks แƒฉแƒแƒœแƒแƒ แƒ—แƒ–แƒ” แƒ“แƒ แƒ“แƒแƒแƒฌแƒ™แƒแƒžแƒฃแƒœแƒ”แƒ— แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ:

แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ–แƒ” แƒแƒ แƒ˜แƒ”แƒœแƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒคแƒฃแƒซแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ–แƒ” S3 แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ Mail.ru Cloud Solutions
แƒจแƒ”แƒแƒ•แƒกแƒ”แƒ— แƒ•แƒ”แƒšแƒ”แƒ‘แƒ˜:

แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ–แƒ” แƒแƒ แƒ˜แƒ”แƒœแƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒคแƒฃแƒซแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ–แƒ” S3 แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ Mail.ru Cloud Solutions

ID - แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒ˜.

แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ - แƒ แƒแƒ›แƒ”แƒšแƒ˜ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒ. แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒแƒงแƒ”แƒœแƒ”แƒ— แƒงแƒ•แƒ”แƒšแƒ แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ˜แƒก แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฎแƒ“แƒ”แƒ‘แƒ แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ—แƒแƒœ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒกแƒแƒก (แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ แƒ“แƒ แƒฌแƒแƒจแƒšแƒ).

URL โ€” แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ˜.

แƒคแƒ˜แƒšแƒขแƒ แƒ˜แƒก แƒžแƒ แƒ”แƒคแƒ˜แƒฅแƒกแƒ˜/แƒกแƒฃแƒคแƒ˜แƒฅแƒกแƒ˜ แƒแƒ แƒ˜แƒก แƒคแƒ˜แƒšแƒขแƒ แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒจแƒ”แƒฅแƒ›แƒœแƒแƒ— แƒ•แƒ”แƒ‘-แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ˜ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ˜แƒ› แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ—แƒ แƒกแƒแƒฎแƒ”แƒšแƒ”แƒ‘แƒ˜ แƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒš แƒฌแƒ”แƒกแƒ”แƒ‘แƒก. แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ˜แƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ› webhook-แƒ›แƒ แƒแƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ“แƒ”แƒก แƒ›แƒฎแƒแƒšแƒแƒ“ แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜ .png แƒ’แƒแƒคแƒแƒ แƒ—แƒแƒ”แƒ‘แƒ˜แƒ—, in แƒคแƒ˜แƒšแƒขแƒ แƒ˜แƒก แƒกแƒฃแƒคแƒ˜แƒฅแƒกแƒ˜ แƒ—แƒฅแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒ“แƒแƒฌแƒ”แƒ แƒแƒ— "png".

แƒแƒ›แƒŸแƒแƒ›แƒแƒ“, แƒ›แƒฎแƒแƒšแƒแƒ“ 80 แƒ“แƒ 443 แƒžแƒแƒ แƒขแƒ”แƒ‘แƒ˜แƒ แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ˜แƒšแƒ˜ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ” แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒแƒญแƒ˜แƒ แƒแƒ— แƒ“แƒแƒแƒ›แƒแƒขแƒ”แƒ— แƒ™แƒแƒ™แƒแƒšแƒ˜ แƒ“แƒ แƒฉแƒ•แƒ”แƒœ แƒ•แƒœแƒแƒฎแƒแƒ•แƒ— แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒก:

แƒ›แƒแƒ•แƒšแƒ”แƒœแƒ”แƒ‘แƒ–แƒ” แƒแƒ แƒ˜แƒ”แƒœแƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒคแƒฃแƒซแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ–แƒ” S3 แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ Mail.ru Cloud Solutions
แƒฐแƒฃแƒ™แƒ›แƒ แƒ“แƒแƒแƒ›แƒแƒขแƒ.

แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒ—แƒแƒ•แƒ˜แƒก แƒŸแƒฃแƒ แƒœแƒแƒšแƒ”แƒ‘แƒจแƒ˜ แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒก Hook แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒ˜แƒก แƒ›แƒ˜แƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ”แƒแƒ‘แƒแƒก:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80
2020/06/15 12:01:14 [POST] incoming HTTP request from 
95.163.216.92:42530
2020/06/15 12:01:14 Got timestamp: 2020-06-15T15:01:13+03:00 TopicArn: 
mcs5259999770|myfiles-ash|s3:ObjectCreated:*,s3:ObjectRemoved:* Token: 
E2itMqAMUVVZc51pUhFWSp13DoxezvRxkUh5P7LEuk1dEe9y URL: 
http://89.208.199.220/webhook
2020/06/15 12:01:14 Generate responce signature: 
3754ce36636f80dfd606c5254d64ecb2fd8d555c27962b70b4f759f32c76b66d

แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒ แƒ“แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ. แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ’แƒแƒœแƒงแƒแƒคแƒ˜แƒšแƒ”แƒ‘แƒแƒจแƒ˜ แƒฃแƒคแƒ แƒ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“ แƒ’แƒแƒœแƒ•แƒ˜แƒฎแƒ˜แƒšแƒแƒ•แƒ— webhook-แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒก แƒแƒšแƒ’แƒแƒ แƒ˜แƒ—แƒ›แƒก.

แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒ

แƒฉแƒ•แƒ”แƒœแƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒจแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒ˜แƒฌแƒ”แƒ แƒ”แƒ‘แƒ Go-แƒจแƒ˜. แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒฎแƒ”แƒ“แƒแƒ— แƒ›แƒ˜แƒกแƒ˜ แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ˜แƒก แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“ แƒžแƒ แƒ˜แƒœแƒชแƒ˜แƒžแƒ”แƒ‘แƒก.

package main

// Generate hmac_sha256_hex
func HmacSha256hex(message string, secret string) string {
}

// Generate hmac_sha256
func HmacSha256(message string, secret string) string {
}

// Send subscription confirmation
func SubscriptionConfirmation(w http.ResponseWriter, req *http.Request, body []byte) {
}

// Send subscription confirmation
func GotRecords(w http.ResponseWriter, req *http.Request, body []byte) {
}

// Liveness probe
func Ping(w http.ResponseWriter, req *http.Request) {
    // log request
    log.Printf("[%s] incoming HTTP Ping request from %sn", req.Method, req.RemoteAddr)
    fmt.Fprintf(w, "Pongn")
}

//Webhook
func Webhook(w http.ResponseWriter, req *http.Request) {
}

func main() {

    // get command line args
    bindPort := flag.Int("port", 80, "number between 1-65535")
    bindAddr := flag.String("address", "", "ip address in dot format")
    flag.StringVar(&actionScript, "script", "", "external script to execute")
    flag.Parse()

    http.HandleFunc("/ping", Ping)
    http.HandleFunc("/webhook", Webhook)

log.Fatal(http.ListenAndServe(*bindAddr+":"+strconv.Itoa(*bindPort), nil))
}

แƒ’แƒแƒœแƒ•แƒ˜แƒฎแƒ˜แƒšแƒแƒ— แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜:

  • Ping() - แƒ›แƒแƒ แƒจแƒ แƒฃแƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒžแƒแƒกแƒฃแƒฎแƒแƒ‘แƒก URL/แƒžแƒ˜แƒœแƒ’แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—, แƒชแƒแƒชแƒฎแƒแƒšแƒ˜ แƒ–แƒแƒœแƒ“แƒ˜แƒก แƒฃแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒกแƒ˜ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ.
  • Webhook() - แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜ แƒ›แƒแƒ แƒจแƒ แƒฃแƒขแƒ˜, URL/แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ”แƒšแƒ˜:
    • แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ”แƒ‘แƒก แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒแƒก แƒ’แƒแƒ›แƒแƒฅแƒ•แƒ”แƒงแƒœแƒ”แƒ‘แƒ˜แƒก แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ–แƒ” (แƒ’แƒแƒ“แƒแƒ“แƒ˜แƒ— SubscriptionConfirmation แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒ–แƒ”),
    • แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒก แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒš แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒก (Gorecords แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ).
  • แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜ HmacSha256 แƒ“แƒ HmacSha256hex แƒแƒ แƒ˜แƒก HMAC-SHA256 แƒ“แƒ HMAC-SHA256 แƒ“แƒแƒจแƒ˜แƒคแƒ•แƒ แƒ˜แƒก แƒแƒšแƒ’แƒแƒ แƒ˜แƒ—แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ, แƒ’แƒแƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜, แƒ แƒแƒ’แƒแƒ แƒช แƒ—แƒ”แƒฅแƒ•แƒกแƒ›แƒ”แƒขแƒแƒ‘แƒ˜แƒ—แƒ˜ แƒ แƒ˜แƒชแƒฎแƒ•แƒ”แƒ‘แƒ˜แƒก แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ˜ แƒฎแƒ”แƒšแƒ›แƒแƒฌแƒ”แƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒกแƒแƒ—แƒ•แƒšแƒ”แƒšแƒแƒ“.
  • main แƒแƒ แƒ˜แƒก แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ, แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒก แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒฎแƒแƒ–แƒ˜แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒก แƒ“แƒ แƒแƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒ”แƒ‘แƒก URL-แƒ˜แƒก แƒ“แƒแƒ›แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒšแƒ”แƒ‘แƒก.

แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒฎแƒแƒ–แƒ˜แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜:

  • -แƒžแƒแƒ แƒขแƒ˜ แƒแƒ แƒ˜แƒก แƒžแƒแƒ แƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ–แƒ”แƒช แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒ›แƒแƒฃแƒกแƒ›แƒ”แƒœแƒก.
  • -address - IP แƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒกแƒแƒช แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒ›แƒแƒฃแƒกแƒ›แƒ”แƒœแƒก.
  • -แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒแƒ แƒ˜แƒก แƒ’แƒแƒ แƒ” แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ›แƒแƒ˜แƒซแƒแƒฎแƒ”แƒ‘แƒ แƒงแƒแƒ•แƒ”แƒšแƒ˜ แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ แƒ™แƒแƒฃแƒญแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒ›แƒแƒ“แƒ˜แƒ— แƒฃแƒคแƒ แƒ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“ แƒ’แƒแƒœแƒ•แƒ˜แƒฎแƒ˜แƒšแƒแƒ— แƒ–แƒแƒ’แƒ˜แƒ”แƒ แƒ—แƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ:

//Webhook
func Webhook(w http.ResponseWriter, req *http.Request) {

    // Read body
    body, err := ioutil.ReadAll(req.Body)
    defer req.Body.Close()
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    // log request
    log.Printf("[%s] incoming HTTP request from %sn", req.Method, req.RemoteAddr)
    // check if we got subscription confirmation request
    if strings.Contains(string(body), 
""Type":"SubscriptionConfirmation"") {
        SubscriptionConfirmation(w, req, body)
    } else {
        GotRecords(w, req, body)
    }

}

แƒ”แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒ’แƒแƒœแƒกแƒแƒ–แƒฆแƒ•แƒ แƒแƒ•แƒก แƒ›แƒแƒ•แƒ˜แƒ“แƒ แƒ—แƒฃ แƒแƒ แƒ แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒ“แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒแƒœ แƒ•แƒ”แƒ‘-แƒฐแƒฃแƒ™แƒ˜. แƒ แƒแƒ’แƒแƒ แƒช แƒ˜แƒ แƒ™แƒ•แƒ”แƒ•แƒ แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒแƒ—แƒฃ แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒ แƒ“แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ“แƒ, แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ Json แƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒ แƒ›แƒ˜แƒ˜แƒฆแƒ”แƒ‘แƒ Post แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜:

POST http://test.com HTTP/1.1
x-amz-sns-messages-type: SubscriptionConfirmation
content-type: application/json

{
    "Timestamp":"2019-12-26T19:29:12+03:00",
    "Type":"SubscriptionConfirmation",
    "Message":"You have chosen to subscribe to the topic $topic. To confirm the subscription you need to response with calculated signature",
    "TopicArn":"mcs2883541269|bucketA|s3:ObjectCreated:Put",
    "SignatureVersion":1,
    "Token":ยซRPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tAยป
}

แƒแƒ› แƒ™แƒ˜แƒ—แƒฎแƒ•แƒแƒ–แƒ” แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒก แƒ’แƒแƒชแƒ”แƒ›แƒแƒ แƒกแƒแƒญแƒ˜แƒ แƒ:

content-type: application/json

{"signature":ยซea3fce4bb15c6de4fec365d36bcebbc34ccddf54616d5ca12e1972f82b6d37afยป}

แƒกแƒแƒ“แƒแƒช แƒฎแƒ”แƒšแƒ›แƒแƒฌแƒ”แƒ แƒ แƒ’แƒแƒ›แƒแƒ˜แƒ—แƒ•แƒšแƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒœแƒแƒ˜แƒ แƒแƒ“:

signature = hmac_sha256(url, hmac_sha256(TopicArn, 
hmac_sha256(Timestamp, Token)))

แƒ—แƒฃ webhook แƒฉแƒแƒ›แƒแƒ•แƒ, Post แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒ แƒแƒกแƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒ:

POST <url> HTTP/1.1
x-amz-sns-messages-type: SubscriptionConfirmation

{ "Records":
    [
        {
            "s3": {
                "object": {
                    "eTag":"aed563ecafb4bcc5654c597a421547b2",
                    "sequencer":1577453615,
                    "key":"some-file-to-bucket",
                    "size":100
                },
            "configurationId":"1",
            "bucket": {
                "name": "bucketA",
                "ownerIdentity": {
                    "principalId":"mcs2883541269"}
                },
                "s3SchemaVersion":"1.0"
            },
            "eventVersion":"1.0",
            "requestParameters":{
                "sourceIPAddress":"185.6.245.156"
            },
            "userIdentity": {
                "principalId":"2407013e-cbc1-415f-9102-16fb9bd6946b"
            },
            "eventName":"s3:ObjectCreated:Put",
            "awsRegion":"ru-msk",
            "eventSource":"aws:s3",
            "responseElements": {
                "x-amz-request-id":"VGJR5rtJ"
            }
        }
    ]
}

แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“, แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒ“แƒแƒœ แƒ’แƒแƒ›แƒแƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ”, แƒ—แƒฅแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒ’แƒ”แƒกแƒ›แƒแƒ“แƒ”แƒ—, แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒแƒ›แƒฃแƒจแƒแƒ•แƒแƒ— แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜. แƒ˜แƒœแƒ“แƒ˜แƒ™แƒแƒขแƒแƒ แƒแƒ“ แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ˜ แƒแƒ•แƒ˜แƒ แƒฉแƒ˜แƒ” "Type":"SubscriptionConfirmation", แƒ แƒแƒ“แƒ’แƒแƒœ แƒ˜แƒก แƒ˜แƒ›แƒงแƒแƒคแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒฌแƒ”แƒ แƒ˜แƒก แƒ“แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜ แƒ“แƒ แƒแƒ  แƒแƒ แƒ˜แƒก แƒ•แƒ”แƒ‘-แƒฐแƒฃแƒ™แƒจแƒ˜. POST แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜ แƒแƒ› แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒ˜แƒก/แƒแƒ แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒ˜แƒก แƒกแƒแƒคแƒฃแƒซแƒ•แƒ”แƒšแƒ–แƒ”, แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ’แƒแƒ›แƒ˜ แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ“แƒแƒ“แƒ˜แƒก แƒแƒœ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒ–แƒ” SubscriptionConfirmation, แƒแƒœ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒจแƒ˜ GotRecords.

แƒฉแƒ•แƒ”แƒœ แƒแƒ  แƒ’แƒแƒœแƒ•แƒ˜แƒฎแƒ˜แƒšแƒแƒ•แƒ— SubscriptionConfirmation แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒก แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“; แƒ˜แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ–แƒ”แƒ›แƒแƒแƒฆแƒœแƒ˜แƒจแƒœแƒฃแƒšแƒ˜ แƒžแƒ แƒ˜แƒœแƒชแƒ˜แƒžแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“. แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ. แƒแƒ› แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒฌแƒงแƒแƒ แƒแƒก แƒ™แƒแƒ“แƒ˜แƒก แƒœแƒแƒฎแƒ•แƒ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒแƒฅ แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜แƒก git แƒกแƒแƒชแƒแƒ•แƒ˜.

GotRecords แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒแƒแƒœแƒแƒšแƒ˜แƒ–แƒ”แƒ‘แƒก แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒš แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒก แƒ“แƒ แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ˜แƒซแƒแƒฎแƒ”แƒ‘แƒก แƒ’แƒแƒ แƒ” แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒก (แƒ แƒแƒ›แƒšแƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ“แƒแƒ”แƒชแƒ -script แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒจแƒ˜) แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜แƒ—:

  • แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒ˜
  • แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ˜แƒก แƒ’แƒแƒกแƒแƒฆแƒ”แƒ‘แƒ˜
  • แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒ:
    • แƒ™แƒแƒžแƒ˜แƒ แƒ”แƒ‘แƒ - แƒ—แƒฃ แƒ—แƒแƒ•แƒ“แƒแƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜ EventName = ObjectCreated | PutObject | PutObjectCopy
    • แƒฌแƒแƒจแƒšแƒ - แƒ—แƒฃ แƒ—แƒแƒ•แƒ“แƒแƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒจแƒ˜ EventName = ObjectRemoved | DeleteObject

แƒแƒ›แƒ แƒ˜แƒ’แƒแƒ“, แƒ—แƒฃ แƒฐแƒฃแƒ™แƒ˜ แƒฉแƒแƒ›แƒแƒ•แƒ Post-แƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒ—, แƒ แƒแƒ’แƒแƒ แƒช แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜แƒ แƒ–แƒ”แƒ›แƒแƒ—, แƒ“แƒ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜ -script=script.sh แƒ›แƒแƒจแƒ˜แƒœ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒ’แƒแƒ›แƒแƒ˜แƒซแƒแƒฎแƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒœแƒแƒ˜แƒ แƒแƒ“:

script.sh  bucketA some-file-to-bucket copy

แƒฃแƒœแƒ“แƒ แƒ’แƒ•แƒ”แƒกแƒ›แƒแƒ“แƒ”แƒก, แƒ แƒแƒ› แƒ”แƒก webhook แƒ›แƒ˜แƒ›แƒฆแƒ”แƒ‘แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒแƒ  แƒแƒ แƒ˜แƒก แƒกแƒ แƒฃแƒšแƒ˜ แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ“แƒแƒฌแƒงแƒ•แƒ”แƒขแƒ, แƒแƒ แƒแƒ›แƒ”แƒ“ แƒจแƒ”แƒกแƒแƒซแƒšแƒ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜.

แƒกแƒแƒ›แƒฃแƒจแƒแƒแƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜

แƒ›แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒ•แƒแƒกแƒ˜แƒœแƒฅแƒ แƒแƒœแƒแƒ— แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜ MCS-แƒ˜แƒก แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜ แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ˜แƒ“แƒแƒœ AWS-แƒ˜แƒก แƒกแƒแƒ แƒ”แƒ–แƒ”แƒ แƒ•แƒ แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒแƒ›แƒ“แƒ”. แƒ›แƒ—แƒแƒ•แƒแƒ  แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒก แƒ”แƒฌแƒแƒ“แƒ”แƒ‘แƒ myfiles-ash, แƒกแƒแƒ แƒ”แƒ–แƒ”แƒ แƒ•แƒแƒก - myfiles-backup (แƒ•แƒ”แƒ“แƒ แƒแƒก แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ AWS-แƒจแƒ˜ แƒกแƒชแƒ˜แƒšแƒ“แƒ”แƒ‘แƒ แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒคแƒแƒ แƒ’แƒšแƒ”แƒ‘แƒก). แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒคแƒแƒ˜แƒšแƒ˜ แƒ›แƒแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ›แƒ—แƒแƒ•แƒแƒ  แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒจแƒ˜, แƒ›แƒ˜แƒกแƒ˜ แƒแƒกแƒšแƒ˜ แƒฃแƒœแƒ“แƒ แƒ’แƒแƒ›แƒแƒฉแƒœแƒ“แƒ”แƒก แƒกแƒแƒ แƒ”แƒ–แƒ”แƒ แƒ•แƒแƒจแƒ˜, แƒฎแƒแƒšแƒ แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒฌแƒแƒจแƒšแƒ˜แƒšแƒ˜แƒ แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒ˜แƒ“แƒแƒœ, แƒฌแƒแƒ˜แƒจแƒšแƒ”แƒ‘แƒ แƒกแƒแƒ แƒ”แƒ–แƒ”แƒ แƒ•แƒแƒจแƒ˜.

แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ— แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ”แƒ‘แƒ—แƒแƒœ awscli แƒฃแƒขแƒ˜แƒšแƒ˜แƒขแƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒแƒ“แƒ˜แƒ แƒ แƒแƒ’แƒแƒ แƒช MCS แƒฆแƒ แƒฃแƒ‘แƒšแƒแƒ•แƒแƒœ แƒกแƒแƒชแƒแƒ•แƒ—แƒแƒœ, แƒแƒกแƒ”แƒ•แƒ” AWS แƒฆแƒ แƒฃแƒ‘แƒšแƒแƒ•แƒแƒœ แƒกแƒแƒชแƒแƒ•แƒ—แƒแƒœ.

ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install awscli
Reading package lists... Done
Building dependency tree
Reading state information... Done
After this operation, 34.4 MB of additional disk space will be used.
Unpacking awscli (1.14.44-1ubuntu1) ...
Setting up awscli (1.14.44-1ubuntu1) ...

แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒแƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ˜แƒ แƒแƒ— แƒฌแƒ•แƒ“แƒแƒ›แƒ S3 MCS API-แƒ–แƒ”:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile mcs
AWS Access Key ID [None]: hdywEPtuuJTExxxxxxxxxxxxxx
AWS Secret Access Key [None]: hDz3SgxKwXoxxxxxxxxxxxxxxxxxx
Default region name [None]:
Default output format [None]:

แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒแƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ˜แƒ แƒแƒ— แƒฌแƒ•แƒ“แƒแƒ›แƒ AWS S3 API-แƒ–แƒ”:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile aws
AWS Access Key ID [None]: AKIAJXXXXXXXXXXXX
AWS Secret Access Key [None]: dfuerphOLQwu0CreP5Z8l5fuXXXXXXXXXXXXXXXX
Default region name [None]:
Default output format [None]:

แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒแƒ›แƒแƒฌแƒ›แƒแƒ— แƒฌแƒ•แƒ“แƒแƒ›แƒ:

AWS-แƒ–แƒ”:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile aws
2020-07-06 08:44:11 myfiles-backup

MCS-แƒกแƒ—แƒ•แƒ˜แƒก, แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ˜แƒกแƒแƒก แƒ—แƒฅแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒ“แƒแƒแƒ›แƒแƒขแƒแƒ— โ€”endpoint-url:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile mcs --endpoint-url 
https://hb.bizmrg.com
2020-02-04 06:38:05 databasebackups-0cdaaa6402d4424e9676c75a720afa85
2020-05-27 10:08:33 myfiles-ash

แƒฌแƒ•แƒ“แƒแƒ›แƒ.

แƒแƒฎแƒšแƒ แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒแƒ— แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ แƒฐแƒฃแƒ™แƒ˜แƒก แƒ“แƒแƒกแƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒšแƒแƒ“, แƒ“แƒแƒ•แƒแƒ แƒฅแƒ•แƒแƒ— แƒ›แƒแƒก s3_backup_mcs_aws.sh

#!/bin/bash
# Require aws cli
# if file added โ€” copy it to backup bucket
# if file removed โ€” remove it from backup bucket
# Variables
ENDPOINT_MCS="https://hb.bizmrg.com"
AWSCLI_MCS=`which aws`" --endpoint-url ${ENDPOINT_MCS} --profile mcs s3"
AWSCLI_AWS=`which aws`" --profile aws s3"
BACKUP_BUCKET="myfiles-backup"

SOURCE_BUCKET=""
SOURCE_FILE=""
ACTION=""

SOURCE="s3://${SOURCE_BUCKET}/${SOURCE_FILE}"
TARGET="s3://${BACKUP_BUCKET}/${SOURCE_FILE}"
TEMP="/tmp/${SOURCE_BUCKET}/${SOURCE_FILE}"

case ${ACTION} in
    "copy")
    ${AWSCLI_MCS} cp "${SOURCE}" "${TEMP}"
    ${AWSCLI_AWS} cp "${TEMP}" "${TARGET}"
    rm ${TEMP}
    ;;

    "delete")
    ${AWSCLI_AWS} rm ${TARGET}
    ;;

    *)
    echo "Usage: 
#!/bin/bash
# Require aws cli
# if file added โ€” copy it to backup bucket
# if file removed โ€” remove it from backup bucket
# Variables
ENDPOINT_MCS="https://hb.bizmrg.com"
AWSCLI_MCS=`which aws`" --endpoint-url ${ENDPOINT_MCS} --profile mcs s3"
AWSCLI_AWS=`which aws`" --profile aws s3"
BACKUP_BUCKET="myfiles-backup"
SOURCE_BUCKET="${1}"
SOURCE_FILE="${2}"
ACTION="${3}"
SOURCE="s3://${SOURCE_BUCKET}/${SOURCE_FILE}"
TARGET="s3://${BACKUP_BUCKET}/${SOURCE_FILE}"
TEMP="/tmp/${SOURCE_BUCKET}/${SOURCE_FILE}"
case ${ACTION} in
"copy")
${AWSCLI_MCS} cp "${SOURCE}" "${TEMP}"
${AWSCLI_AWS} cp "${TEMP}" "${TARGET}"
rm ${TEMP}
;;
"delete")
${AWSCLI_AWS} rm ${TARGET}
;;
*)
echo "Usage: ${0} sourcebucket sourcefile copy/delete"
exit 1
;;
esac
sourcebucket sourcefile copy/delete" exit 1 ;; esac

แƒ›แƒแƒ“แƒ˜แƒ— แƒ“แƒแƒ•แƒ˜แƒฌแƒงแƒแƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80 -
script scripts/s3_backup_mcs_aws.sh

แƒ•แƒœแƒแƒฎแƒแƒ—, แƒ แƒแƒ’แƒแƒ  แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก. แƒ›แƒ”แƒจแƒ•แƒ”แƒแƒ‘แƒ˜แƒ— MCS แƒ•แƒ”แƒ‘ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜ แƒ“แƒแƒแƒ›แƒแƒขแƒ”แƒ— test.txt แƒคแƒแƒ˜แƒšแƒ˜ myfiles-ash bucket-แƒจแƒ˜. แƒ™แƒแƒœแƒกแƒแƒšแƒ˜แƒก แƒŸแƒฃแƒ แƒœแƒแƒšแƒ”แƒ‘แƒ˜ แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒก, แƒ แƒแƒ› แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ“แƒ webhook แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ”:

2020/07/06 09:43:08 [POST] incoming HTTP request from 
95.163.216.92:56612
download: s3://myfiles-ash/test.txt to ../../../tmp/myfiles-ash/test.txt
upload: ../../../tmp/myfiles-ash/test.txt to 
s3://myfiles-backup/test.txt

แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒแƒ›แƒแƒฌแƒ›แƒแƒ— myfiles-แƒก แƒกแƒแƒ แƒ”แƒ–แƒ”แƒ แƒ•แƒ แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ˜แƒก แƒจแƒ˜แƒœแƒแƒแƒ แƒกแƒ˜ AWS-แƒจแƒ˜:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls 
myfiles-backup
2020-07-06 09:43:10       1104 test.txt

แƒแƒฎแƒšแƒ, แƒ•แƒ”แƒ‘ แƒ˜แƒœแƒขแƒ”แƒ แƒคแƒ”แƒ˜แƒกแƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—, แƒฉแƒ•แƒ”แƒœ แƒฌแƒแƒ•แƒจแƒšแƒ˜แƒ— แƒคแƒแƒ˜แƒšแƒก myfiles-ash bucket-แƒ˜แƒ“แƒแƒœ.

แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒŸแƒฃแƒ แƒœแƒแƒšแƒ”แƒ‘แƒ˜:

2020/07/06 09:44:46 [POST] incoming HTTP request from 
95.163.216.92:58224
delete: s3://myfiles-backup/test.txt

แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ˜แƒก แƒจแƒ˜แƒ’แƒ—แƒแƒ•แƒกแƒ˜:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls 
myfiles-backup
ubuntu@ubuntu-basic-1-2-10gb:~$

แƒคแƒแƒ˜แƒšแƒ˜ แƒฌแƒแƒจแƒšแƒ˜แƒšแƒ˜แƒ, แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ แƒ›แƒแƒ’แƒ•แƒแƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ.

แƒ“แƒแƒกแƒ™แƒ•แƒœแƒ แƒ“แƒ แƒ“แƒแƒ•แƒแƒšแƒ”แƒ‘แƒ

แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒงแƒ•แƒ”แƒšแƒ แƒ™แƒแƒ“แƒ˜ แƒแƒ แƒ˜แƒก แƒฉแƒ”แƒ›แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜. แƒแƒกแƒ”แƒ•แƒ” แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ”แƒ‘แƒ˜ แƒ“แƒ แƒฎแƒ”แƒšแƒ›แƒแƒฌแƒ”แƒ แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ—แƒ•แƒšแƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ”แƒ‘แƒ˜ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ˜แƒก แƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒ”แƒก แƒ™แƒแƒ“แƒ˜ แƒกแƒฎแƒ•แƒ แƒแƒ แƒแƒคแƒ”แƒ แƒ˜แƒ, แƒ—แƒฃ แƒแƒ แƒ แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜ แƒ˜แƒ›แƒ˜แƒกแƒ, แƒ—แƒฃ แƒ แƒแƒ’แƒแƒ  แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒ— S3 แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ˜ แƒ—แƒฅแƒ•แƒ”แƒœแƒก แƒกแƒแƒฅแƒ›แƒ˜แƒแƒœแƒแƒ‘แƒแƒจแƒ˜. แƒ แƒแƒ’แƒแƒ แƒช แƒ“แƒแƒกแƒแƒฌแƒงแƒ˜แƒกแƒจแƒ˜ แƒ•แƒ—แƒฅแƒ•แƒ˜, แƒ—แƒฃ แƒ—แƒฅแƒ•แƒ”แƒœ แƒ’แƒ”แƒ’แƒ›แƒแƒ•แƒ— แƒแƒกแƒ”แƒ—แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒแƒก แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒแƒจแƒ˜, แƒ›แƒ˜แƒœแƒ˜แƒ›แƒฃแƒ› แƒฃแƒœแƒ“แƒ แƒ’แƒแƒ“แƒแƒฌแƒ”แƒ แƒแƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒแƒกแƒ˜แƒœแƒฅแƒ แƒแƒœแƒฃแƒšแƒ˜ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก: แƒ“แƒแƒแƒ แƒ”แƒ’แƒ˜แƒกแƒขแƒ แƒ˜แƒ แƒแƒ— แƒจแƒ”แƒ›แƒแƒ›แƒแƒ•แƒแƒšแƒ˜ แƒ•แƒ”แƒ‘แƒฐแƒฃแƒ™แƒ”แƒ‘แƒ˜ แƒ แƒ˜แƒ’แƒจแƒ˜ (RabbitMQ แƒแƒœ NATS) แƒ“แƒ แƒ˜แƒฅแƒ˜แƒ“แƒแƒœ แƒ’แƒแƒแƒแƒœแƒแƒšแƒ˜แƒ–แƒแƒ— แƒ“แƒ แƒ“แƒแƒแƒ›แƒฃแƒจแƒแƒ•แƒแƒ— แƒ˜แƒกแƒ˜แƒœแƒ˜. แƒ›แƒฃแƒจแƒแƒ—แƒ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒ—. แƒฌแƒ˜แƒœแƒแƒแƒฆแƒ›แƒ“แƒ”แƒ’ แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒ แƒแƒ“แƒ”แƒกแƒแƒช webhooks แƒ›แƒแƒกแƒ˜แƒฃแƒ แƒแƒ“ แƒฉแƒแƒ›แƒแƒ“แƒ˜แƒก, แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒจแƒ”แƒ’แƒฎแƒ•แƒ“แƒ”แƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ แƒ”แƒกแƒฃแƒ แƒกแƒ”แƒ‘แƒ˜แƒก แƒœแƒแƒ™แƒšแƒ”แƒ‘แƒแƒ‘แƒ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒšแƒแƒ“. แƒ แƒ˜แƒ’แƒ”แƒ‘แƒ˜แƒก แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒแƒœแƒแƒฌแƒ˜แƒšแƒแƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒ“แƒ แƒ›แƒฃแƒจแƒ”แƒ‘แƒ˜, แƒแƒกแƒ”แƒ•แƒ” แƒ›แƒแƒแƒ’แƒ•แƒแƒ แƒแƒ— แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ”แƒ‘แƒ˜ แƒ’แƒแƒœแƒ›แƒ”แƒแƒ แƒ”แƒ‘แƒ˜แƒ— แƒ“แƒแƒ•แƒแƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒฌแƒแƒ แƒฃแƒ›แƒแƒขแƒ”แƒ‘แƒšแƒแƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜. แƒแƒกแƒ”แƒ•แƒ” แƒ›แƒ˜แƒ–แƒแƒœแƒจแƒ”แƒฌแƒแƒœแƒ˜แƒšแƒ˜แƒ แƒจแƒ”แƒชแƒ•แƒแƒšแƒแƒ— แƒฎแƒ”แƒ”แƒ‘แƒ˜ แƒฃแƒคแƒ แƒ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ  แƒ“แƒ แƒฃแƒคแƒ แƒ แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒ˜แƒ–แƒ”แƒ‘แƒฃแƒšแƒ–แƒ”.

แƒ’แƒ˜แƒกแƒฃแƒ แƒ•แƒ”แƒ‘แƒ— แƒฌแƒแƒ แƒ›แƒแƒขแƒ”แƒ‘แƒ”แƒ‘แƒก!

แƒ›แƒ”แƒขแƒ˜ แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ แƒ—แƒ”แƒ›แƒแƒ–แƒ”:

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ