ื“ื•ื’ืžื” ืœืืคืœื™ืงืฆื™ื” ืžื•ื ืขืช ืื™ืจื•ืขื™ื ื”ืžื‘ื•ืกืกืช ืขืœ webhooks ื‘ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื S3 Mail.ru Cloud Solutions

ื“ื•ื’ืžื” ืœืืคืœื™ืงืฆื™ื” ืžื•ื ืขืช ืื™ืจื•ืขื™ื ื”ืžื‘ื•ืกืกืช ืขืœ webhooks ื‘ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื S3 Mail.ru Cloud Solutions
ืžื›ื•ื ืช ืงืคื” ืจื•ื‘ื” ื’ื•ืœื“ื‘ืจื’

ืืจื›ื™ื˜ืงื˜ื•ืจื” ืžื•ื ืขืช ืื™ืจื•ืขื™ื ืžื’ื“ื™ืœื” ืืช ื™ืขื™ืœื•ืช ื”ืขืœื•ืช ืฉืœ ื”ืžืฉืื‘ื™ื ื”ืžืฉืžืฉื™ื ืžื›ื™ื•ื•ืŸ ืฉื”ื ืžืฉืžืฉื™ื ืจืง ื‘ืจื’ืข ืฉื‘ื• ื”ื ื ื—ื•ืฆื™ื. ื™ืฉื ืŸ ืืคืฉืจื•ื™ื•ืช ืจื‘ื•ืช ื›ื™ืฆื“ ืœื™ื™ืฉื ื–ืืช ื•ืœื ืœื™ืฆื•ืจ ื™ืฉื•ื™ื•ืช ืขื ืŸ ื ื•ืกืคื•ืช ื›ืืคืœื™ืงืฆื™ื•ืช ืขื•ื‘ื“ื™ื. ื•ื”ื™ื•ื ืื ื™ ืื“ื‘ืจ ืœื ืขืœ FaaS, ืืœื ืขืœ webhooks. ืื ื™ ืืจืื” ื“ื•ื’ืžื” ืœื”ื“ืจื›ื” ืฉืœ ื˜ื™ืคื•ืœ ื‘ืื™ืจื•ืขื™ื ื‘ืืžืฆืขื•ืช webhooks ืœืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื.

ื›ืžื” ืžื™ืœื™ื ืขืœ ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื ื•-webhooks. ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื ืžืืคืฉืจ ืœืš ืœืื—ืกืŸ ื›ืœ ื ืชื•ื ื™ื ื‘ืขื ืŸ ื‘ืฆื•ืจื” ืฉืœ ืื•ื‘ื™ื™ืงื˜ื™ื, ื”ื ื’ื™ืฉื™ื ื“ืจืš S3 ืื• API ืื—ืจ (ื‘ื”ืชืื ืœืžื™ืžื•ืฉ) ื‘ืืžืฆืขื•ืช HTTP/HTTPS. Webhooks ื”ื ื‘ื“ืจืš ื›ืœืœ ื”ืชืงืฉืจื•ืช ืขื HTTP ืžื•ืชืืžื•ืช ืื™ืฉื™ืช. ื”ื ืžื•ืคืขืœื™ื ื‘ื“ืจืš ื›ืœืœ ืขืœ ื™ื“ื™ ืื™ืจื•ืข, ื›ื’ื•ืŸ ืงื•ื“ ืฉื ื“ื—ืฃ ืœืžืื’ืจ ืื• ื”ืขืจื” ืฉืžืชืคืจืกืžืช ื‘ื‘ืœื•ื’. ื›ืืฉืจ ืžืชืจื—ืฉ ืื™ืจื•ืข, ืืชืจ ื”ืžืงื•ืจ ืฉื•ืœื— ื‘ืงืฉืช HTTP ืœื›ืชื•ื‘ืช ื”-URL ืฉืฆื•ื™ื ื” ืขื‘ื•ืจ ื”-webhook. ื›ืชื•ืฆืื” ืžื›ืš, ืืชื” ื™ื›ื•ืœ ืœื’ืจื•ื ืœืื™ืจื•ืขื™ื ื‘ืืชืจ ืื—ื“ ืœื”ืคืขื™ืœ ืคืขื•ืœื•ืช ื‘ืืชืจ ืื—ืจ (ื•ื™ืงื™). ื‘ืžืงืจื” ืฉื‘ื• ืืชืจ ื”ืžืงื•ืจ ื”ื•ื ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื, ืื™ืจื•ืขื™ื ืคื•ืขืœื™ื ื›ืฉื™ื ื•ื™ื™ื ื‘ืชื•ื›ืŸ ืฉืœื•.

