S3 рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдг Mail.ru Cloud Solutions рдорд╛ рд╡реЗрдмрд╣реБрдХрд╣рд░реВрдорд╛ рдЖрдзрд╛рд░рд┐рдд рдШрдЯрдирд╛-рд╕рдВрдЪрд╛рд▓рд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧрдХреЛ рдЙрджрд╛рд╣рд░рдг

S3 рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдг Mail.ru Cloud Solutions рдорд╛ рд╡реЗрдмрд╣реБрдХрд╣рд░реВрдорд╛ рдЖрдзрд╛рд░рд┐рдд рдШрдЯрдирд╛-рд╕рдВрдЪрд╛рд▓рд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧрдХреЛ рдЙрджрд╛рд╣рд░рдг
рд░реБрдмреЗ рдЧреЛрд▓реНрдбрдмрд░реНрдЧ рдХрдлреА рдореЗрд╕рд┐рди

рдШрдЯрдирд╛-рд╕рдВрдЪрд╛рд▓рд┐рдд рд╡рд╛рд╕реНрддреБрдХрд▓рд╛рд▓реЗ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХрд╛ рд╕реНрд░реЛрддрд╣рд░реВрдХреЛ рд▓рд╛рдЧрдд рджрдХреНрд╖рддрд╛ рдмрдврд╛рдЙрдБрдЫ рдХрд┐рдирднрдиреЗ рддрд┐рдиреАрд╣рд░реВ рдЖрд╡рд╢реНрдпрдХ рд╣реБрдБрджрд╛ рдорд╛рддреНрд░ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫред рдпрд╕рд▓рд╛рдИ рдХрд╕рд░реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░реНрдиреЗ рд░ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╣рд░реВрдХреЛ рд░реВрдкрдорд╛ рдердк рдХреНрд▓рд╛рдЙрдб рд╕рдВрд╕реНрдерд╛рд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдирдЧрд░реНрдиреЗ рднрдиреНрдиреЗ рдмрд╛рд░реЗ рдзреЗрд░реИ рд╡рд┐рдХрд▓реНрдкрд╣рд░реВ рдЫрдиреНред рд░ рдЖрдЬ рдо FaaS рдХреЛ рдмрд╛рд░реЗрдорд╛ рд╣реЛрдЗрди, рддрд░ рд╡реЗрдмрд╣реБрдХрдХреЛ рдмрд╛рд░реЗрдорд╛ рдХреБрд░рд╛ рдЧрд░реНрдиреЗрдЫреБред рдо рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдг рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдШрдЯрдирд╛рд╣рд░реВ рд╣реНрдпрд╛рдиреНрдбрд▓ рдЧрд░реНрдиреЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦрд╛рдЙрдиреЗрдЫреБред

рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдг рд░ рд╡реЗрдмрд╣реБрдХ рдмрд╛рд░реЗ рдХреЗрд╣реА рд╢рдмреНрджрд╣рд░реВред рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдгрд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдХреНрд▓рд╛рдЙрдбрдорд╛ рдХреБрдиреИ рдкрдирд┐ рдбрд╛рдЯрд╛рд▓рд╛рдИ рд╡рд╕реНрддреБрдХреЛ рд░реВрдкрдорд╛ рднрдгреНрдбрд╛рд░рдг рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ, S3 рд╡рд╛ рдЕрд░реНрдХреЛ API (рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдорд╛ рдирд┐рд░реНрднрд░) HTTP/HTTPS рдорд╛рд░реНрдлрдд рдкрд╣реБрдБрдЪрдпреЛрдЧреНрдпред рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рдЕрдиреБрдХреВрд▓рди HTTP рдХрд▓рдмреНрдпрд╛рдХрд╣рд░реВ рд╣реБрдиреНред рддрд┐рдиреАрд╣рд░реВ рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рдПрдХ рдШрдЯрдирд╛ рджреНрд╡рд╛рд░рд╛ рдЯреНрд░рд┐рдЧрд░ рд╣реБрдиреНрдЫрдиреН, рдЬрд╕реНрддреИ рдХреЛрдб рдПрдХ рднрдгреНрдбрд╛рд░рдорд╛ рдзрдХреЗрд▓рд┐рдПрдХреЛ рд╡рд╛ рдмреНрд▓рдЧрдорд╛ рдкреЛрд╕реНрдЯ рдЧрд░рд┐рдПрдХреЛ рдЯрд┐рдкреНрдкрдгреАред рдЬрдм рдШрдЯрдирд╛ рд╣реБрдиреНрдЫ, рдЙрддреНрдкрддреНрддрд┐ рд╕рд╛рдЗрдЯрд▓реЗ рд╡реЗрдмрд╣реБрдХрдХреЛ рд▓рд╛рдЧрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ URL рдорд╛ HTTP рдЕрдиреБрд░реЛрдз рдкрдард╛рдЙрдБрдЫред рдирддрд┐рдЬрд╛рдХреЛ рд░реВрдкрдорд╛, рддрдкрд╛рдЗрдБ рдПрдХ рд╕рд╛рдЗрдЯрдорд╛ рдШрдЯрдирд╛рд╣рд░реВ рдмрдирд╛рдЙрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдЕрд░реНрдХреЛрдорд╛ рдХрд╛рд░реНрдпрд╣рд░реВ рдЯреНрд░рд┐рдЧрд░ рдЧрд░реНрдиреБрд╣реЛрд╕реН (wiki)ред рдпрджрд┐ рд╕реНрд░реЛрдд рд╕рд╛рдЗрдЯ рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдг рд╣реЛ рднрдиреЗ, рдШрдЯрдирд╛рд╣рд░реВрд▓реЗ рдпрд╕рдХреЛ рд╕рд╛рдордЧреНрд░реАрд╣рд░реВрдорд╛ рдкрд░рд┐рд╡рд░реНрддрдирдХреЛ рд░реВрдкрдорд╛ рдХрд╛рд░реНрдп рдЧрд░реНрджрдЫред

рдпрд╕реНрддреЛ рд╕реНрд╡рдЪрд╛рд▓рди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ рдЬрдм рд╕рд╛рдзрд╛рд░рдг рдорд╛рдорд▓рд╛рд╣рд░реБ рдХреЛ рдЙрджрд╛рд╣рд░рдгрд╣рд░реБ:

  1. рдЕрд░реНрдХреЛ рдХреНрд▓рд╛рдЙрдб рднрдгреНрдбрд╛рд░рдгрдорд╛ рд╕рдмреИ рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐рд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджреИред рдлрд╛рдЗрд▓рд╣рд░реВ рдердкреНрджрд╛ рд╡рд╛ рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реНрджрд╛ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐рд╣рд░реВ рдлреНрд▓рд╛рдЗрдорд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрдкрд░реНрдЫред
  2. рдЧреНрд░рд╛рдлрд┐рдХ рдлрд╛рдЗрд▓рд╣рд░реВрдХреЛ рдердореНрдмрдиреЗрд▓рд╣рд░реВрдХреЛ рд╢реНрд░реГрдВрдЦрд▓рд╛рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╕рд┐рд░реНрдЬрдирд╛, рдлреЛрдЯреЛрд╣рд░реВрдорд╛ рд╡рд╛рдЯрд░рдорд╛рд░реНрдХрд╣рд░реВ рдердкреНрджреИ, рд░ рдЕрдиреНрдп рдЫрд╡рд┐ рдкрд░рд┐рдорд╛рд░реНрдЬрдирд╣рд░реВред
  3. рдирдпрд╛рдБ рдХрд╛рдЧрдЬрд╛рддрд╣рд░реВрдХреЛ рдЖрдЧрдордирдХреЛ рдмрд╛рд░реЗрдорд╛ рд╕реВрдЪрдирд╛ (рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рд╡рд┐рддрд░рд┐рдд рд▓реЗрдЦрд╛ рд╕реЗрд╡рд╛рд▓реЗ рдХреНрд▓рд╛рдЙрдбрдорд╛ рд░рд┐рдкреЛрд░реНрдЯрд╣рд░реВ рдЕрдкрд▓реЛрдб рдЧрд░реНрджрдЫ, рд░ рд╡рд┐рддреНрддреАрдп рдЕрдиреБрдЧрдордирд▓реЗ рдирдпрд╛рдБ рд░рд┐рдкреЛрд░реНрдЯрд╣рд░реВ, рдЬрд╛рдБрдЪрд╣рд░реВ рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рд╕реВрдЪрдирд╛рд╣рд░реВ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрджрдЫ)ред
  4. рдереЛрд░реИ рдЬрдЯрд┐рд▓ рдХреЗрд╕рд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рд╣реБрдиреНрдЫрдиреН, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рд▓рд╛рдИ рдЕрдиреБрд░реЛрдз рдЙрддреНрдкрдиреНрди рдЧрд░реНрдиреЗ, рдЬрд╕рд▓реЗ рдЖрд╡рд╢реНрдпрдХ рдХрдиреНрдЯреЗрдирд░рд╣рд░реВрдХреЛ рд╕рд╛рде рдкреЛрдб рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджрдЫ, рдпрд╕рдорд╛ рдХрд╛рд░реНрдп рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрджрдЫ, рд░ рдкреНрд░рд╢реЛрдзрди рдкрдЫрд┐ рдХрдиреНрдЯреЗрдирд░рд▓рд╛рдИ рдкрддрди рдЧрд░реНрджрдЫред

