diff --git a/.ci/certs/ca_certificate.pem b/.ci/certs/ca_certificate.pem new file mode 100644 index 0000000..77f380a --- /dev/null +++ b/.ci/certs/ca_certificate.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhjCCAm6gAwIBAgIUYqXLpnhFfIhE5o1qvs6gnL67IsQwDQYJKoZIhvcNAQEL +BQAwTDE7MDkGA1UEAwwyVExTR2VuU2VsZlNpZ25lZHRSb290Q0EgMjAyMy0wOS0x +MVQyMDo1MTozOS42MDMwMTMxDTALBgNVBAcMBCQkJCQwHhcNMjMwOTExMTg1MTM5 +WhcNMzMwOTA4MTg1MTM5WjBMMTswOQYDVQQDDDJUTFNHZW5TZWxmU2lnbmVkdFJv +b3RDQSAyMDIzLTA5LTExVDIwOjUxOjM5LjYwMzAxMzENMAsGA1UEBwwEJCQkJDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJl6TmIdlTdZpd3ZJaTafrYi +0MAcHE5FEfDQgGkTJgbeXG83MTUD2NYjlGgrb1v793PiO3/iYSK2uGv5AAQdvUmI +jAP8yuJTFiIFpWvljERaDd3sg+RniUN4YaxI0xnM82A2UBWXpdAbS2ASMdPSY6+V +ZX+xbBaY/H7HDL7zhrQEkl1OGgybX+segjOTX1jkNJ7QQZ924DHLvJWDNIIBt8S8 +aYVbf6V2MFziwD98hsfIRgF22T2bgEMkI5M0H5jO4hLkeTYE7Mhpb7TfeZCSLeVD +/vmMbnOvgXJt0wvILwltH6MAviAQTjKIXiMbECTX81tmHInUQ+PKTiz8t5mVSLcC +AwEAAaNgMF4wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYE +FCjyUnXFpZI5+zz7PJxHxDuulqqZMB8GA1UdIwQYMBaAFCjyUnXFpZI5+zz7PJxH +xDuulqqZMA0GCSqGSIb3DQEBCwUAA4IBAQAw6PFWRnMqVd9rYXHHagxDSlIPj8xm +0RoeSHNgl+G8w2c6tXY2gWU0LWdmrdEX4/OpIBcw7USBSwIBCsv6vBU+HGosMhlk +/K6arqvxENu/zafU1P0RMZnjiTmmzRObIsJiijFsgZQC2q6IjZetpPo6UfdHx0Xm +PRrv+SnbkMk93/QCJJAOlodYwAhZqAkishR2fwlDnNDdR2Aj7qQLYuFr3t5Z92ej +M7OPKbd6XudeWVR3FOxi7/fcNu8mttOtfXkFcUPigs8RJDHMEH1mLMrCzQsRMfA+ +BVZiA+hifJn/9KgZXFlsANT+uLuAWmcEimDAcU/xlAf8eZLcntTB2Oep +-----END CERTIFICATE----- diff --git a/.ci/certs/ca_key.pem b/.ci/certs/ca_key.pem new file mode 100644 index 0000000..ebbda3c --- /dev/null +++ b/.ci/certs/ca_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZek5iHZU3WaXd +2SWk2n62ItDAHBxORRHw0IBpEyYG3lxvNzE1A9jWI5RoK29b+/dz4jt/4mEitrhr ++QAEHb1JiIwD/MriUxYiBaVr5YxEWg3d7IPkZ4lDeGGsSNMZzPNgNlAVl6XQG0tg +EjHT0mOvlWV/sWwWmPx+xwy+84a0BJJdThoMm1/rHoIzk19Y5DSe0EGfduAxy7yV +gzSCAbfEvGmFW3+ldjBc4sA/fIbHyEYBdtk9m4BDJCOTNB+YzuIS5Hk2BOzIaW+0 +33mQki3lQ/75jG5zr4FybdMLyC8JbR+jAL4gEE4yiF4jGxAk1/NbZhyJ1EPjyk4s +/LeZlUi3AgMBAAECggEABfZ+hDsi5P69U3GpOofEcBVXh9EBjdx8rYKBnj4kNk1w +Ae6bdtC4x/kVdv+Drk7EPf94JovPSW37fvn5n4Smf142Tto9sJHR0sM7nhQ1fZQg +Vq9moGw8elhe/cTNq0mdaURr06rvUH4bbV3kC3rF+vFLbR6hxqffawvBoMtisbrY +xIp1MfsguOjHLhEDp9crJ+1N5XkqWKZPMpMgPI0mW4Yk+O409+hT5yg/ziNQ5a7o +o86tK3axtPNiaSTPkxoU+sCVu2ILZVTbfjMk2lh7OCgoAA3A9jQ3ulRz+Cl4sXqr +1Ze5pPuRseBL10xmOmoNHR5kvqSNG3Kp6bxyTGiqIQKBgQDPYT2VyaSD4NSA5Es3 +p1DjJa/gItWWIsSSDnpBm5zF908g9rAVxLvx3JLUI4YPFY82o57DCi34jDrE6O0k +SsjuZA2SiuqSqrHxP02RYdAh7/9S/LLM9kakj7QKUU2f92QoyQvKn8M3cygBBz3x +G0uwLE0EU2wgm58SBdnAR6zHuwKBgQC9deipcKT+OG6MZWGhjYsnBiaK8XxxPl9v +Kf2hBmImVDDdOkwthPLKJhP4VhjLETKo8Zi28Nxo6ueOpfn2Q5+0XrI18VNQZI/G +ip6adbezgdIKB0OcWvkXH0Fwl7P7fgNWAPdla9jznSvGj7UnSgt7tFp1xJkXzEfU +n1NEXDNdNQKBgDlOR7RimkGPGWncrCRe6e069tTbC2aHiQZLVeFXXQUfiBA12wbI +7J6zMyfIAT2d2Ythv3dqErYCGiNbslw7BjdKEq4SESwiWzWtJoQsIVWfelC2X7pf +u7mxtDC9stOni1fx5n5Bk7J48e8Gz0kXH905ALdXTiPcnSJf14JYzBgNAoGBAITB +dBAWkGZaYIwcFfc/2Tu1AZjmcY5gaDrar4//ixLUd5Ds4qgauo2PdPrUSXcxS9A5 +ygqWZ7tUroC0KJy48dVPbYyC1yBD9sLmKxCMX/Z2hxjj0ipjTJs5GX+trT4SJIBF +GRWGJnU9sojl9cfcCIPb8m8HHUchq0t/gLcr7AnpAoGARNnUh19fK+8ldKx/h9jN +svJZK1I615OXXRCAY2BWl4k7pbufseVVhtSHxkAfzhmv5gIqojfUGf4WCfcf0eZ9 +xWBXpuWgMwnWuMlPJLwIzlaU1phDsSaHdd2iuAYfZEKWmIIIxT7+vXDO4UaVpXs6 +kso6qBkSwQTymY4m5RATlK4= +-----END PRIVATE KEY----- diff --git a/.ci/certs/client.p12 b/.ci/certs/client.p12 new file mode 100644 index 0000000..78f604e Binary files /dev/null and b/.ci/certs/client.p12 differ diff --git a/.ci/certs/client_certificate.pem b/.ci/certs/client_certificate.pem new file mode 100644 index 0000000..6a00436 --- /dev/null +++ b/.ci/certs/client_certificate.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBAjANBgkqhkiG9w0BAQsFADBMMTswOQYDVQQDDDJUTFNH +ZW5TZWxmU2lnbmVkdFJvb3RDQSAyMDIzLTA5LTExVDIwOjUxOjM5LjYwMzAxMzEN +MAsGA1UEBwwEJCQkJDAeFw0yMzA5MTExODUxNDBaFw0zMzA5MDgxODUxNDBaMDYx +IzAhBgNVBAMMGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tMQ8wDQYDVQQKDAZj +bGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQf+IB3RTjtvdY +3/Rii9zzrY3hCcFcG1k4aOwQAGnE3pgcpRzHaF+l6ZvFX8llP2hcix6ew/IZReDF +p8kuK93PxM0qsYxvCj5fywaGI2mL9sNibrs6CFtvPL+Rj57LSt5UJHSaH3LmY0CE +bV2OdBEuYEBR7eGtzmpupmA+PptHF/U0hTmfIaet6sVLjvJTmD2/3LcztNm/8ksH +iqeHgJDUE+ERWUVl7AEcBo1rHDJw+z/jsKEtKbmqoNxsfcdb2UdZw9cJkB5ojKMr +l73m35s9uIWZxf2iNd3/tqos7cXMLJcTpwr4x6n6F+PsMhBK5sVTw+kFkq+iyxsu +nSVpVT6nAgMBAAGjgfEwge4wCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0l +BAwwCgYIKwYBBQUHAwIwTAYDVR0RBEUwQ4IaZ3NhbnRvbWFnZzZMVkRNLnZtd2Fy +ZS5jb22CGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tgglsb2NhbGhvc3QwMQYD +VR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC1zZXJ2ZXI6ODAwMC9iYXNpYy5jcmww +HQYDVR0OBBYEFF+biSCzxAazbay1NaTfGDWawU6dMB8GA1UdIwQYMBaAFCjyUnXF +pZI5+zz7PJxHxDuulqqZMA0GCSqGSIb3DQEBCwUAA4IBAQCREnq62BDzp61MRlzL +lsheI/13hkLutFl+OJAoNGcSgprys7d0zwQJGakCO5o05Csi1pQmP0MCKSyPN2Xb +CTEb1qeDBt3FQkgSzXUCAjVL2wvWoL1nIZaAkD5XDjDvGr5Yd4Eczc7WYwujlT5B +JausVa/ShyYatuiTfgPI7UKASW625fkdi+h30OxQ6vnP+X3FUjOV5NO5/GSrlyFN +Fk0M1YqcypUa9meFooDo2aSMTF8zUuZKsOhFLO9B1z7Io/iAiACdPvjdZWjcpJmI +m+gUWeyMH/R4ql6VlPaitUus+CUWkWtdNuQIZEH8HKR1CIOeCW3xwmIJCK9rnbvI +oGb4 +-----END CERTIFICATE----- diff --git a/.ci/certs/client_key.pem b/.ci/certs/client_key.pem new file mode 100644 index 0000000..ab60e2f --- /dev/null +++ b/.ci/certs/client_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQf+IB3RTjtvdY +3/Rii9zzrY3hCcFcG1k4aOwQAGnE3pgcpRzHaF+l6ZvFX8llP2hcix6ew/IZReDF +p8kuK93PxM0qsYxvCj5fywaGI2mL9sNibrs6CFtvPL+Rj57LSt5UJHSaH3LmY0CE +bV2OdBEuYEBR7eGtzmpupmA+PptHF/U0hTmfIaet6sVLjvJTmD2/3LcztNm/8ksH +iqeHgJDUE+ERWUVl7AEcBo1rHDJw+z/jsKEtKbmqoNxsfcdb2UdZw9cJkB5ojKMr +l73m35s9uIWZxf2iNd3/tqos7cXMLJcTpwr4x6n6F+PsMhBK5sVTw+kFkq+iyxsu +nSVpVT6nAgMBAAECggEAI86Cit1j9AN9ERdNCguJA5Q/tHEPcvkDZoumVs0rXPL5 +XpoAikJjgsPOy6O6m5e7HYGK3as7DZoRkwBQrYw9CKx8q6NYQc2Zjqv4T9sPCklz +npjzsHC0+zKMl7v5gmI2Mm8cU0epXOWYs+VwVsGaHcPL6AYZZtb3Mk+CYc4wrpGg +BBzkFhMMRDHAhdz5O0tiV/zawZyqxAXrlgBkIWb+lQZm+cZiC/NGEQNnSErNoHiN +mjaC86jjGaI6TXmn0bte0H+KSUSCfWm3xHJGKFIxV74GzWeS3ZtBOMOTZRwZ9qYU +MS/7YeV26J2tGeC3RhWTyuZm7zrn7ZqGp9QzVWbrSQKBgQD+O24nMmveW9yQnahX +rPWwRZ+E0DDblB0M+CjHfI8bn6JEi56B+akkYjjAYi2JgVWwiWJS9TCbWkk4wEmu +o8IxEL0SH0SuBjLXWwMt4vDM5AmxNqdOyoO3J+Ewapw9zKY6uz8b/FV1eZNPQ9+J +bXQxQODDs5GC3QeR+3uJr3uIEwKBgQDR8wq9SgsBfwuqKxSX3rBA7jx/Xxfl3Qbz +OraCCl8o00C7P1jTVk32K+JmzRB2I6lVhDNNjh0hQkc39P1o6SXWH5OAC98hdZDh +q14qGit/oTtQ3Ps9Sw7dt1AAcSbEpKfkIS0T/uf2c1uTvC7tPzAqHViEG+WUwMuD +gVssX5FpnQKBgDnXzb0vVKmX3vwsUsP3/0Jm5N9z+tnKvj1YLPcOWQUg8euElMDf +y+MSUfU7oT665YMwDuXvEWsXRLeb0GfirGk7dLkt0hOCJ4kmFPgYvU7wx1/Bnpln +rEY81ZiNeRT6fgu41KgKZms/CQws1ixPcfNO3pTIQ2Ax5+oH/Niby5BvAoGALDzK +yYG9ee48FfoH18w7VSMdqjTuQyfkXAHGDPaEgISqwgmh/L3VpYYvqTuSOWJgPr2h +VbkZGDXv7bF4Z8+gglKa8MMPm+w6v+Is8DAddEITzoERiyOymTMT71PoOEz9d0sq +RWlTlRFPfXyMYr8KtgUC7qs2H7bT6vypqlrkt90CgYEA1FtcmoIdj0aUH1Ph3ReQ +HSfG19UDmI0o0CaD0d6k8cjDZnxAMe7rHW9oejIzEB+fLOuQeyGpnWKtUXLTHxYz +HmGAlmshG6r4G0Vs7En0syXB7Kd8ZLAj+oRAobzRVTOj2opiF47mK5z4rO9ymUUS +09Wnq4lVGnpvuTeviY+fA3Y= +-----END PRIVATE KEY----- diff --git a/.ci/certs/server.p12 b/.ci/certs/server.p12 new file mode 100644 index 0000000..561ebee Binary files /dev/null and b/.ci/certs/server.p12 differ diff --git a/.ci/certs/server_certificate.pem b/.ci/certs/server_certificate.pem new file mode 100644 index 0000000..dcab80d --- /dev/null +++ b/.ci/certs/server_certificate.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBATANBgkqhkiG9w0BAQsFADBMMTswOQYDVQQDDDJUTFNH +ZW5TZWxmU2lnbmVkdFJvb3RDQSAyMDIzLTA5LTExVDIwOjUxOjM5LjYwMzAxMzEN +MAsGA1UEBwwEJCQkJDAeFw0yMzA5MTExODUxNDBaFw0zMzA5MDgxODUxNDBaMDYx +IzAhBgNVBAMMGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tMQ8wDQYDVQQKDAZz +ZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6H9gnMoGCmgDN +GXpqgLiIJBmDvbo64P+FsPOvKEYFNKj/Poz2UVVY96kOJRDTBXW3p42C0GCll/2z +/4RcOwN4Jcf4TIU+IsytOyQ39FYNVMDJpMzH4dQPYlvx9euyIqxUccTYCiXtHkrd +xw5cV3gs7HPQLcklQtBgoVNnlf1fPQcPgYPa5x95+oEki2yWhScXa9EP3W6G+KXE +guCi1enoIZ3+MfxbEkfdm+C9Yo47vh6LXcokyKpiuOYk2TGrfaw5JQb1tRwb4BOQ +ORriMCHi6+TkQf58yQ5GRZvJ5sjBeJgLtmCvRJXbdZXcw25jKXPwz74qS1Q728kD +c2k7lgKvAgMBAAGjgfEwge4wCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwTAYDVR0RBEUwQ4IaZ3NhbnRvbWFnZzZMVkRNLnZtd2Fy +ZS5jb22CGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tgglsb2NhbGhvc3QwHQYD +VR0OBBYEFG5VGCQucC7FqyOJOTzIYtclS9/SMB8GA1UdIwQYMBaAFCjyUnXFpZI5 ++zz7PJxHxDuulqqZMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwtc2VydmVy +OjgwMDAvYmFzaWMuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQB3nWIIa+9Oo29gU0us +fvryYJo92A/mEGIBpixX2i4eQoPhgTSJvFWN3QCHDexbnccM6tRksQmKwn5Rrf+P +DdM8BiTLP/jOQWJXChZro8xpHLmNjlOGletsQ7wo7/p5hvD6Y7pB6FK6LdLcbwbI +Rmvy8olsfOMewEyyWLbKB7e7+iwDIO5lxxgNWXKspO+Kx7wgVeS3j2OhLaOBj1N4 +a+YAXVVaN3IkkdHwUHBTPfuvguXCD8fZxVW5RkYDiweeHAMuwpu3o2rd7y2dGzG7 +u5mLzNazq4Ki/FTSZMkMAloN4/vfXQfGUO4UJcGXB/c3XO9XURsF2N1k0T9ThIUh +bhmL +-----END CERTIFICATE----- diff --git a/.ci/certs/server_key.pem b/.ci/certs/server_key.pem new file mode 100644 index 0000000..b352f63 --- /dev/null +++ b/.ci/certs/server_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6H9gnMoGCmgDN +GXpqgLiIJBmDvbo64P+FsPOvKEYFNKj/Poz2UVVY96kOJRDTBXW3p42C0GCll/2z +/4RcOwN4Jcf4TIU+IsytOyQ39FYNVMDJpMzH4dQPYlvx9euyIqxUccTYCiXtHkrd +xw5cV3gs7HPQLcklQtBgoVNnlf1fPQcPgYPa5x95+oEki2yWhScXa9EP3W6G+KXE +guCi1enoIZ3+MfxbEkfdm+C9Yo47vh6LXcokyKpiuOYk2TGrfaw5JQb1tRwb4BOQ +ORriMCHi6+TkQf58yQ5GRZvJ5sjBeJgLtmCvRJXbdZXcw25jKXPwz74qS1Q728kD +c2k7lgKvAgMBAAECggEAA45fNA8wJUgpqBbgCA/nNrFbNsarERFCdedLHfd1hbJG +C6vCHWSxbkPmcX7ozYyxp+17c9qPtipAw9h9IBaqkCLx/qmrnrkjKFN/HiiSH6q/ +t4/pWmT+BxXjLtd624pJDktRg6qHTfqsWy9rSVK3LkM4SpZ4B45kFSyP6jnrP49j +vmSHzDISiN4G4GqFK12IbA0nioF5tbuacZVGEAoKcUFxEHQmq1e8b6sjg6uKSexk +GFEpvcBm8XgSYjiBPit/AHKxGqzuO0/BbjvQK7gSeSLLaV6DUdKFi9GFsOQjmedq +DLbxy0CIleCnK0hYwp1SN9gvNBLrOIT5lqZfv4+X0QKBgQDrlRjiNJ6rWwQZcidp +ncStV2f/RVuztAacSYHz+0ZZY72uQh+8+W/7+BDkKsZIV2Bswv2wN9/8mPluvyI8 +OLWf1MOwRC5RUsBJqykRuPzFCoe4aZksBVnQsx82bBpfzQFqspCXw3UAcZcM+dHg +jTkFVsSOeCoQxg2DFN0bwz8/vwKBgQDKQWogOStxgnJisxffSQYH0pHbMmVV/V8+ +OTIhx87YHV+cnWT9JGv+Qsnz2s18E9zj1FEYwBJqAbHd5qytATsvMYB4y3voR03G +AzPeDOdFBNZqQaJyGqYPD+HEuVKYlPx8NC2ew+CEh+h5kPUoO/DgCQJrYA3ZXZKw +dOpieR75EQKBgApgtArq9H5p8QFJ9RCDAbH9IritDoAZEx15Y38i95NigG2Xvhwu +BM/duqjCdZ+kMbw4zsIfg/91oa9OPizW9rFGxyQRrNSqR4w3PQTp2EC52Qa3qCa3 +SaCW824LTxIfTsureBEnbBUL6/KHYsZ4kiV5EAmSo4+/mcLHfYIGlNezAoGAMcw5 +XQW2dJQxpauCzS8llPd7ggS+fpWLxb4/YaHYg813pQ/7tXgqPsgjAS92OH6LfGzi +Kr3fysnwCTqqeU48TDpb72HqeB5WP9K6CooSxyORx0exv3ZgPIUkiVM3yumj4NDY +CqcfuIHd81CFjAp2HDMbrWRRBJvNajTfIK/BuIECgYBJPClPwYzJaXYMlc5rmAgL +lJ9rlbjxRffyLOG4BAsapfGYS789MpoP8WzFPkCNcweXWnI9ftKAE57R/o+a+ov6 +hMlnqI4fij2N9BZuFbVWvpf3th72WU8CE1wpzY10Gp//iePXntJqsiwkr+eStPSL +9H/WjV5NwVwqe+YYC6ABMw== +-----END PRIVATE KEY----- diff --git a/.ci/conf/enabled_plugins b/.ci/conf/enabled_plugins new file mode 100644 index 0000000..9d0383d --- /dev/null +++ b/.ci/conf/enabled_plugins @@ -0,0 +1 @@ +[rabbitmq_management, rabbitmq_stream, rabbitmq_stream_management]. \ No newline at end of file diff --git a/.ci/conf/rabbitmq.conf b/.ci/conf/rabbitmq.conf new file mode 100644 index 0000000..6d1d180 --- /dev/null +++ b/.ci/conf/rabbitmq.conf @@ -0,0 +1,9 @@ +loopback_users.guest = false + +ssl_options.cacertfile = /etc/rabbitmq/certs/ca_certificate.pem +ssl_options.certfile = /etc/rabbitmq/certs/server_certificate.pem +ssl_options.keyfile = /etc/rabbitmq/certs/server_key.pem +listeners.ssl.default = 5671 +stream.listeners.ssl.default = 5551 +ssl_options.verify = verify_peer +ssl_options.fail_if_no_peer_cert = false diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index af2ab1a..b6b9108 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -17,25 +17,52 @@ jobs: python-version: [3.9] os: [ubuntu-22.04] runs-on: ${{ matrix.os }} - services: - rabbitmq-server: - image: rabbitmq:4.0.3-management - ports: - - 5672:5672 - - 15672:15672 + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v4 - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and export + uses: docker/build-push-action@v6 + with: + context: . + tags: rabbitmq_tls:latest + outputs: type=docker,dest=/tmp/rabbitmq_tls.tar + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: rabbitmq_tls + path: /tmp/rabbitmq_tls.tar + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: rabbitmq_tls + path: /tmp + - name: Load image + run: | + docker load --input /tmp/rabbitmq_tls.tar + docker image ls -a + docker run -d --rm --name rabbitmq-stream-client-test \ + -p 5552:5552 -p 5672:5672 -p 5671:5671 -p 5551:5551 -p 15672:15672 \ + -e RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-rabbitmq_stream advertised_host localhost" \ + rabbitmq_tls + - name: wait for running + run: | + docker exec rabbitmq-stream-client-test /bin/bash -c 'ps -aux' + docker exec rabbitmq-stream-client-test /bin/bash -c 'sleep 10' + docker exec rabbitmq-stream-client-test /bin/bash -c 'rabbitmqctl status' + docker exec rabbitmq-stream-client-test /bin/bash -c 'rabbitmqctl wait --pid 1 --timeout 70' - name: Install and configure Poetry uses: snok/install-poetry@v1 with: version: 1.4.2 virtualenvs-create: true virtualenvs-in-project: false - - name: Enable RabbitMQ Plugins - run: docker exec ${{ job.services.rabbitmq-server.id }} rabbitmq-plugins enable rabbitmq_stream rabbitmq_stream_management rabbitmq_amqp1_0 + - name: poetry install run: poetry install --no-root - name: isort check-only diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5adcbfb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM rabbitmq:4-management +#FROM pivotalrabbitmq/rabbitmq:sha-ae9fbb7bd5982aff099293adbb1edcd616ef806f + + +COPY .ci/conf/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf +COPY .ci/conf/enabled_plugins /etc/rabbitmq/enabled_plugins + +COPY .ci/certs /etc/rabbitmq/certs diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3cc9675 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ + +all: test build + +rabbitmq-server: + docker build -t rabbitmq-tls-test . + docker run -it --rm --name rabbitmq-tls-test \ + -p 5672:5672 -p 5671:5671 -p 15672:15672 \ + -e RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-rabbitmq_stream advertised_host localhost" \ + rabbitmq-tls-test + +help: + cat Makefile diff --git a/examples/getting_started/main.py b/examples/getting_started/main.py index 46603bb..fcbb76c 100644 --- a/examples/getting_started/main.py +++ b/examples/getting_started/main.py @@ -1,7 +1,7 @@ # type: ignore -from rabbitmq_amqp_python_client import ( +from rabbitmq_amqp_python_client import ( # SSlConfigurationContext,; SslConfigurationContext,; ClientCert, AddressHelper, AMQPMessagingHandler, BindingSpecification, @@ -59,7 +59,18 @@ def on_link_closed(self, event: Event) -> None: def create_connection() -> Connection: - connection = Connection("amqp://guest:guest@localhost:5672/") + connection = Connection("amqps://guest:guest@localhost:5672/") + # in case of SSL enablement + # ca_cert_file = ".ci/certs/ca_certificate.pem" + # client_cert = ".ci/certs/client_certificate.pem" + # client_key = ".ci/certs/client_key.pem" + # connection = Connection( + # "amqps://guest:guest@localhost:5671/", + # ssl_context=SslConfigurationContext( + # ca_cert=ca_cert_file, + # client_cert=ClientCert(client_cert=client_cert, client_key=client_key), + # ), + # ) connection.dial() return connection diff --git a/rabbitmq_amqp_python_client/__init__.py b/rabbitmq_amqp_python_client/__init__.py index 1f28688..8bcda4f 100644 --- a/rabbitmq_amqp_python_client/__init__.py +++ b/rabbitmq_amqp_python_client/__init__.py @@ -22,6 +22,10 @@ QuorumQueueSpecification, StreamSpecification, ) +from .ssl_configuration import ( + ClientCert, + SslConfigurationContext, +) try: __version__ = metadata.version(__package__) @@ -52,5 +56,7 @@ "AddressHelper", "AMQPMessagingHandler", "ArgumentOutOfRangeException", + "SslConfigurationContext", + "ClientCert", "Delivery", ] diff --git a/rabbitmq_amqp_python_client/connection.py b/rabbitmq_amqp_python_client/connection.py index 7c63883..bd2a11a 100644 --- a/rabbitmq_amqp_python_client/connection.py +++ b/rabbitmq_amqp_python_client/connection.py @@ -7,20 +7,41 @@ from .management import Management from .publisher import Publisher from .qpid.proton._handlers import MessagingHandler +from .qpid.proton._transport import SSLDomain from .qpid.proton.utils import BlockingConnection +from .ssl_configuration import SslConfigurationContext logger = logging.getLogger(__name__) class Connection: - def __init__(self, addr: str): + def __init__( + self, addr: str, ssl_context: Optional[SslConfigurationContext] = None + ): self._addr: str = addr self._conn: BlockingConnection self._management: Management + self._conf_ssl_context: Optional[SslConfigurationContext] = ssl_context + self._ssl_domain = None def dial(self) -> None: logger.debug("Establishing a connection to the amqp server") - self._conn = BlockingConnection(self._addr) + if self._conf_ssl_context is not None: + logger.debug("Enabling SSL") + + self._ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT) + if self._ssl_domain is not None: + self._ssl_domain.set_trusted_ca_db(self._conf_ssl_context.ca_cert) + # for mutual authentication + if self._conf_ssl_context.client_cert is not None: + logger.debug("Enabling mutual authentication as well") + if self._ssl_domain is not None: + self._ssl_domain.set_credentials( + self._conf_ssl_context.client_cert.client_cert, + self._conf_ssl_context.client_cert.client_key, + self._conf_ssl_context.client_cert.password, + ) + self._conn = BlockingConnection(self._addr, ssl_domain=self._ssl_domain) self._open() logger.debug("Connection to the server established") diff --git a/rabbitmq_amqp_python_client/ssl_configuration.py b/rabbitmq_amqp_python_client/ssl_configuration.py new file mode 100644 index 0000000..e272988 --- /dev/null +++ b/rabbitmq_amqp_python_client/ssl_configuration.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class ClientCert: + client_cert: str + client_key: str + password: Optional[str] = None + + +@dataclass +class SslConfigurationContext: + ca_cert: str + client_cert: Optional[ClientCert] = None diff --git a/tests/conftest.py b/tests/conftest.py index eb266cd..005bf6d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,8 +3,10 @@ from rabbitmq_amqp_python_client import ( AddressHelper, AMQPMessagingHandler, + ClientCert, Connection, Event, + SslConfigurationContext, symbol, ) @@ -20,6 +22,26 @@ def connection(pytestconfig): connection.close() +@pytest.fixture() +def connection_ssl(pytestconfig): + ca_cert_file = ".ci/certs/ca_certificate.pem" + client_cert = ".ci/certs/client_certificate.pem" + client_key = ".ci/certs/client_key.pem" + connection = Connection( + "amqps://guest:guest@localhost:5671/", + ssl_context=SslConfigurationContext( + ca_cert=ca_cert_file, + client_cert=ClientCert(client_cert=client_cert, client_key=client_key), + ), + ) + connection.dial() + try: + yield connection + + finally: + connection.close() + + @pytest.fixture() def management(pytestconfig): connection = Connection("amqp://guest:guest@localhost:5672/") diff --git a/tests/test_connection.py b/tests/test_connection.py index 1d2aa4d..b6a7676 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1,7 +1,25 @@ -from rabbitmq_amqp_python_client import Connection +from rabbitmq_amqp_python_client import ( + ClientCert, + Connection, + SslConfigurationContext, +) def test_connection() -> None: connection = Connection("amqp://guest:guest@localhost:5672/") connection.dial() connection.close() + + +def test_connection_ssl() -> None: + ca_cert_file = ".ci/certs/ca_certificate.pem" + client_cert = ".ci/certs/client_certificate.pem" + client_key = ".ci/certs/client_key.pem" + connection = Connection( + "amqps://guest:guest@localhost:5671/", + ssl_context=SslConfigurationContext( + ca_cert=ca_cert_file, + client_cert=ClientCert(client_cert=client_cert, client_key=client_key), + ), + ) + connection.dial() diff --git a/tests/test_publisher.py b/tests/test_publisher.py index 01bb0e5..6391c22 100644 --- a/tests/test_publisher.py +++ b/tests/test_publisher.py @@ -39,6 +39,29 @@ def test_publish_queue(connection: Connection) -> None: assert raised is False +def test_publish_ssl(connection_ssl: Connection) -> None: + + queue_name = "test-queue" + management = connection_ssl.management() + + management.declare_queue(QuorumQueueSpecification(name=queue_name)) + + raised = False + + try: + publisher = connection_ssl.publisher("/queues/" + queue_name) + publisher.publish(Message(body="test")) + except Exception: + raised = True + + publisher.close() + + management.delete_queue(queue_name) + management.close() + + assert raised is False + + def test_publish_to_invalid_destination(connection: Connection) -> None: queue_name = "test-queue"