ื“ื•ื’ืžืื•ืช ืœืžืงืจื™ื ืคืฉื•ื˜ื™ื ืฉื‘ื”ื ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ืื•ื˜ื•ืžืฆื™ื” ื›ื–ื•:

  1. ื™ืฆื™ืจืช ืขื•ืชืงื™ื ืฉืœ ื›ืœ ื”ืื•ื‘ื™ื™ืงื˜ื™ื ื‘ืื—ืกื•ืŸ ืขื ืŸ ืื—ืจ. ื™ืฉ ืœื™ืฆื•ืจ ืขื•ืชืงื™ื ืชื•ืš ื›ื“ื™ ืชื ื•ืขื” ื‘ื›ืœ ืคืขื ืฉืžืชื•ื•ืกืคื™ื ืื• ืžืฉื ื™ื ืงื‘ืฆื™ื.
  2. ื™ืฆื™ืจื” ืื•ื˜ื•ืžื˜ื™ืช ืฉืœ ืกื“ืจื” ืฉืœ ืชืžื•ื ื•ืช ืžืžื•ื–ืขืจื•ืช ืฉืœ ืงื‘ืฆื™ื ื’ืจืคื™ื™ื, ื”ื•ืกืคืช ืกื™ืžื ื™ ืžื™ื ืœืชืžื•ื ื•ืช ื•ืฉื™ื ื•ื™ื™ ืชืžื•ื ื” ืื—ืจื™ื.
  3. ื”ื•ื“ืขื” ืขืœ ื”ื’ืขืช ืžืกืžื›ื™ื ื—ื“ืฉื™ื (ืœื“ื•ื’ืžื”, ืฉื™ืจื•ืช ื”ื ื”ืœืช ื—ืฉื‘ื•ื ื•ืช ืžื‘ื•ื–ืจ ืžืขืœื” ื“ื•ื—ื•ืช ืœืขื ืŸ, ื•ื”ื ื™ื˜ื•ืจ ื”ืคื™ื ื ืกื™ ืžืงื‘ืœ ื”ื•ื“ืขื•ืช ืขืœ ื“ื•ื—ื•ืช ื—ื“ืฉื™ื, ื‘ื•ื“ืง ื•ืžื ืชื— ืื•ืชื).
  4. ืžืงืจื™ื ืงืฆืช ื™ื•ืชืจ ืžื•ืจื›ื‘ื™ื ื›ื•ืœืœื™ื, ืœืžืฉืœ, ื™ืฆื™ืจืช ื‘ืงืฉื” ืœ-Kubernetes, ืฉื™ื•ืฆืจืช ืคื•ื“ ืขื ื”ืงื•ื ื˜ื™ื™ื ืจื™ื ื”ื“ืจื•ืฉื™ื, ืžืขื‘ื™ืจื” ืืœื™ื• ืคืจืžื˜ืจื™ื ืฉืœ ืžืฉื™ืžื•ืช ื•ืœืื—ืจ ืขื™ื‘ื•ื“ ืžืžื•ื˜ื˜ืช ื”ืงื•ื ื˜ื™ื™ื ืจ.