рдЙрджрд╛рд╣рд░рдгрдХреЛ рд░реВрдкрдорд╛, рдЬрдм Mail.ru Cloud Solutions (MCS) рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдг рдмрд╛рдХреЗрдЯрдорд╛ рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВ рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ AWS рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдгрдорд╛ рд╕рд┐рдЩреНрдХреНрд░реЛрдирд╛рдЗрдЬ рд╣реБрдиреНрдЫрдиреН, рддрдм рд╣рд╛рдореА рдЯрд╛рд╕реНрдХ рез рдХреЛ рднрд┐рдиреНрдирддрд╛ рдмрдирд╛рдЙрдиреЗрдЫреМрдВред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд▓реЛрдб рднрдПрдХреЛ рдЕрд╡рд╕реНрдерд╛рдорд╛, рд▓рд╛рдордорд╛ рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рджрд░реНрддрд╛ рдЧрд░реЗрд░ рдПрд╕рд┐рдиреНрдХреНрд░реЛрдирд╕ рдХрд╛рд░реНрдп рдкреНрд░рджрд╛рди рдЧрд░рд┐рдиреБрдкрд░реНрдЫ, рддрд░ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХрд╛рд░реНрдпрдХреЛ рд▓рд╛рдЧрд┐ рд╣рд╛рдореА рдпреЛ рдмрд┐рдирд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░реНрдиреЗрдЫреМрдВред

рдХрд╛рд░реНрдп рдпреЛрдЬрдирд╛

рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛ рдкреНрд░реЛрдЯреЛрдХрд▓ рдорд╛ рд╡рд┐рд╕реНрддреГрдд рд░реВрдкрдорд╛ рд╡рд░реНрдгрди рдЧрд░рд┐рдПрдХреЛ рдЫ MCS рдорд╛ S3 рд╡реЗрдмрд╣реБрдХрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдЧрд╛рдЗрдбред рдХрд╛рд░реНрдп рдпреЛрдЬрдирд╛рд▓реЗ рдирд┐рдореНрди рддрддреНрд╡рд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрджрдЫ:

  • рдкреНрд░рдХрд╛рд╢рди рд╕реЗрд╡рд╛, рдЬреБрди S3 рднрдгреНрдбрд╛рд░рдг рдкрдХреНрд╖рдорд╛ рдЫ рд░ рд╡реЗрдмрдирд╣реБрдХ рдЯреНрд░рд┐рдЧрд░ рд╣реБрдБрджрд╛ HTTP рдЕрдиреБрд░реЛрдзрд╣рд░реВ рдкреНрд░рдХрд╛рд╢рд┐рдд рдЧрд░реНрджрдЫред
  • рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░, рдЬрд╕рд▓реЗ HTTP рдкреНрд░рдХрд╛рд╢рди рд╕реЗрд╡рд╛рдмрд╛рдЯ рдЕрдиреБрд░реЛрдзрд╣рд░реВ рд╕реБрдиреНрдЫ рд░ рдЙрдкрдпреБрдХреНрдд рдХрд╛рд░реНрдпрд╣рд░реВ рдЧрд░реНрджрдЫред рд╕рд░реНрднрд░ рдХреБрдиреИ рдкрдирд┐ рднрд╛рд╖рд╛рдорд╛ рд▓реЗрдЦреНрди рд╕рдХрд┐рдиреНрдЫ; рд╣рд╛рдореНрд░реЛ рдЙрджрд╛рд╣рд░рдгрдорд╛, рд╣рд╛рдореА Go рдорд╛ рд╕рд░реНрднрд░ рд▓реЗрдЦреНрдиреЗрдЫреМрдВред