ื›ื“ื•ื’ืžื”, ื ื‘ืฆืข ื’ืจืกื” ืฉืœ ืžืฉื™ืžื” 1, ื›ืืฉืจ ืฉื™ื ื•ื™ื™ื ื‘ื“ืœื™ ืื—ืกื•ืŸ ื”ืื•ื‘ื™ื™ืงื˜ื™ื ืฉืœ Mail.ru Cloud Solutions (MCS) ืžืกื•ื ื›ืจื ื™ื ื‘ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื ืฉืœ AWS ื‘ืืžืฆืขื•ืช webhooks. ื‘ืžืงืจื” ื˜ืขื•ืŸ ืืžื™ืชื™, ื™ืฉ ืœืกืคืง ืขื‘ื•ื“ื” ืืกื™ื ื›ืจื•ื ื™ืช ืขืœ ื™ื“ื™ ืจื™ืฉื•ื webhooks ื‘ืชื•ืจ, ืืš ืขื‘ื•ืจ ืžืฉื™ืžืช ื”ื”ื“ืจื›ื” ืื ื• ื ืขืฉื” ืืช ื”ื™ื™ืฉื•ื ืœืœื ื–ื”.

ืชื›ื ื™ืช ืขื‘ื•ื“ื”

ืคืจื•ื˜ื•ืงื•ืœ ื”ืื™ื ื˜ืจืืงืฆื™ื” ืžืชื•ืืจ ื‘ืคื™ืจื•ื˜ ื‘ ืžื“ืจื™ืš ืœ-S3 webhooks ื‘-MCS. ืขืจื›ืช ื”ืขื‘ื•ื“ื” ืžื›ื™ืœื” ืืช ื”ืืœืžื ื˜ื™ื ื”ื‘ืื™ื:

  • ืฉื™ืจื•ืช ื”ื•ืฆืื” ืœืื•ืจ, ืฉื ืžืฆื ื‘ืฆื“ ื”ืื—ืกื•ืŸ ืฉืœ S3 ื•ืžืคืจืกื ื‘ืงืฉื•ืช HTTP ื›ืืฉืจ ื”-webnhook ืžื•ืคืขืœ.
  • ืฉืจืช ืžืงื‘ืœ Webhook, ืืฉืจ ืžืงืฉื™ื‘ื” ืœื‘ืงืฉื•ืช ืžืฉื™ืจื•ืช ื”ืคืจืกื•ื HTTP ื•ืžื‘ืฆืขืช ืคืขื•ืœื•ืช ืžืชืื™ืžื•ืช. ื ื™ืชืŸ ืœื›ืชื•ื‘ ืืช ื”ืฉืจืช ื‘ื›ืœ ืฉืคื”; ื‘ื“ื•ื’ืžื” ืฉืœื ื•, ื ื›ืชื•ื‘ ืืช ื”ืฉืจืช ื‘-Go.

ืชื›ื•ื ื” ืžื™ื•ื—ื“ืช ืฉืœ ื”ื˜ืžืขืช webhooks ื‘-S3 API ื”ื™ื ื”ืจื™ืฉื•ื ืฉืœ ืฉืจืช ืงื‘ืœืช webhook ื‘ืฉื™ืจื•ืช ื”ื”ื•ืฆืื” ืœืื•ืจ. ื‘ืคืจื˜, ื”ืฉืจืช ื”ืžืงื‘ืœ webhook ื—ื™ื™ื‘ ืœืืฉืจ ืืช ื”ืžื ื•ื™ ืœื”ื•ื“ืขื•ืช ืžืฉื™ืจื•ืช ื”ื”ื•ืฆืื” ืœืื•ืจ (ื‘ื™ื™ืฉื•ืžื™ webhook ืื—ืจื™ื, ื‘ื“ืจืš ื›ืœืœ ืื™ืŸ ืฆื•ืจืš ื‘ืื™ืฉื•ืจ ื”ืžื ื•ื™).

ื‘ื”ืชืื ืœื›ืš, ื”ืฉืจืช ื”ืžืงื‘ืœ webhook ื—ื™ื™ื‘ ืœืชืžื•ืš ื‘ืฉืชื™ ืคืขื•ืœื•ืช ืขื™ืงืจื™ื•ืช:

  • ืœื”ื’ื™ื‘ ืœื‘ืงืฉืช ืฉื™ืจื•ืช ื”ื”ื•ืฆืื” ืœืืฉืจ ืืช ื”ืจื™ืฉื•ื,
  • ืœืขื‘ื“ ืื™ืจื•ืขื™ื ื ื›ื ืกื™ื.

ื”ืชืงื ืช ืฉืจืช ืงืœื™ื˜ืช webhook

ื›ื“ื™ ืœื”ืคืขื™ืœ ืืช ื”ืฉืจืช ื”ืžืงื‘ืœ webhook, ืืชื” ืฆืจื™ืš ืฉืจืช ืœื™ื ื•ืงืก. ื‘ืžืืžืจ ื–ื”, ื›ื“ื•ื’ืžื”, ืื ื• ืžืฉืชืžืฉื™ื ื‘ืžื•ืคืข ื•ื™ืจื˜ื•ืืœื™ ืฉืื ื• ืคื•ืจืกื™ื ื‘-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) ...

ืฉื›ืคืœ ืืช ื”ืชื™ืงื™ื” ืขื ื”ืฉืจืช ื”ืžืงื‘ืœ webhook:

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

ื”ื™ืจืฉื ืœืฉื™ืจื•ืช ืคืจืกื•ื

ืืชื” ื™ื›ื•ืœ ืœืจืฉื•ื ืืช ืฉืจืช ืงื‘ืœืช ื”-webhook ืฉืœืš ื“ืจืš ื”-API ืื• ืžืžืฉืง ื”ืื™ื ื˜ืจื ื˜. ืœืฉื ื”ืคืฉื˜ื•ืช, ื ื™ืจืฉื ื“ืจืš ืžืžืฉืง ื”ืื™ื ื˜ืจื ื˜:

  1. ื‘ื•ื ื ืœืš ืœืงื˜ืข ื”ื“ืœื™ื™ื ื‘ื—ื“ืจ ื”ื‘ืงืจื”.
  2. ืขื‘ื•ืจ ืืœ ื”ื“ืœื™ ืฉืขื‘ื•ืจื• ื ื’ื“ื™ืจ webhooks ื•ืœื—ืฅ ืขืœ ื’ืœื’ืœ ื”ืฉื™ื ื™ื™ื:

ื“ื•ื’ืžื” ืœืืคืœื™ืงืฆื™ื” ืžื•ื ืขืช ืื™ืจื•ืขื™ื ื”ืžื‘ื•ืกืกืช ืขืœ webhooks ื‘ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื S3 Mail.ru Cloud Solutions

ืขื‘ื•ืจ ืœื›ืจื˜ื™ืกื™ื™ื” Webhooks ื•ืœื—ืฅ ืขืœ ื”ื•ืกืฃ:

ื“ื•ื’ืžื” ืœืืคืœื™ืงืฆื™ื” ืžื•ื ืขืช ืื™ืจื•ืขื™ื ื”ืžื‘ื•ืกืกืช ืขืœ webhooks ื‘ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื S3 Mail.ru Cloud Solutions
ืžืœื ืืช ื”ืฉื“ื•ืช:

ื“ื•ื’ืžื” ืœืืคืœื™ืงืฆื™ื” ืžื•ื ืขืช ืื™ืจื•ืขื™ื ื”ืžื‘ื•ืกืกืช ืขืœ webhooks ื‘ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื S3 Mail.ru Cloud Solutions

ืžื–ื”ื” - ืฉื ื”-webhook.

ืื™ืจื•ืข - ืื™ืœื• ืื™ืจื•ืขื™ื ืœืฉื“ืจ. ืงื‘ืขื ื• ืืช ื”ืฉื™ื“ื•ืจ ืฉืœ ื›ืœ ื”ืื™ืจื•ืขื™ื ื”ืžืชืจื—ืฉื™ื ื‘ืขื‘ื•ื“ื” ืขื ืงื‘ืฆื™ื (ื”ื•ืกืคื” ื•ืžื—ื™ืงื”).

ื›ืชื•ื‘ืช URL - ื›ืชื•ื‘ืช ืฉืจืช ื”ืžืงื‘ืœืช webhook.

ืงื™ื“ื•ืžืช/ืกื™ื•ืžืช ืžืกื ืŸ ื”ื™ื ืžืกื ืŸ ื”ืžืืคืฉืจ ืœื™ืฆื•ืจ webhooks ืจืง ืขื‘ื•ืจ ืื•ื‘ื™ื™ืงื˜ื™ื ืฉืฉืžื•ืชื™ื”ื ืชื•ืืžื™ื ื›ืœืœื™ื ืžืกื•ื™ืžื™ื. ืœื“ื•ื’ืžื”, ื›ื“ื™ ืฉื”-webhook ื™ืคืขื™ืœ ืจืง ืงื‘ืฆื™ื ืขื ืกื™ื•ืžืช .png, ื‘ ืกื™ื•ืžืช ืžืกื ืŸ ืืชื” ืฆืจื™ืš ืœื›ืชื•ื‘ "png".