S3 API рдорд╛ рд╡реЗрдмрд╣реБрдХрд╣рд░реВрдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреНрд░рдХрд╛рд╢рди рд╕реЗрд╡рд╛рдорд╛ рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░рдХреЛ рджрд░реНрддрд╛ рд╣реЛред рд╡рд┐рд╢реЗрд╖ рдЧрд░реА, рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░рд▓реЗ рдкреНрд░рдХрд╛рд╢рди рд╕реЗрд╡рд╛рдмрд╛рдЯ рд╕рдиреНрджреЗрд╢рд╣рд░реВрдХреЛ рд╕рджрд╕реНрдпрддрд╛ рдкреБрд╖реНрдЯрд┐ рдЧрд░реНрдиреБрдкрд░реНрдЫ (рдЕрдиреНрдп рд╡реЗрдмрд╣реБрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирд╣рд░реВрдорд╛, рд╕рджрд╕реНрдпрддрд╛рдХреЛ рдкреБрд╖реНрдЯрд┐ рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рдЖрд╡рд╢реНрдпрдХ рдкрд░реНрджреИрди)ред

рддрджрдиреБрд╕рд╛рд░, рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░рд▓реЗ рджреБрдИ рдореБрдЦреНрдп рдХрд╛рд░реНрдпрд╣рд░реВрд▓рд╛рдИ рд╕рдорд░реНрдерди рдЧрд░реНрдиреБрдкрд░реНрдЫ:

  • рджрд░реНрддрд╛ рдкреБрд╖реНрдЯрд┐ рдЧрд░реНрди рдкреНрд░рдХрд╛рд╢рди рд╕реЗрд╡рд╛рдХреЛ рдЕрдиреБрд░реЛрдзрд▓рд╛рдИ рдЬрд╡рд╛рдл рджрд┐рдиреБрд╣реЛрд╕реН,
  • рдЖрдЧрдорди рдШрдЯрдирд╛рд╣рд░реВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ред

рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрджреИ

рд╡реЗрдмрд╣реБрдХ рд░рд┐рд╕рд┐рднрд┐рдЩ рд╕рд░реНрднрд░ рдЪрд▓рд╛рдЙрдирдХреЛ рд▓рд╛рдЧрд┐ рддрдкрд╛рдИрд▓рд╛рдИ рд▓рд┐рдирдХреНрд╕ рд╕рд░реНрднрд░ рдЪрд╛рд╣рд┐рдиреНрдЫред рдпрд╕ рд▓реЗрдЦрдорд╛, рдЙрджрд╛рд╣рд░рдгрдХреЛ рд░реВрдкрдорд╛, рд╣рд╛рдореАрд▓реЗ MCS рдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рднрд░реНрдЪреБрдЕрд▓ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдЫреМрдВред

рдЖрд╡рд╢реНрдпрдХ рд╕рдлреНрдЯрд╡реЗрдпрд░ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реМрдВ рд░ рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░ рд╕реБрд░реБ рдЧрд░реМрдВред

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 рдорд╛ рд╡реЗрдмрд╣реБрдХрд╣рд░реВрдорд╛ рдЖрдзрд╛рд░рд┐рдд рдШрдЯрдирд╛-рд╕рдВрдЪрд╛рд▓рд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧрдХреЛ рдЙрджрд╛рд╣рд░рдг

рд╡реЗрдмрд╣реБрдХреНрд╕ рдЯреНрдпрд╛рдмрдорд╛ рдЬрд╛рдиреБрд╣реЛрд╕реН рд░ рдердкреНрдиреБрд╣реЛрд╕реН рдХреНрд▓рд┐рдХ рдЧрд░реНрдиреБрд╣реЛрд╕реН:

S3 рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдг Mail.ru Cloud Solutions рдорд╛ рд╡реЗрдмрд╣реБрдХрд╣рд░реВрдорд╛ рдЖрдзрд╛рд░рд┐рдд рдШрдЯрдирд╛-рд╕рдВрдЪрд╛рд▓рд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧрдХреЛ рдЙрджрд╛рд╣рд░рдг
рдХреНрд╖реЗрддреНрд░рд╣рд░реВ рднрд░реНрдиреБрд╣реЛрд╕реН:

S3 рд╡рд╕реНрддреБ рднрдгреНрдбрд╛рд░рдг Mail.ru Cloud Solutions рдорд╛ рд╡реЗрдмрд╣реБрдХрд╣рд░реВрдорд╛ рдЖрдзрд╛рд░рд┐рдд рдШрдЯрдирд╛-рд╕рдВрдЪрд╛рд▓рд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧрдХреЛ рдЙрджрд╛рд╣рд░рдг

ID тАФ рд╡реЗрдмрд╣реБрдХрдХреЛ рдирд╛рдоред

рдШрдЯрдирд╛ - рдХреБрди рдШрдЯрдирд╛рд╣рд░реВ рдкреНрд░рд╕рд╛рд░рдг рдЧрд░реНрдиред рд╣рд╛рдореАрд▓реЗ рдлрд╛рдЗрд▓рд╣рд░реВрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрджрд╛ рд╣реБрдиреЗ рд╕рдмреИ рдШрдЯрдирд╛рд╣рд░реВрдХреЛ рдкреНрд░рд╕рд╛рд░рдг рд╕реЗрдЯ рдЧрд░реЗрдХрд╛ рдЫреМрдВ (рдердкреНрджреИ рд░ рдореЗрдЯрд╛рдЙрдиреЗ)ред

URL тАФ рд╡реЗрдмрд╣реБрдХ рд╕рд░реНрднрд░ рдареЗрдЧрд╛рдирд╛ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрджреИред

рдлрд┐рд▓реНрдЯрд░ рдЙрдкрд╕рд░реНрдЧ/рдкреНрд░рддреНрдпрдп рдПрдХ рдлрд┐рд▓реНрдЯрд░ рд╣реЛ рдЬрд╕рд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдирд╛рдорд╣рд░реВ рдирд┐рд╢реНрдЪрд┐рдд рдирд┐рдпрдорд╣рд░реВрд╕рдБрдЧ рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдорд╛рддреНрд░ рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рдЙрддреНрдкрдиреНрди рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рд╡реЗрдмрд╣реБрдХрд▓реЗ .png рдПрдХреНрд╕рдЯреЗрдиреНрд╕рди рднрдПрдХрд╛ рдлрд╛рдЗрд▓рд╣рд░реВ рдорд╛рддреНрд░ рдЯреНрд░рд┐рдЧрд░ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐, рднрд┐рддреНрд░ рдлрд┐рд▓реНрдЯрд░ рдкреНрд░рддреНрдпрдп рддрдкрд╛рдИрд▓реЗ "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

рджрд░реНрддрд╛ рд╕рдореНрдкрдиреНрди рднрдПрдХреЛ рдЫред рдЕрд░реНрдХреЛ рдЦрдгреНрдбрдорд╛, рд╣рд╛рдореА рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░рдХреЛ рд╕рдЮреНрдЪрд╛рд▓рдирдХреЛ рдПрд▓реНрдЧреЛрд░рд┐рджрдордорд╛ рдердк рд╡рд┐рд╕реНрддрд╛рд░рдорд╛ рд╣реЗрд░реНрдиреЗрдЫреМрдВред

рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░рдХреЛ рд╡рд┐рд╡рд░рдг