ื ื›ื•ืŸ ืœืขื›ืฉื™ื•, ืจืง ื™ืฆื™ืื•ืช 80 ื•-443 ื ืชืžื›ื•ืช ืœื’ื™ืฉื” ืœืฉืจืช ื”ืžืงื‘ืœ webhook.

ื‘ื•ื ื ืงืœื™ืง ื”ื•ืกืฃ ื•ื• ื•ื ืจืื” ืืช ื”ื“ื‘ืจื™ื ื”ื‘ืื™ื:

ื“ื•ื’ืžื” ืœืืคืœื™ืงืฆื™ื” ืžื•ื ืขืช ืื™ืจื•ืขื™ื ื”ืžื‘ื•ืกืกืช ืขืœ webhooks ื‘ืื—ืกื•ืŸ ืื•ื‘ื™ื™ืงื˜ื™ื S3 Mail.ru Cloud Solutions
ื”ื•ืง ื ื•ืกืฃ.

ื”ืฉืจืช ื”ืžืงื‘ืœ webhook ืžืฆื™ื’ ื‘ื™ื•ืžื ื™ื ืฉืœื• ืืช ื”ืชืงื“ืžื•ืช ืชื”ืœื™ืš ืจื™ืฉื•ื ื”-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.

ืชื™ืื•ืจ ื”ืฉืจืช ื”ืžืงื‘ืœ 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/ping, ื”ื™ื™ืฉื•ื ื”ืคืฉื•ื˜ ื‘ื™ื•ืชืจ ืฉืœ ื‘ื“ื™ืงื” ื—ื™ื”.
  • Webhook() - ื ืชื™ื‘ ืจืืฉื™, ืžื˜ืคืœ ื‘-URL/webhook:
    • ืžืืฉืจ ืจื™ืฉื•ื ื‘ืฉื™ืจื•ืช ื”ื”ื•ืฆืื” ืœืื•ืจ (ืขื‘ื•ืจ ืœืคื•ื ืงืฆื™ื™ืช ืื™ืฉื•ืจ ืžื ื•ื™),
    • ืžืขื‘ื“ webhooks ื ื›ื ืก (ืคื•ื ืงืฆื™ื™ืช Gorecords).
  • ื”ืคื•ื ืงืฆื™ื•ืช HmacSha256 ื•-HmacSha256hex ื”ืŸ ื™ื™ืฉื•ืžื™ื ืฉืœ ืืœื’ื•ืจื™ืชืžื™ ื”ื”ืฆืคื ื” HMAC-SHA256 ื•-HMAC-SHA256 ืขื ืคืœื˜ ื›ืžื—ืจื•ื–ืช ืฉืœ ืžืกืคืจื™ื ื”ืงืกื“ืฆื™ืžืœื™ื™ื ืœื—ื™ืฉื•ื‘ ื”ื—ืชื™ืžื”.
  • main ื”ื•ื ื”ืคื•ื ืงืฆื™ื” ื”ืขื™ืงืจื™ืช, ืžืขื‘ื“ ืคืจืžื˜ืจื™ื ืฉืœ ืฉื•ืจืช ื”ืคืงื•ื“ื” ื•ืจื•ืฉื ืžื˜ืคืœื™ื ื‘-URL.

ืคืจืžื˜ืจื™ื ืฉืœ ืฉื•ืจืช ื”ืคืงื•ื“ื” ื”ืžืงื•ื‘ืœื™ื ืขืœ ื™ื“ื™ ื”ืฉืจืช:

  • -port ื”ื™ื ื”ื™ืฆื™ืื” ื‘ื” ื”ืฉืจืช ื™ืงืฉื™ื‘.
  • -ื›ืชื•ื‘ืช - ื›ืชื•ื‘ืช IP ืฉื”ืฉืจืช ื™ืงืฉื™ื‘ ืœื”.
  • -script ื”ื™ื ืชื•ื›ื ื™ืช ื—ื™ืฆื•ื ื™ืช ืฉื ืงืจืืช ืขื‘ื•ืจ ื›ืœ ื”ื•ืง ื ื›ื ืก.