рд╣рд╛рдореНрд░реЛ рдЙрджрд╛рд╣рд░рдгрдорд╛, рд╕рд░реНрднрд░ 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 рдорд╛рд░реНрдлрдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджрд┐рдиреЗ рдорд╛рд░реНрдЧ, liveness probe рдХреЛ рд╕рд░рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред
  • рд╡реЗрдмрд╣реБрдХ () - рдореБрдЦреНрдп рдорд╛рд░реНрдЧ, URL/рд╡реЗрдмрд╣реБрдХ рд╣реНрдпрд╛рдиреНрдбрд▓рд░:
    • рдкреНрд░рдХрд╛рд╢рди рд╕реЗрд╡рд╛рдорд╛ рджрд░реНрддрд╛ рдкреБрд╖реНрдЯрд┐ рдЧрд░реНрджрдЫ (рд╕рджрд╕реНрдпрддрд╛ рдкреБрд╖реНрдЯрд┐рдХрд░рдг рдкреНрд░рдХрд╛рд░реНрдпрдорд╛ рдЬрд╛рдиреБрд╣реЛрд╕реН),
    • рдЖрдЧрдорди рд╡реЗрдмрд╣реБрдХрд╣рд░реВ (рдЧреЛрд░реЗрдХреЛрд░реНрдбреНрд╕ рдкреНрд░рдХрд╛рд░реНрдп) рдкреНрд░рд╢реЛрдзрди рдЧрд░реНрджрдЫред
  • HmacSha256 рд░ HmacSha256hex рдХрд╛рд░реНрдпрд╣рд░реВ HMAC-SHA256 рд░ HMAC-SHA256 рдЗрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдПрд▓реНрдЧреЛрд░рд┐рджрдорд╣рд░реВ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЧрдгрдирд╛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рд╣реЗрдХреНрд╕рд╛рдбреЗрд╕рд┐рдорд▓ рд╕рдВрдЦреНрдпрд╛рд╣рд░реВрдХреЛ рд╕реНрдЯреНрд░рд┐рдЩрдХреЛ рд░реВрдкрдорд╛ рдЖрдЙрдЯрдкреБрдЯ рд╕рд╣рд┐рддрдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реБрдиреНред
  • main рдореБрдЦреНрдп рдкреНрд░рдХрд╛рд░реНрдп рд╣реЛ, рдХрдорд╛рдгреНрдб рд▓рд╛рдЗрди рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрджрдЫ рд░ URL рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд╣рд░реВ рджрд░реНрддрд╛ рдЧрд░реНрджрдЫред

рд╕рд░реНрднрд░ рджреНрд╡рд╛рд░рд╛ рд╕реНрд╡реАрдХреГрдд рдЖрджреЗрд╢ рд░реЗрдЦрд╛ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ:

  • -рдкреЛрд░реНрдЯ рддреНрдпреЛ рдкреЛрд░реНрдЯ рд╣реЛ рдЬрд╕рдорд╛ рд╕рд░реНрднрд░рд▓реЗ рд╕реБрдиреНрдиреЗрдЫред
  • -рдареЗрдЧрд╛рдирд╛ - рдЖрдИрдкреА рдареЗрдЧрд╛рдирд╛ рдЬреБрди рд╕рд░реНрднрд░рд▓реЗ рд╕реБрдиреНрдиреЗрдЫред
  • -рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдПрдХ рдмрд╛рд╣реНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реЛ рдЬреБрди рдкреНрд░рддреНрдпреЗрдХ рдЖрдЧрдорди рд╣реБрдХрдХреЛ рд▓рд╛рдЧрд┐ рдмреЛрд▓рд╛рдЗрдиреНрдЫред

рдХреЗрд╣реА рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВрдорд╛ рдирдЬрд┐рдХрдмрд╛рдЯ рд╣реЗрд░реМрдВ:

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

рдпрджрд┐ рд╡реЗрдмрд╣реБрдХ рдЖрдЙрдБрдЫ рднрдиреЗ, рдкреЛрд╕реНрдЯ рдЕрдиреБрд░реЛрдзрдХреЛ рд╕рдВрд░рдЪрдирд╛ рдпрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдЫ:

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.

рд╣рд╛рдореА рд╕рджрд╕реНрдпрддрд╛ рдкреБрд╖реНрдЯрд┐рдХрд░рдг рдкреНрд░рдХрд╛рд░реНрдпрд▓рд╛рдИ рд╡рд┐рд╕реНрддреГрдд рд░реВрдкрдорд╛ рд╡рд┐рдЪрд╛рд░ рдЧрд░реНрджреИрдиреМрдВ; рдпреЛ рдорд╛ рд╕реЗрдЯ рдЧрд░рд┐рдПрдХрд╛ рд╕рд┐рджреНрдзрд╛рдиреНрддрд╣рд░реВ рдЕрдиреБрд╕рд╛рд░ рд▓рд╛рдЧреВ рдЧрд░рд┐рдПрдХреЛ рдЫред рдХрд╛рдЧрдЬрд╛рддред рддрдкрд╛рдИрд▓реЗ рдпрд╕ рдкреНрд░рдХрд╛рд░реНрдпрдХреЛ рд▓рд╛рдЧрд┐ рд╕реНрд░реЛрдд рдХреЛрдб рдпрд╣рд╛рдБ рд╣реЗрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдкрд░рд┐рдпреЛрдЬрдирд╛ git рднрдгреНрдбрд╛рд░рд╣рд░реВ.

GotRecords рдкреНрд░рдХрд╛рд░реНрдпрд▓реЗ рдЖрдЧрдорди рдЕрдиреБрд░реЛрдзрд▓рд╛рдИ рдкрд╛рд░реНрд╕ рдЧрд░реНрджрдЫ рд░ рдкреНрд░рддреНрдпреЗрдХ рд░реЗрдХрд░реНрдб рд╡рд╕реНрддреБрдХреЛ рд▓рд╛рдЧрд┐ рдмрд╛рд╣реНрдп рд╕реНрдХреНрд░рд┐рдкреНрдЯ (рдЬрд╕рдХреЛ рдирд╛рдо -script рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рдорд╛ рдкрд╛рд░рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ) рд▓рд╛рдИ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рд╕рд╣рд┐рдд рдХрд▓ рдЧрд░реНрджрдЫ:

  • рдмрд╛рд▓реНрдЯрд┐рдирдХреЛ рдирд╛рдо
  • рд╡рд╕реНрддреБ рдХреБрдЮреНрдЬреА
  • рдХрд╛рд░реНрдп:
    • рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ - рдпрджрд┐ рдореВрд▓ рдЕрдиреБрд░реЛрдзрдорд╛ EventName = ObjectCreated | PutObject | PutObjectCopy
    • рдореЗрдЯрд╛рдЙрдиреБрд╣реЛрд╕реН - рдпрджрд┐ рдореВрд▓ рдЕрдиреБрд░реЛрдзрдорд╛ EventName = ObjectRemoved | рд╡рд╕реНрддреБ рдореЗрдЯрд╛рдЙрдиреБрд╣реЛрд╕реН

рдпрд╕рд░реА, рдпрджрд┐ рд╣реБрдХ рдкреЛрд╖реНрдЯ рдЕрдиреБрд░реЛрдзрдХреЛ рд╕рд╛рде рдЖрдЗрдкреБрдЧреНрдЫ рднрдиреЗ, рд╡рд░реНрдгрди рдЧрд░рд┐рдП рдЕрдиреБрд╕рд╛рд░ рдЙрдЪреНрдЪ, рд░ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░ -script=script.sh рддреНрдпрд╕рдкрдЫрд┐ рд╕реНрдХреНрд░рд┐рдкреНрдЯрд▓рд╛рдИ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдмреЛрд▓рд╛рдЗрдиреЗрдЫ:

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

рдпреЛ рдмреБрдЭреНрдиреБрдкрд░реНрдЫ рдХрд┐ рдпреЛ рд╡реЗрдмрд╣реБрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗ рд╕рд░реНрднрд░ рдкреВрд░реНрдг рдЙрддреНрдкрд╛рджрди рд╕рдорд╛рдзрд╛рди рд╣реЛрдЗрди, рддрд░ рд╕рдореНрднрд╛рд╡рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХреЛ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реЛред

рдХрд╛рдордХреЛ рдЙрджрд╛рд╣рд░рдг

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 рд╡реЗрдм рдЗрдиреНрдЯрд░рдлреЗрд╕ myfiles-ash рдмрдХреЗрдЯрдорд╛ test.txt рдлрд╛рдЗрд▓ рдердкреНрдиреБрд╣реЛрд╕реНред рдХрдиреНрд╕реЛрд▓ рд▓рдЧрд╣рд░реВрд▓реЗ рд╡реЗрдмрд╣реБрдХ рд╕рд░реНрднрд░рдорд╛ рдЕрдиреБрд░реЛрдз рдЧрд░рд┐рдПрдХреЛ рджреЗрдЦрд╛рдЙрдБрдЫ:

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

AWS рдорд╛ myfiles-рдмреНрдпрд╛рдХрдЕрдк рдмрдХреЗрдЯрдХреЛ рд╕рд╛рдордЧреНрд░реАрд╣рд░реВ рдЬрд╛рдБрдЪ рдЧрд░реМрдВ:

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:~$

рдлрд╛рдЗрд▓ рдореЗрдЯрд╛рдЗрдпреЛ, рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рднрдпреЛред

рдирд┐рд╖реНрдХрд░реНрд╖ рд░ ToDo