ื‘ื•ืื• ื ืกืชื›ืœ ืžืงืจื•ื‘ ืขืœ ื›ืžื” ืžื”ืคื•ื ืงืฆื™ื•ืช:

//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)
    }

}

ืคื•ื ืงืฆื™ื” ื–ื• ืงื•ื‘ืขืช ืื ื”ื’ื™ืขื” ื‘ืงืฉื” ืœืืฉืจ ืจื™ืฉื•ื ืื• webhook. ื›ื“ืœืงืžืŸ ืž ืชื™ืขื•ื“, ืื ื”ื”ืจืฉืžื” ืžืื•ืฉืจืช, ื”ืžื‘ื ื” ื”ื‘ื ืฉืœ Json ืžืชืงื‘ืœ ื‘ื‘ืงืฉืช ื”ืคื•ืกื˜:

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 <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", ืžื›ื™ื•ื•ืŸ ืฉื”ื•ื ืงื™ื™ื ื‘ื‘ืงืฉืช ืื™ืฉื•ืจ ื”ืžื ื•ื™ ื•ืื™ื ื• ืงื™ื™ื ื‘-webhook. ื‘ื”ืชื‘ืกืก ืขืœ ื ื•ื›ื—ื•ืช/ื”ื™ืขื“ืจ ืขืจืš ื–ื” ื‘ื‘ืงืฉืช ื”-POST, ื‘ื™ืฆื•ืข ื ื•ืกืฃ ืฉืœ ื”ืชื•ื›ื ื™ืช ืขื•ื‘ืจ ืœืคื•ื ืงืฆื™ื” SubscriptionConfirmation, ืื• ืœืชื•ืš ืคื•ื ืงืฆื™ื” GotRecords.

ืœื ื ืฉืงื•ืœ ืืช ืคื•ื ืงืฆื™ื™ืช ืื™ืฉื•ืจ ื”ืžื ื•ื™ ื‘ืคื™ืจื•ื˜; ื”ื™ื ืžื™ื•ืฉืžืช ืขืœ ืคื™ ื”ืขืงืจื•ื ื•ืช ื”ืžืคื•ืจื˜ื™ื ื‘ ืชื™ืขื•ื“. ืืชื” ื™ื›ื•ืœ ืœื”ืฆื™ื’ ืืช ืงื•ื“ ื”ืžืงื•ืจ ืฉืœ ืคื•ื ืงืฆื™ื” ื–ื• ื‘ื›ืชื•ื‘ืช ืคืจื•ื™ืงื˜ git repositories.

ื”ืคื•ื ืงืฆื™ื” GotRecords ืžื ืชื—ืช ื‘ืงืฉื” ื ื›ื ืกืช ื•ืœื›ืœ ืื•ื‘ื™ื™ืงื˜ Record ืงื•ืจืืช ืกืงืจื™ืคื˜ ื—ื™ืฆื•ื ื™ (ืฉืฉืžื• ื”ื•ืขื‘ืจ ื‘ืคืจืžื˜ืจ -script) ืขื ื”ืคืจืžื˜ืจื™ื:

  • ืฉื ื”ื“ืœื™
  • ืžืคืชื— ืื•ื‘ื™ื™ืงื˜
  • ืคืขื•ืœื”:
    • ื”ืขืชืง - ืื ื‘ื‘ืงืฉื” ื”ืžืงื•ืจื™ืช EventName = ObjectCreated | PutObject | PutObjectCopy
    • ืžื—ืง - ืื ื‘ื‘ืงืฉื” ื”ืžืงื•ืจื™ืช EventName = ObjectRemoved | ืžื—ืงObject

ืœืคื™ื›ืš, ืื ื”ื•ืง ืžื’ื™ืข ืขื ื‘ืงืฉืช ืคื•ืกื˜, ื›ืžืชื•ืืจ ืžืขืœ, ื•ื”ืคืจืžื˜ืจ -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

ื ื™ื’ืฉ.

ืขื›ืฉื™ื• ื‘ื•ืื• ื ื›ืชื•ื‘ ืกืงืจื™ืคื˜ ืœืขื™ื‘ื•ื“ ื”-hook ื”ื ื›ื ืก, ื‘ื•ืื• ื ืงืจื ืœื–ื” 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. ื™ื•ืžื ื™ ื”ืžืกื•ืฃ ืžืจืื™ื ืฉื”ื•ื’ืฉื” ื‘ืงืฉื” ืœืฉืจืช ื”-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:~$

ื”ืงื•ื‘ืฅ ื ืžื—ืง, ื”ื‘ืขื™ื” ื ืคืชืจื”.

ืžืกืงื ื” ื•ืžืฉื™ืžื•ืช

ื›ืœ ื”ืงื•ื“ ื”ืžืฉืžืฉ ื‘ืžืืžืจ ื–ื” ื”ื•ื ื‘ืžืื’ืจ ืฉืœื™. ื™ืฉ ื’ื ื“ื•ื’ืžืื•ืช ืฉืœ ืกืงืจื™ืคื˜ื™ื ื•ื“ื•ื’ืžืื•ืช ืœืกืคื™ืจืช ื—ืชื™ืžื•ืช ืœืจื™ืฉื•ื webhooks.

ื”ืงื•ื“ ื”ื–ื” ื”ื•ื ืœื ื™ื•ืชืจ ืžืืฉืจ ื“ื•ื’ืžื” ืœืื•ืคืŸ ืฉื‘ื• ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘-S3 webhooks ื‘ืคืขื™ืœื•ื™ื•ืช ืฉืœืš. ื›ืคื™ ืฉืืžืจืชื™ ื‘ื”ืชื—ืœื”, ืื ืืชื” ืžืชื›ื ืŸ ืœื”ืฉืชืžืฉ ื‘ืฉืจืช ื›ื–ื” ื‘ื™ื™ืฆื•ืจ, ืืชื” ืฆืจื™ืš ืœืคื—ื•ืช ืœืฉื›ืชื‘ ืืช ื”ืฉืจืช ืœืขื‘ื•ื“ื” ืืกื™ื ื›ืจื•ื ื™ืช: ืœืจืฉื•ื webhooks ื ื›ื ืก ื‘ืชื•ืจ (RabbitMQ ืื• NATS), ื•ืžืฉื ืœื ืชื— ืื•ืชื ื•ืœืขื‘ื“ ืื•ืชื ืขื ื™ื™ืฉื•ืžื™ ืขื•ื‘ื“ื™ื. ืื—ืจืช, ื›ืืฉืจ webhooks ืžื’ื™ืขื™ื ื‘ืื•ืคืŸ ืžืกื™ื‘ื™, ืืชื” ืขืœื•ืœ ืœื”ื™ืชืงืœ ื‘ืžื—ืกื•ืจ ื‘ืžืฉืื‘ื™ ืฉืจืช ืœื”ืฉืœืžืช ืžืฉื™ืžื•ืช. ื”ื ื•ื›ื—ื•ืช ืฉืœ ืชื•ืจื™ื ืžืืคืฉืจืช ืœืš ืœื”ืคื™ืฅ ืืช ื”ืฉืจืช ื•ื”ืขื•ื‘ื“ื™ื, ื›ืžื• ื’ื ืœืคืชื•ืจ ื‘ืขื™ื•ืช ืขื ืžืฉื™ืžื•ืช ื—ื•ื–ืจื•ืช ื‘ืžืงืจื” ืฉืœ ื›ืฉืœื™ื. ื›ืžื• ื›ืŸ, ืจืฆื•ื™ ืœืฉื ื•ืช ืืช ื”ืจื™ืฉื•ื ืœืžืคื•ืจื˜ ื™ื•ืชืจ ื•ืกื˜ื ื“ืจื˜ื™ ื™ื•ืชืจ.

ืžื–ืœ ื˜ื•ื‘!

ืงืจื™ืื” ื ื•ืกืคืช ื‘ื ื•ืฉื:

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”