рдпрд╕ рд▓реЗрдЦрдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХреЛ рд╕рдмреИ рдХреЛрдб рд╣реЛ рдореЗрд░реЛ рднрдгреНрдбрд╛рд░рдорд╛ред рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рджрд░реНрддрд╛ рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рд▓рд┐рдкрд┐рд╣рд░реВ рд░ рдЧрдгрдирд╛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд╣рд░реВрдХреЛ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рдкрдирд┐ рдЫрдиреНред

рдпреЛ рдХреЛрдб рддрдкрд╛рдИрдВрд▓реЗ рдЖрдлреНрдиреЛ рдЧрддрд┐рд╡рд┐рдзрд┐рд╣рд░реВрдорд╛ S3 рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рдХрд╕рд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рднрдиреНрдиреЗ рдЙрджрд╛рд╣рд░рдг рдорд╛рддреНрд░ рд╣реЛрдЗрдиред рдореИрд▓реЗ рд╕реБрд░реБрдорд╛ рднрдиреЗрдЭреИрдВ, рдпрджрд┐ рддрдкрд╛рдЗрдБ рдЙрддреНрдкрд╛рджрдирдорд╛ рдпрд╕реНрддреЛ рд╕рд░реНрднрд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдпреЛрдЬрдирд╛ рдмрдирд╛рдЙрдиреБрд╣реБрдиреНрдЫ рднрдиреЗ, рддрдкрд╛рдЗрдБрд▓реЗ рдХрдореНрддрд┐рдорд╛ рдПрд╕рд┐рдиреНрдХреНрд░реЛрдирд╕ рдХрд╛рд░реНрдпрдХреЛ рд▓рд╛рдЧрд┐ рд╕рд░реНрднрд░рд▓рд╛рдИ рдкреБрди: рд▓реЗрдЦреНрди рдЖрд╡рд╢реНрдпрдХ рдЫ: рдЖрдЧрдорди рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рдПрдХ рд▓рд╛рдордорд╛ рджрд░реНрддрд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН (RabbitMQ рд╡рд╛ NATS), рд░ рддреНрдпрд╣рд╛рдБрдмрд╛рдЯ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдкрд╛рд░реНрд╕ рдЧрд░реНрдиреБрд╣реЛрд╕реН рд░ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реНред рдХрд╛рдорджрд╛рд░ рдЖрд╡реЗрджрдирд╣рд░реБ рд╕рдВрдЧред рдЕрдиреНрдпрдерд╛, рдЬрдм рд╡реЗрдмрд╣реБрдХрд╣рд░реВ рд╡реНрдпрд╛рдкрдХ рд░реВрдкрдорд╛ рдЖрдЗрдкреБрдЧреНрдЫрдиреН, рддрдкрд╛рдИрдВрд▓реЗ рдХрд╛рд░реНрдпрд╣рд░реВ рдкреВрд░рд╛ рдЧрд░реНрди рд╕рд░реНрднрд░ рд╕реНрд░реЛрддрд╣рд░реВрдХреЛ рдЕрднрд╛рд╡ рд╕рд╛рдордирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред рд▓рд╛рдорд╣рд░реВрдХреЛ рдЙрдкрд╕реНрдерд┐рддрд┐рд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рд╕рд░реНрднрд░ рд░ рдХрд╛рдорджрд╛рд░рд╣рд░реВрд▓рд╛рдИ рд╡рд┐рддрд░рдг рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ, рд╕рд╛рдереИ рдЕрд╕рдлрд▓рддрд╛рдХреЛ рдЕрд╡рд╕реНрдерд╛рдорд╛ рджреЛрд╣реЛрд░реНрдпрд╛рдЙрдиреЗ рдХрд╛рд░реНрдпрд╣рд░реВрд╕рдБрдЧ рд╕рдорд╕реНрдпрд╛рд╣рд░реВ рд╕рдорд╛рдзрд╛рди рдЧрд░реНрдиред рд▓рдЧрд┐рдЩрд▓рд╛рдИ рдердк рд╡рд┐рд╕реНрддреГрдд рд░ рдЕрдзрд┐рдХ рдорд╛рдирдХреАрдХреГрддрдорд╛ рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реНрди рдкрдирд┐ рд╕рд▓реНрд▓рд╛рд╣ рджрд┐рдЗрдиреНрдЫред

рд╢реБрднрдХрд╛рдордирд╛!

рдпрд╕ рд╡рд┐рд╖рдпрдорд╛ рдердк рдкрдвреНрдиреБрд╣реЛрд╕реН:

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди