From f111cdbe0c69235b435c6b20cfc569192efee33d Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 28 Oct 2025 12:56:46 +0100 Subject: [PATCH 1/9] Add connect method --- packages/api/internal/api/api.gen.go | 34 +++ packages/api/internal/api/spec.gen.go | 212 +++++++++--------- packages/api/internal/api/types.gen.go | 9 + .../api/internal/handlers/sandbox_connect.go | 159 +++++++++++++ spec/openapi.yml | 44 ++++ tests/integration/internal/api/client.gen.go | 178 +++++++++++++++ tests/integration/internal/api/models.gen.go | 9 + .../api/sandboxes/sandbox_connect_test.go | 132 +++++++++++ .../api/sandboxes/sandbox_refresh_test.go | 79 +++++++ .../api/sandboxes/sandbox_timeout_test.go | 77 +++++++ 10 files changed, 828 insertions(+), 105 deletions(-) create mode 100644 packages/api/internal/handlers/sandbox_connect.go create mode 100644 tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go create mode 100644 tests/integration/internal/tests/api/sandboxes/sandbox_refresh_test.go create mode 100644 tests/integration/internal/tests/api/sandboxes/sandbox_timeout_test.go diff --git a/packages/api/internal/api/api.gen.go b/packages/api/internal/api/api.gen.go index d56e9a00ef..ef14190759 100644 --- a/packages/api/internal/api/api.gen.go +++ b/packages/api/internal/api/api.gen.go @@ -59,6 +59,9 @@ type ServerInterface interface { // (GET /sandboxes/{sandboxID}) GetSandboxesSandboxID(c *gin.Context, sandboxID SandboxID) + // (POST /sandboxes/{sandboxID}/connect) + PostSandboxesSandboxIDConnect(c *gin.Context, sandboxID SandboxID) + // (GET /sandboxes/{sandboxID}/logs) GetSandboxesSandboxIDLogs(c *gin.Context, sandboxID SandboxID, params GetSandboxesSandboxIDLogsParams) @@ -501,6 +504,36 @@ func (siw *ServerInterfaceWrapper) GetSandboxesSandboxID(c *gin.Context) { siw.Handler.GetSandboxesSandboxID(c, sandboxID) } +// PostSandboxesSandboxIDConnect operation middleware +func (siw *ServerInterfaceWrapper) PostSandboxesSandboxIDConnect(c *gin.Context) { + + var err error + + // ------------- Path parameter "sandboxID" ------------- + var sandboxID SandboxID + + err = runtime.BindStyledParameterWithOptions("simple", "sandboxID", c.Param("sandboxID"), &sandboxID, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter sandboxID: %w", err), http.StatusBadRequest) + return + } + + c.Set(ApiKeyAuthScopes, []string{}) + + c.Set(Supabase1TokenAuthScopes, []string{}) + + c.Set(Supabase2TeamAuthScopes, []string{}) + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.PostSandboxesSandboxIDConnect(c, sandboxID) +} + // GetSandboxesSandboxIDLogs operation middleware func (siw *ServerInterfaceWrapper) GetSandboxesSandboxIDLogs(c *gin.Context) { @@ -1272,6 +1305,7 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options router.GET(options.BaseURL+"/sandboxes/metrics", wrapper.GetSandboxesMetrics) router.DELETE(options.BaseURL+"/sandboxes/:sandboxID", wrapper.DeleteSandboxesSandboxID) router.GET(options.BaseURL+"/sandboxes/:sandboxID", wrapper.GetSandboxesSandboxID) + router.POST(options.BaseURL+"/sandboxes/:sandboxID/connect", wrapper.PostSandboxesSandboxIDConnect) router.GET(options.BaseURL+"/sandboxes/:sandboxID/logs", wrapper.GetSandboxesSandboxIDLogs) router.GET(options.BaseURL+"/sandboxes/:sandboxID/metrics", wrapper.GetSandboxesSandboxIDMetrics) router.POST(options.BaseURL+"/sandboxes/:sandboxID/pause", wrapper.PostSandboxesSandboxIDPause) diff --git a/packages/api/internal/api/spec.gen.go b/packages/api/internal/api/spec.gen.go index 6b99622196..8fe966e1aa 100644 --- a/packages/api/internal/api/spec.gen.go +++ b/packages/api/internal/api/spec.gen.go @@ -18,111 +18,113 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+w9W1PcOLp/ReVzHnaqOkBIduoMVftASDKbnZChaMicqgyVEvbX3Vps2SPJQC/Ff9/S", - "zZZtyXY3zSUJTwltWZfvru/mmyjOsyKnQAWP9m6iAjOcgQCm/sJxDJyf5BdAP7yVPxAa7UUFFotoElGc", - "QbTXGjOJGPxVEgZJtCdYCZOIxwvIsHxZLAv5AheM0Hl0ezuJcEF+g2V4avt4tVnPS5ImwUnt09XmpHkC", - "wSnNw9Vm5Jgm5/l1cNL6+WrzCsBZcFLzcNUZsyLFAnpmrQasMvOtHMyLnHJQ1PZ6Z0f+E+dUABWK/ooi", - "JTEWJKfb/+Y5lb/V8/0vg1m0F/3Pdk3C2/op337HWM70GgnwmJFCThLtRW9wguQWgYvodhK93nl5/2vu", - "l2IBVJhZEehxcvFX97/4+5ydkyQBqld8ff8rfsoFmuUlTfSKv9z/igc5naUkVhj9+0NQ0RTYJTCLyVtL", - "5YqM9/+YHsOccMGWSqKyvAAmiKZxfMX3lcCUgi2Rv7RI5Y8p0gPQb7BEH96iWc7Qu4NjhBtEFE3a7DSR", - "c8uF9QG70+pn6GoBDJBYgJqVmZ0iwlGax1hAEph6CjEDUW3ev4Ye5J5g/Pb1D+1ZT5YFoHxWb7QzEdAy", - "i/a+yD1GZxOP/Kol0hf9dNJGg/eALkDrefPzf4MmtDdSkXzM5++oF9MpXEI6RGAf8/lHNe52EmXAOZ57", - "QPAxnyPzEFmy9sCPCyi6L08FFIhQhXCl+lDBcoUdBlJmJ0jk6mGazxGoo/hwQzLgAmeeBU7sI4ml9kSz", - "nGVYRHtRggW8kLNEgxiqlqpBMjHQPLNgnwosSn4M2LBzC/QaKeavBGa4TEW09+Vs4oEs6JFtcHC1AmJ6", - "iUlEBGR8CJ1NkqhoOsKM4WUvjg8Nfq+IWHTXn6C4ZAyoSJeIQZEzQegc5TTV/KXEkHljRcoQCyzQDJPU", - "x/ctzNjNSywcHJ0e5KWWry1ZfHSK4pwBV1tTR9GWjEsOhIpXuxLBhJJMsu/LanFCBcxB6ccDBhIl+7WF", - "2cV1bMaIAcrUZioSchakXtLSYwyFTiLiEdUfEimGZgSYpXx3DXfqsiReqZphfjFEUvUqh5hfEDp/CwKT", - "lMv3tfnV3tcnnEFgR12+tkBtQW4BaFam6RIZ8A5M1CIUdVq1ObuCOevEQddZjeATwNn+0QejVdbD7/7R", - "B3QBy9VRaxZ4o9bGafr7LNr70o8Tud9TLmn0bBLRMk3xeQra3h1NK2a/Y8jkwqdtj/EVusRpCd0JOxOk", - "mItTDp59fcRcIAkZJBaEV0C8whyVXIkELxCbZ34Uyg4e10eLeqAhQUOYTUp8S/jFIQhGYt6lwQQuSezZ", - "z1v1O7KU3gbCjKTAl1xAduI1bd5Xz5F8F/0NtuZbEwTX4vUEXc/4T16ZIaXuUU58ovdQPkOFfGjBlBB1", - "Zg/jC5y+WQp7wAZfyWeIFzgGaTmcq1EunRIqfn4d+SS2JJrArJIA15m0rYTq808sYjqgdjfSOKtF9ZT8", - "Bw7feDBK+AXi5D/QVl5yz4fkTa8O2/FB5B29/IyNNyVJiFwHp0ct8nK38I5eEpbTDKhAl5gRyWc+Xdol", - "+3f0MvkMjHtvAOaBpQuglwliJaXSkDDmYXDuSaQvQl3hnCceulaDkXrmAVcXREGjSK86xOFmIdc6ec/y", - "7EOG5+BexBIi584IxUKfJcNFISfU17KQmHKvc5NoHhehgb8eHDkDWbVyYDRQYDit3ridWNguPxmvijz1", - "7STKKYzQSe42byf9Y92dDo5t71PC152gQxQcmOTK/TiWrPov7qPGqR6DzCD0r+nvnxSN/3pw9ABXRYnF", - "sVdFz3F8t8E2nDpgKTDnVznzKOEj80RePUpeix5WU9PGIVDNfeaZvOTA/Br41DwZv1U/UKsVJjVcfFAN", - "2ggd8ErlDslnaREdMZiRaw+c1e/KsJEiT7+BLpuCUV8QchaypZx1puXMu47+/Y7rFP2HUPc2YqHDO1Mi", - "A+jOvMpm/Ah0LhYec1D93r/FkGI2G26uMPHgxQdDKVQ+Ei4gmRol1PWcpQR71OW+/LnasXFEe+38lAAV", - "2oedQMFAO7uMBTtkruu3vfMWZXUT7hOk1Y35diJVkWOC9L3lGCu3knuDFyF0tYCGGkdXJE0RXBeEwejL", - "EDRNiF7fqDNUKfEsZ8vhAx3aceodgRMsBt2whiYO7fB29GQIeT2GDReY9VwvPVDFHJmXRkOVC0mT4w45", - "VWM7UZehI9rRaMbyDF0tSLxAhDd2bi48wyLajea4UaiKg1ywOQzgEEGDxC3dWkA0yUyxvnWDepxU8lAd", - "PFo1lsB5OY8mEaGzPJpEV5gpJafsRp9mO8TX8vKub3oelAPOUKYeGk+c44xsiqOWR7RfnnR8pGaNVdyk", - "jhP2lPo0Q+8iUhHJ1/Rl/28c4pwmHHFCY0BQ5PHip5axHrjhKenu9xhl+FpehJpuCRNrg8Rux1w25uQS", - "KJITs0uc1kvRMjv3aBcXEU042C1JOjqMi56LVieKc3hwhOKczsi8ZDo0171mBVwdtYly6Ai+tk9XPlnn", - "Jvly9/98sP8EV72+0Lv6A1swV9Od6XV71HKaX31VeKQgvuoFfGo6za8qEIi82skCkH253tB5nqeAlV7B", - "pciPcMmh4cqf4ZSDJ8yaZ1gau2m6RIV8qSkB8UyAxoUkobz0rwj1jX1A/6lhUo9psutVe3FxV40HccnA", - "d5WSvyOcpsg4k+I8y0pqo81KjnU0oHPe1RSNJZBeW8uC10XZy7/7pKIkhZRcev0tRkhtrep0CeszQ8x9", - "/ubNeR5r9jFekpbvJC25ADYO6maw1/7Ms4z44jDqdztBzuIFcMGU7yPoBX9v71at0yuZLKdq2hIqcDTW", - "NahfmZaK72GVVXj1zriVxjngqXYbdS94tRe4j0MlUq3DuJEftPrdguYZToL7McAIRNs6QANeufVy6h60", - "AbmAJ45XNqiKMA6vaQaiqV28xav+VbRH5QPlAtPYK3esf4iYMfVVdxB/Jgw6An06iKyMmpFe034uavO/", - "zQpTIYjuoSeOCKi23cJ3TY5dBmoybQB59dkqSWFFknaleAQTjheQqFC2h0vlLV2CQ4/SKQUckaRFbVW4", - "POC5qkPiz3LwWQ6uIAehhyaHROCoHI6mG8pDsM/ia4T40vLJlSTDAqwjqWoitDLLCdG2cw4Te+Hlnbu6", - "vKMoSjw4Ou3jt2ocqpJYRirO6k195wuEQPdV8LK5knaZrBpndZ2OvuAtrc5Up+Osbg7ERXkELAavESAB", - "LicvVd5SocfpZK0xcyeEX3BfSF2oZCSLS53fhOOFimRvZ3WEeyw/u5F9b0aWhP/JYDicagJbB1n6rdNw", - "aPyTM7eNGqwdIG8Qe4AyG6jtbtDj03MAZHFneXJaSayu667kLXlXx59wIq9QCcNESmrF9JRCLPQfJV0A", - "TsXCE6CaRNcv5DQvLrGKIXE5X72RYzNz/cvbeo36xwN3tfrn03rdxvEOFpjON3eLG8z5WV0NtMjATCBP", - "cQy8zPoiK00XS7/a3pCT5ZE9BLeT6JsLNCV5holHyb/BHJB+6CR3V642hmczEiPCjcuNnKejUriAXrYz", - "L1sAcTMqldhSsppeJk0P1GbjTJsK/Dzp8Eo7PmJoNXRjew6NPgJ3PEAk9gmy33OY9znMu3aY15z9Yz73", - "F7noSGUz8IowTVBKKHRudepH7zzySV+lzCNVs6gNN+EQqB2aETDOt1DOaMitVsclH7z+6LGgqvbv1goZ", - "6DUhzYfLhJqXF1bGomSQyL3yrogZdfdsI9pz/0zN1jogv/ua3eVaYFRrT1w4ODA7dKT2uMxl+8agPG4s", - "4k3EOHRTF8YKhLBT5FPXHTIuNTkuSnktPooDhU59zo9ZmmPRTWzQMlPdp0O+hkRloQdT5cOeBvmiv9BD", - "JbYHfQu9voverfZ4RHon9e/ycMAHEp7yx0zHWSFJxlHfDlHXuHBQ7dCRS6yObJhaS2elZC3jlFc5v6q6", - "yJehVUUS/yBiEazIaQQDQtJpnK0p5c9tx3tSzS9PfQI489y6VHcKj2Fuiqisv0LIt301hfyt9Xy0p/hj", - "AWIB9evWxjOuktaUjltlOHshtJu6bcSwDeqboWNdmkYTJsvbAMs9tYXsc+Vf0Av4wxfuGerxFo9uKJEz", - "zqkprp6GI4wnC3BiKvUrTsixxe4jjAs3YH/sFai+7A5zJ5NGh/F/jjI6nhXkkIL00IEHR5bylBToyCzI", - "jIOuVcgmf7bHLLk/gWGc9DBvD4gOHy/pven9G1+g35MIIV8i+LyJ4zM9VK7IoIWu8NJ0dkipJl8W4/jK", - "6f80BE0pYG1exaxMTYcMyco6P7nPa3peN6IYkpgW4E7vinX9owNasfZkNaBXO4UeSTWuX/GyrqdSonZa", - "4Cu6MrAUUdxNi67hJS3K89Snypq2oNkm4UiPRznTfUBq9zU6X3rsNMdI5BIq6/JhGy49V7K1PJs+aiyL", - "ZA2a12jUr67pZnJdpHXfuBGeUINMl13dY7gM1qbUBn4aQrPJDZNKWDdFkSvglbzpSvkVBKQa6jVNx/bY", - "UXvQTjReOdU21lCndp+N2MBK2opVzYUGN9joRjQ6eB9QCptim3G0XOVt+X2BjT2+JymcFmmOPSRVMODe", - "PCFXfM1IqkQXTlX6BzIv2ZIglS7mlVgl8xhVpyx1Inpqbr7IyzRB54BKtU/VzmkQNHbvnQMfmz6Bmw+4", - "rhMYzeMLYPKYHu9e9cy5hoSXX0c9KYwdZB4bVSXcoHgB8YWKPGKqKtnhGuJSgEVuJZrr/JCgbFFXHO9a", - "yg7f0Cob9ng4+AkR0ufdp0FK6+B/w9DSx+4ASuHXB6ZZzuIRJWCutLla5KnteVcLBjWRIh1WUsRgjlmS", - "Aq9gHRZCM9tUxAME+bPtiYA5wugc8y4vhmlx5mtY0oeabocTM4t7t2v7RMwu7rDP708KcAHFYJtAm18u", - "x/atZ1cZZdtYfEwFFN5QXSek67MYBtIuO1uzznj1t/bGX2Fi8iBtVma4gLqx6d5mk82VbdfJbm42GzTg", - "9tm8zCTo6hRAufoqxpzqD/VPzD09L+SvFlpqWBV+clbqMuzq8khOtRFB1N/7JbxrXysWVwKfqvtJ0Oh5", - "qAuq3Kfeyhp1mnCl2rFVlLJisaatsyViOZVsqtdy8rD2S9035RwwA/be3in14b7aumrF4upQali9+kII", - "xev7SUZoY0LVVnsBOFHDTWPt/3+hBr44adZrm2CKnEf9b2iOow8vfnNhUL8/LQssVcDLMXuxg8PbsSN2", - "FebGztYgAzuZRIXq6qB6LQhp9Ubvdt9IhDqlInvRztbLrR3VJqsAigsS7UWvtna2dlSUUSwU/rY1el4o", - "9Ghazrkvoq/rrDCicNUulZe0p8JLH5JoLzrKuXCogpu+58DFmzxZbqz/dKvgvxWmNK61Rg/13Q32M/e0", - "X/U1N+80VoXEcammS6fNum+1avvbclDdwLt/rBzkcqtyT/qo+cvZrdRjeK7KBJqEoPi9SRzbN43vGdxq", - "IklBeNs/yt8Rpv20ooe51LLf+mSC+9GFgJe1HrLd/OCCPF2LAl4PJIvq89wNSaaR/NDY14+C0IK8uICl", - "gsYcRKBeEKepjq0bFcE7iPsVhJavmr0bMF6tx/xIe7DSdl1rsNuB3kEeYiBKRiHxHOqRmc+rE1ootOiS", - "tsgIweyezy+YHaTdi0x2MfUoIrm9AU/wu5EV8cQk8mpE4bL09o39JswoydxPK0Ywa2rZr781s6I4ti+O", - "k8QN5Hzrknhl7sYi9lzBtLU/hK4j+fKGsbV58dC5uYySEDsDhGJCRz8IoUiO12WYQRX+T/VY+5t8ils/", - "j8YA2lx4dclHBd/VoKuQvE3zBEZYHXqYZ9OfzIPN2BrjwvaqOZFq6ru+xaEP9GBKpX15btGRfGqISG1s", - "+0a3MrgNYuZXELq+27QR9CPmk22IsJrEMX0Ubier1AerO/NfJahsK3NlbrRbqNA9lAh0dkdyGqIdU5M4", - "ml6qWvAnKb3GkVbQTFVF4vbTLflMGqy67L1rpG6CpO5JhXWq3m+732rz2zYGtxYCKvNITfEtaK7xYqWR", - "fd4v620jGrctSke8uAmHLUoIVNgo0aAd1SJHM5LaOEedJ6q+JoH+VK22/4HP4z/LnZ3dn3FR/KNgefJn", - "9NMWeofjhTIvME10106OspILdA7o9PgjAhrnCSRbAYFU1XX2feTv7GHVWat7z930Whd5ihh3xhDjzgPq", - "Q8cJ/OVMKpq1jbBm3cPAZdxWnKpa1FacuivwXCK/p3t5hfaHvZQ3lu1KRLekOHwb/0GIqiE+t50eY2Ex", - "6nYC0lm544TpYd0Nqk+mHuRZhl9wkIMkatJmMzH04a0K+c6hsZNoEsF1karOniby5xORZpKvJOG9n0YN", - "RzIzfP1BP3y5s9MSZpOopOSvEswARef3avB5i7PuJlJ1eUZWN2j6QVnhpirB7/Vs/UbStBa9AZdWhaap", - "U9a/molZNwQY6dZqCboLkqbfhtV3X8ozeNOsFef5Eqk7W1iG3RMCNy4R1rkF8rrF4g9DFkGe37aJzEGy", - "sURjEnVH0MxHPXJtupl4866k9Baefg5cf5OmTnCpkE0oykiaElPEFbhNqHQvv2vD1hj0N/3uXJbM5wjq", - "ur2+XQZ2lRLdiLLeVd2ubEcq5NX6jj0AKyqsr8OImrKeuVFy45Bh6jJk3XV0BE8GjdI7sGVVJ6lZsk6S", - "w6zqe2w/tDFx2uZN1FDdRKiuv7xH/vRNC6p+1WWvEUcDmqx3sNW2fPYQYf9WJ4J1/RUuIz+ANf2d8n1h", - "22D6XR+qS2aru0WPp6Piet1d86FtcN1lo2GDK09fjKnWfKot6H1i/vXOL2PG/vKNUQmDGQO+gJ5UwmM9", - "pMGWcC2AJuqDq4Kb5g26t+lIMjqu1r0rKa3nfmt9Fdl8NMmTfuF+TqkWwxYOtfF1AYVAWHV3raW36vdw", - "raXyq5+ljTXwsZdWnvzIYEVLjGrIPtDN5AlQsOT9PvKVz9eQdPrFR6LPPjXbaoL8dF3ERiw/mOvkO5XR", - "ToNpP4lPQbhdqtvtpbfQib+DK7q2gsoJfJCs/cG7LXSA01RdlheES5NskScoK1NBihRMdX1+CeyKEWEK", - "7U9OPk50s3s1Ycn164BstxmnCR6vbXw5Sn/0XeQoA8xLUxNrj2Yl9dZIJj6pGnc/vpZpNApvV/7Lw9WK", - "o8aHCy9TBBZUQ92+vOt8Y8zs8mwj2ogb0qy6FJvZfzQbXQDORmZxe6/fJ+bBQwagVTXLHePO+kAPF99o", - "lzf1obGREyF/c1C1faOrhMf5T9y4nlMO5sfiiZp4Xe+JKV5+dp18X64TpwPcnfwmou4Wd89Ok1djxr56", - "MgJ5kMG3M3zdy+TC+S6wj+GDnwMeIQYO8fWzJHjykmAS6O0scsmEjMAlNKhEfz1ap1gEss6Yaq0Uzqaw", - "Ne51S7+vvNvT76tCxlemuvo9bOJs8zPkz7Jq47JK56GNsh3tUK/IqR+2xIyPMquetyFGHN0r5eyhbVaT", - "t3dnu9XC6xFzc9a2Zuvdjy5E7El3dGnnPvxZ3kZVo7xauxvfQ8itpTt/XGH9cZ1C2GDDk0vw2gTJNASP", - "NJRsv7WxlYoBYtIjKnI6cfu4rWr7VK+ODyg1Wipuol7xKfJ6b1limM3la/eCmPsTF80eL2vXJna6ggbr", - "E59+Mue9Koxj0EIQ05Hq4tsgo29R63wHmmRbf259+8Y08LztCW+oi6vb+mwU0emPNb+p+oOuT4GTwdG2", - "C6lHGe36ZY5G7cL5Ntt3i9ntuols2LnSbLEWql4dQvPU9oB9EGR362BpAtd15zIT0Dq3XXuDaaX6uw6t", - "ZvS+FM58zn+fzTgE8jhXTuIMOGHsh8jGSbH6y2v36mlodoJe0dNg5eyTDDv5+XGsQ2ENDlXNAbdvFpgv", - "+kvJMTXth1FK6IVyo2EkMNM9iiVa9feoLY3jJehnfCT3vq+6Gd6RZxUZF1g1SjBUvNDThp1rA90TR3kz", - "Xt4PfTsNqgO2gYsX0zs6tz8qmjdY+g5SJ++PPy53V6mA7i3W+7z7Pdc+d1Tde73ZeqPnS5RTQDlDWc50", - "3byCxKjaQvOV1fXyjesP0LZapXKxVM0WpU70aOuDkvGcScjzysJUJZMzlmcBYFG4Fidua8xx0OoWcKgD", - "mshByaj6BlKhP7u4evFGn9p/eZ8hzedK9kfIJbncbYYF7urf/bz7GB7ez7tP97ZtYPBdVbcPqMEHuaU7", - "lPYU7un3TOj2CwDjyfxpuQnuSlhqQnZpEam+fKLaRvO97W1ckC3YPd/CRRE5M9zUEcg6AHfT6kHQ/FFF", - "S92/G31U3Qe2Ldvt2e1/AwAA///zg27DLbgAAA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/packages/api/internal/api/types.gen.go b/packages/api/internal/api/types.gen.go index 7b48695a4a..a458178bed 100644 --- a/packages/api/internal/api/types.gen.go +++ b/packages/api/internal/api/types.gen.go @@ -119,6 +119,12 @@ type BuildStatusReason struct { // CPUCount CPU cores for the sandbox type CPUCount = int32 +// ConnectSandbox defines model for ConnectSandbox. +type ConnectSandbox struct { + // Timeout Timeout in seconds from the current time after which the sandbox should expire + Timeout int32 `json:"timeout"` +} + // CreatedAccessToken defines model for CreatedAccessToken. type CreatedAccessToken struct { // CreatedAt Timestamp of access token creation @@ -968,6 +974,9 @@ type PostNodesNodeIDJSONRequestBody = NodeStatusChange // PostSandboxesJSONRequestBody defines body for PostSandboxes for application/json ContentType. type PostSandboxesJSONRequestBody = NewSandbox +// PostSandboxesSandboxIDConnectJSONRequestBody defines body for PostSandboxesSandboxIDConnect for application/json ContentType. +type PostSandboxesSandboxIDConnectJSONRequestBody = ConnectSandbox + // PostSandboxesSandboxIDRefreshesJSONRequestBody defines body for PostSandboxesSandboxIDRefreshes for application/json ContentType. type PostSandboxesSandboxIDRefreshesJSONRequestBody PostSandboxesSandboxIDRefreshesJSONBody diff --git a/packages/api/internal/handlers/sandbox_connect.go b/packages/api/internal/handlers/sandbox_connect.go new file mode 100644 index 0000000000..1c7785ab58 --- /dev/null +++ b/packages/api/internal/handlers/sandbox_connect.go @@ -0,0 +1,159 @@ +package handlers + +import ( + "database/sql" + "errors" + "fmt" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "go.opentelemetry.io/otel/trace" + "go.uber.org/zap" + + "github.com/e2b-dev/infra/packages/api/internal/api" + "github.com/e2b-dev/infra/packages/api/internal/auth" + "github.com/e2b-dev/infra/packages/api/internal/db/types" + "github.com/e2b-dev/infra/packages/api/internal/sandbox" + "github.com/e2b-dev/infra/packages/api/internal/utils" + "github.com/e2b-dev/infra/packages/db/queries" + "github.com/e2b-dev/infra/packages/shared/pkg/logger" + sbxlogger "github.com/e2b-dev/infra/packages/shared/pkg/logger/sandbox" + "github.com/e2b-dev/infra/packages/shared/pkg/telemetry" +) + +func (a *APIStore) PostSandboxesSandboxIDConnect(c *gin.Context, sandboxID api.SandboxID) { + ctx := c.Request.Context() + + // Get team from context, use TeamContextKey + teamInfo := c.Value(auth.TeamContextKey).(*types.Team) + + span := trace.SpanFromContext(ctx) + traceID := span.SpanContext().TraceID().String() + c.Set("traceID", traceID) + + telemetry.ReportEvent(ctx, "Parsed body") + + body, err := utils.ParseBody[api.PostSandboxesSandboxIDConnectJSONRequestBody](ctx, c) + if err != nil { + a.sendAPIStoreError(c, http.StatusBadRequest, fmt.Sprintf("Error when parsing request: %s", err)) + + telemetry.ReportCriticalError(ctx, "error when parsing request", err) + + return + } + + sandboxID = utils.ShortID(sandboxID) + sandboxData, err := a.orchestrator.GetSandbox(sandboxID) + if err == nil { + switch sandboxData.State { + case sandbox.StatePausing: + zap.L().Debug("Waiting for sandbox to pause", logger.WithSandboxID(sandboxID)) + err = a.orchestrator.WaitForStateChange(ctx, sandboxID) + if err != nil { + a.sendAPIStoreError(c, http.StatusInternalServerError, "Error waiting for sandbox to pause") + + return + } + case sandbox.StateKilling: + a.sendAPIStoreError(c, http.StatusNotFound, "Sandbox can't be resumed, no snapshot found") + + return + case sandbox.StateRunning: + zap.L().Debug("Sandbox is already running", + logger.WithSandboxID(sandboxID), + zap.Time("end_time", sandboxData.EndTime), + zap.Time("start_time", sandboxData.StartTime), + zap.String("node_id", sandboxData.NodeID), + ) + + c.JSON(http.StatusOK, sandboxData.ToAPISandbox()) + + return + default: + zap.L().Error("Sandbox is in an unknown state", logger.WithSandboxID(sandboxID), zap.String("state", string(sandboxData.State))) + a.sendAPIStoreError(c, http.StatusInternalServerError, "Sandbox is in an unknown state") + + return + } + } + + timeout := time.Duration(body.Timeout) * time.Second + if timeout > time.Duration(teamInfo.Limits.MaxLengthHours)*time.Hour { + a.sendAPIStoreError(c, http.StatusBadRequest, fmt.Sprintf("Timeout cannot be greater than %d hours", teamInfo.Limits.MaxLengthHours)) + + return + } + + lastSnapshot, err := a.sqlcDB.GetLastSnapshot(ctx, queries.GetLastSnapshotParams{SandboxID: sandboxID, TeamID: teamInfo.Team.ID}) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + zap.L().Debug("Snapshot not found", logger.WithSandboxID(sandboxID)) + a.sendAPIStoreError(c, http.StatusNotFound, "Sandbox can't be resumed, no snapshot found") + + return + } + + zap.L().Error("Error getting last snapshot", logger.WithSandboxID(sandboxID), zap.Error(err)) + a.sendAPIStoreError(c, http.StatusInternalServerError, "Error when getting snapshot") + + return + } + + autoPause := lastSnapshot.Snapshot.AutoPause + snap := lastSnapshot.Snapshot + build := lastSnapshot.EnvBuild + + nodeID := &snap.OriginNodeID + + alias := "" + if len(lastSnapshot.Aliases) > 0 { + alias = lastSnapshot.Aliases[0] + } + + sbxlogger.E(&sbxlogger.SandboxMetadata{ + SandboxID: sandboxID, + TemplateID: build.EnvID, + TeamID: teamInfo.Team.ID.String(), + }).Debug("Started resuming sandbox") + + var envdAccessToken *string = nil + if snap.EnvSecure { + accessToken, tokenErr := a.getEnvdAccessToken(build.EnvdVersion, sandboxID) + if tokenErr != nil { + zap.L().Error("Secure envd access token error", zap.Error(tokenErr.Err), logger.WithTemplateID(build.EnvID), logger.WithBuildID(build.ID.String()), logger.WithSandboxID(sandboxID)) + a.sendAPIStoreError(c, tokenErr.Code, tokenErr.ClientMsg) + + return + } + + envdAccessToken = &accessToken + } + + sbx, createErr := a.startSandbox( + ctx, + snap.SandboxID, + timeout, + nil, + snap.Metadata, + alias, + teamInfo, + build, + &c.Request.Header, + true, + nodeID, + snap.BaseEnvID, + autoPause, + envdAccessToken, + snap.AllowInternetAccess, + nil, + ) + if createErr != nil { + zap.L().Error("Failed to resume sandbox", zap.Error(createErr.Err)) + a.sendAPIStoreError(c, createErr.Code, createErr.ClientMsg) + + return + } + + c.JSON(http.StatusCreated, &sbx) +} diff --git a/spec/openapi.yml b/spec/openapi.yml index e57d3e448d..1602b0c4a7 100644 --- a/spec/openapi.yml +++ b/spec/openapi.yml @@ -478,6 +478,17 @@ components: deprecated: true description: Automatically pauses the sandbox after the timeout + ConnectSandbox: + type: object + required: + - timeout + properties: + timeout: + description: Timeout in seconds from the current time after which the sandbox should expire + type: integer + format: int32 + minimum: 0 + TeamMetric: description: Team metric with timestamp required: @@ -1620,6 +1631,7 @@ paths: /sandboxes/{sandboxID}/resume: post: + deprecated: true description: Resume the sandbox tags: [sandboxes] security: @@ -1650,6 +1662,38 @@ paths: "500": $ref: "#/components/responses/500" + /sandboxes/{sandboxID}/connect: + post: + description: Returns sandbox info if the sandbox is running, resumes it if it is paused. The timeout is set only if the sandbox is paused. + tags: [sandboxes] + security: + - ApiKeyAuth: [] + - Supabase1TokenAuth: [] + Supabase2TeamAuth: [] + parameters: + - $ref: "#/components/parameters/sandboxID" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ConnectSandbox" + responses: + "201": + description: The sandbox was resumed successfully + content: + application/json: + schema: + $ref: "#/components/schemas/Sandbox" + "409": + $ref: "#/components/responses/409" + "404": + $ref: "#/components/responses/404" + "401": + $ref: "#/components/responses/401" + "500": + $ref: "#/components/responses/500" + /sandboxes/{sandboxID}/timeout: post: description: Set the timeout for the sandbox. The sandbox will expire x seconds from the time of the request. Calling this method multiple times overwrites the TTL, each time using the current timestamp as the starting point to measure the timeout duration. diff --git a/tests/integration/internal/api/client.gen.go b/tests/integration/internal/api/client.gen.go index b2440d179b..d7fab77a19 100644 --- a/tests/integration/internal/api/client.gen.go +++ b/tests/integration/internal/api/client.gen.go @@ -144,6 +144,11 @@ type ClientInterface interface { // GetSandboxesSandboxID request GetSandboxesSandboxID(ctx context.Context, sandboxID SandboxID, reqEditors ...RequestEditorFn) (*http.Response, error) + // PostSandboxesSandboxIDConnectWithBody request with any body + PostSandboxesSandboxIDConnectWithBody(ctx context.Context, sandboxID SandboxID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostSandboxesSandboxIDConnect(ctx context.Context, sandboxID SandboxID, body PostSandboxesSandboxIDConnectJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetSandboxesSandboxIDLogs request GetSandboxesSandboxIDLogs(ctx context.Context, sandboxID SandboxID, params *GetSandboxesSandboxIDLogsParams, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -461,6 +466,30 @@ func (c *Client) GetSandboxesSandboxID(ctx context.Context, sandboxID SandboxID, return c.Client.Do(req) } +func (c *Client) PostSandboxesSandboxIDConnectWithBody(ctx context.Context, sandboxID SandboxID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostSandboxesSandboxIDConnectRequestWithBody(c.Server, sandboxID, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PostSandboxesSandboxIDConnect(ctx context.Context, sandboxID SandboxID, body PostSandboxesSandboxIDConnectJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostSandboxesSandboxIDConnectRequest(c.Server, sandboxID, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) GetSandboxesSandboxIDLogs(ctx context.Context, sandboxID SandboxID, params *GetSandboxesSandboxIDLogsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetSandboxesSandboxIDLogsRequest(c.Server, sandboxID, params) if err != nil { @@ -1378,6 +1407,53 @@ func NewGetSandboxesSandboxIDRequest(server string, sandboxID SandboxID) (*http. return req, nil } +// NewPostSandboxesSandboxIDConnectRequest calls the generic PostSandboxesSandboxIDConnect builder with application/json body +func NewPostSandboxesSandboxIDConnectRequest(server string, sandboxID SandboxID, body PostSandboxesSandboxIDConnectJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostSandboxesSandboxIDConnectRequestWithBody(server, sandboxID, "application/json", bodyReader) +} + +// NewPostSandboxesSandboxIDConnectRequestWithBody generates requests for PostSandboxesSandboxIDConnect with any type of body +func NewPostSandboxesSandboxIDConnectRequestWithBody(server string, sandboxID SandboxID, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "sandboxID", runtime.ParamLocationPath, sandboxID) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/sandboxes/%s/connect", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + // NewGetSandboxesSandboxIDLogsRequest generates requests for GetSandboxesSandboxIDLogs func NewGetSandboxesSandboxIDLogsRequest(server string, sandboxID SandboxID, params *GetSandboxesSandboxIDLogsParams) (*http.Request, error) { var err error @@ -2547,6 +2623,11 @@ type ClientWithResponsesInterface interface { // GetSandboxesSandboxIDWithResponse request GetSandboxesSandboxIDWithResponse(ctx context.Context, sandboxID SandboxID, reqEditors ...RequestEditorFn) (*GetSandboxesSandboxIDResponse, error) + // PostSandboxesSandboxIDConnectWithBodyWithResponse request with any body + PostSandboxesSandboxIDConnectWithBodyWithResponse(ctx context.Context, sandboxID SandboxID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostSandboxesSandboxIDConnectResponse, error) + + PostSandboxesSandboxIDConnectWithResponse(ctx context.Context, sandboxID SandboxID, body PostSandboxesSandboxIDConnectJSONRequestBody, reqEditors ...RequestEditorFn) (*PostSandboxesSandboxIDConnectResponse, error) + // GetSandboxesSandboxIDLogsWithResponse request GetSandboxesSandboxIDLogsWithResponse(ctx context.Context, sandboxID SandboxID, params *GetSandboxesSandboxIDLogsParams, reqEditors ...RequestEditorFn) (*GetSandboxesSandboxIDLogsResponse, error) @@ -2987,6 +3068,32 @@ func (r GetSandboxesSandboxIDResponse) StatusCode() int { return 0 } +type PostSandboxesSandboxIDConnectResponse struct { + Body []byte + HTTPResponse *http.Response + JSON201 *Sandbox + JSON401 *N401 + JSON404 *N404 + JSON409 *N409 + JSON500 *N500 +} + +// Status returns HTTPResponse.Status +func (r PostSandboxesSandboxIDConnectResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostSandboxesSandboxIDConnectResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetSandboxesSandboxIDLogsResponse struct { Body []byte HTTPResponse *http.Response @@ -3654,6 +3761,23 @@ func (c *ClientWithResponses) GetSandboxesSandboxIDWithResponse(ctx context.Cont return ParseGetSandboxesSandboxIDResponse(rsp) } +// PostSandboxesSandboxIDConnectWithBodyWithResponse request with arbitrary body returning *PostSandboxesSandboxIDConnectResponse +func (c *ClientWithResponses) PostSandboxesSandboxIDConnectWithBodyWithResponse(ctx context.Context, sandboxID SandboxID, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostSandboxesSandboxIDConnectResponse, error) { + rsp, err := c.PostSandboxesSandboxIDConnectWithBody(ctx, sandboxID, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostSandboxesSandboxIDConnectResponse(rsp) +} + +func (c *ClientWithResponses) PostSandboxesSandboxIDConnectWithResponse(ctx context.Context, sandboxID SandboxID, body PostSandboxesSandboxIDConnectJSONRequestBody, reqEditors ...RequestEditorFn) (*PostSandboxesSandboxIDConnectResponse, error) { + rsp, err := c.PostSandboxesSandboxIDConnect(ctx, sandboxID, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostSandboxesSandboxIDConnectResponse(rsp) +} + // GetSandboxesSandboxIDLogsWithResponse request returning *GetSandboxesSandboxIDLogsResponse func (c *ClientWithResponses) GetSandboxesSandboxIDLogsWithResponse(ctx context.Context, sandboxID SandboxID, params *GetSandboxesSandboxIDLogsParams, reqEditors ...RequestEditorFn) (*GetSandboxesSandboxIDLogsResponse, error) { rsp, err := c.GetSandboxesSandboxIDLogs(ctx, sandboxID, params, reqEditors...) @@ -4519,6 +4643,60 @@ func ParseGetSandboxesSandboxIDResponse(rsp *http.Response) (*GetSandboxesSandbo return response, nil } +// ParsePostSandboxesSandboxIDConnectResponse parses an HTTP response from a PostSandboxesSandboxIDConnectWithResponse call +func ParsePostSandboxesSandboxIDConnectResponse(rsp *http.Response) (*PostSandboxesSandboxIDConnectResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostSandboxesSandboxIDConnectResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Sandbox + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest N401 + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest N404 + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: + var dest N409 + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON409 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest N500 + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + // ParseGetSandboxesSandboxIDLogsResponse parses an HTTP response from a GetSandboxesSandboxIDLogsWithResponse call func ParseGetSandboxesSandboxIDLogsResponse(rsp *http.Response) (*GetSandboxesSandboxIDLogsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/tests/integration/internal/api/models.gen.go b/tests/integration/internal/api/models.gen.go index 7b48695a4a..a458178bed 100644 --- a/tests/integration/internal/api/models.gen.go +++ b/tests/integration/internal/api/models.gen.go @@ -119,6 +119,12 @@ type BuildStatusReason struct { // CPUCount CPU cores for the sandbox type CPUCount = int32 +// ConnectSandbox defines model for ConnectSandbox. +type ConnectSandbox struct { + // Timeout Timeout in seconds from the current time after which the sandbox should expire + Timeout int32 `json:"timeout"` +} + // CreatedAccessToken defines model for CreatedAccessToken. type CreatedAccessToken struct { // CreatedAt Timestamp of access token creation @@ -968,6 +974,9 @@ type PostNodesNodeIDJSONRequestBody = NodeStatusChange // PostSandboxesJSONRequestBody defines body for PostSandboxes for application/json ContentType. type PostSandboxesJSONRequestBody = NewSandbox +// PostSandboxesSandboxIDConnectJSONRequestBody defines body for PostSandboxesSandboxIDConnect for application/json ContentType. +type PostSandboxesSandboxIDConnectJSONRequestBody = ConnectSandbox + // PostSandboxesSandboxIDRefreshesJSONRequestBody defines body for PostSandboxesSandboxIDRefreshes for application/json ContentType. type PostSandboxesSandboxIDRefreshesJSONRequestBody PostSandboxesSandboxIDRefreshesJSONBody diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go new file mode 100644 index 0000000000..fd462a36db --- /dev/null +++ b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go @@ -0,0 +1,132 @@ +package sandboxes + +import ( + "fmt" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" + + "github.com/e2b-dev/infra/tests/integration/internal/api" + "github.com/e2b-dev/infra/tests/integration/internal/setup" + "github.com/e2b-dev/infra/tests/integration/internal/utils" +) + +func TestSandboxConnect(t *testing.T) { + c := setup.GetAPIClient() + + t.Run("connect with paused sandbox", func(t *testing.T) { + // Create a sandbox with auto-pause disabled + sbx := utils.SetupSandboxWithCleanup(t, c, utils.WithAutoPause(false)) + sbxId := sbx.SandboxID + pauseSandbox(t, c, sbxId) + + // Connect to the sandbox + sbxConnect, err := c.PostSandboxesSandboxIDConnectWithResponse(t.Context(), sbxId, api.PostSandboxesSandboxIDConnectJSONRequestBody{ + Timeout: 30, + }, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusCreated, sbxConnect.StatusCode()) + require.NotNil(t, sbxConnect.JSON201) + assert.Equal(t, sbxConnect.JSON201.SandboxID, sbxId) + + // Check if the sandbox is running + res, err := c.GetSandboxesSandboxIDWithResponse(t.Context(), sbxId, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, res.StatusCode()) + require.NotNil(t, res.JSON200) + assert.Equal(t, api.Running, res.JSON200.State) + }) + + t.Run("connect to running sandbox", func(t *testing.T) { + // Create a sandbox with auto-pause disabled + sbx := utils.SetupSandboxWithCleanup(t, c) + sbxId := sbx.SandboxID + + res, err := c.GetSandboxesSandboxIDWithResponse(t.Context(), sbxId, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, res.StatusCode()) + require.NotNil(t, res.JSON200) + assert.Equal(t, api.Running, res.JSON200.State) + + initialEndTime := res.JSON200.EndAt + + // Connect to the sandbox + sbxConnect, err := c.PostSandboxesSandboxIDConnectWithResponse(t.Context(), sbxId, api.PostSandboxesSandboxIDConnectJSONRequestBody{ + Timeout: 321, + }, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusCreated, sbxConnect.StatusCode()) + require.NotNil(t, sbxConnect.JSON201) + assert.Equal(t, sbxConnect.JSON201.SandboxID, sbxId) + + // Check if the sandbox is running and the timeout isn't changed + res, err = c.GetSandboxesSandboxIDWithResponse(t.Context(), sbxId, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, res.StatusCode()) + require.NotNil(t, res.JSON200) + assert.Equal(t, api.Running, res.JSON200.State) + + assert.Equal(t, initialEndTime, res.JSON200.EndAt, "the timeout shouldn't be changed") + }) + + t.Run("connect to not existing sandbox", func(t *testing.T) { + // Try to connect the sandbox + sbxConnect, err := c.PostSandboxesSandboxIDConnectWithResponse(t.Context(), "it-isnt-there", api.PostSandboxesSandboxIDConnectJSONRequestBody{ + Timeout: 30, + }, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusNotFound, sbxConnect.StatusCode()) + }) + + t.Run("concurrent connects - not returning early", func(t *testing.T) { + c := setup.GetAPIClient() + + // Create a sandbox with auto-pause disabled + sbx := utils.SetupSandboxWithCleanup(t, c) + sbxId := sbx.SandboxID + + // Pause the sandbox + resp, err := c.PostSandboxesSandboxIDPauseWithResponse(t.Context(), sbxId, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusNoContent, resp.StatusCode()) + + wg := errgroup.Group{} + for range 5 { + wg.Go(func() error { + // Try to connect the sandbox + sbxConnect, err := c.PostSandboxesSandboxIDConnectWithResponse(t.Context(), sbxId, api.PostSandboxesSandboxIDConnectJSONRequestBody{ + Timeout: 30, + }, setup.WithAPIKey()) + if err != nil { + return fmt.Errorf("connect sandbox - %w", err) + } + + // Try to check the status of the sandbox + sbxState, err := c.GetSandboxesSandboxIDWithResponse(t.Context(), sbxId, setup.WithAPIKey()) + if err != nil { + return fmt.Errorf("get sandbox - %w", err) + } + + if sbxState.StatusCode() != http.StatusOK { + return fmt.Errorf("get sandbox - unexpected status code: %d", sbxState.StatusCode()) + } + + if sbxState.JSON200.State != api.Running { + return fmt.Errorf("get sandbox - unexpected state: %s", sbxState.JSON200.State) + } + + if sbxConnect.StatusCode() != http.StatusCreated && sbxConnect.StatusCode() != http.StatusOK { + return fmt.Errorf("connect sandbox - unexpected status code: %d", sbxConnect.StatusCode()) + } + + return nil + }) + } + + err = wg.Wait() + require.NoError(t, err) + }) +} diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_refresh_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_refresh_test.go new file mode 100644 index 0000000000..1514997819 --- /dev/null +++ b/tests/integration/internal/tests/api/sandboxes/sandbox_refresh_test.go @@ -0,0 +1,79 @@ +package sandboxes + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/e2b-dev/infra/tests/integration/internal/api" + "github.com/e2b-dev/infra/tests/integration/internal/setup" + "github.com/e2b-dev/infra/tests/integration/internal/utils" +) + +func TestSandboxRefresh(t *testing.T) { + c := setup.GetAPIClient() + testCases := []struct { + name string + extend bool + same bool + + initialDuration int + newDuration int + }{ + { + name: "extend", + extend: true, + same: false, + + initialDuration: 60, + newDuration: 120, + }, + { + name: "shorten", + extend: false, + same: true, + initialDuration: 120, + newDuration: 60, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sbx := utils.SetupSandboxWithCleanup(t, c, utils.WithTimeout(int32(tc.initialDuration))) + + // Get initial sandbox details + detailResp, err := c.GetSandboxesSandboxIDWithResponse(t.Context(), sbx.SandboxID, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, detailResp.StatusCode()) + require.NotNil(t, detailResp.JSON200) + + initialEndTime := detailResp.JSON200.EndAt + + timeoutResp, err := c.PostSandboxesSandboxIDRefreshesWithResponse(t.Context(), sbx.SandboxID, api.PostSandboxesSandboxIDRefreshesJSONRequestBody{ + Duration: &tc.newDuration, + }, setup.WithAPIKey()) + require.NoError(t, err) + assert.Equal(t, http.StatusNoContent, timeoutResp.StatusCode()) + + detailResp2, err := c.GetSandboxesSandboxIDWithResponse(t.Context(), sbx.SandboxID, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, detailResp2.StatusCode()) + require.NotNil(t, detailResp2.JSON200) + + newEndTime := detailResp2.JSON200.EndAt + + assert.Equal(t, tc.extend, newEndTime.After(initialEndTime), "End time should be extended") + assert.Equal(t, tc.same, newEndTime.Equal(initialEndTime), "End time should be updated") + }) + } +} + +func TestSandboxRefresh_NotFound(t *testing.T) { + c := setup.GetAPIClient() + + timeoutResp, err := c.PostSandboxesSandboxIDRefreshesWithResponse(t.Context(), "nonexistent-sandbox-id", api.PostSandboxesSandboxIDRefreshesJSONRequestBody{}, setup.WithAPIKey()) + require.NoError(t, err) + assert.Equal(t, http.StatusNotFound, timeoutResp.StatusCode()) +} diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_timeout_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_timeout_test.go new file mode 100644 index 0000000000..f3c3be495a --- /dev/null +++ b/tests/integration/internal/tests/api/sandboxes/sandbox_timeout_test.go @@ -0,0 +1,77 @@ +package sandboxes + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/e2b-dev/infra/tests/integration/internal/api" + "github.com/e2b-dev/infra/tests/integration/internal/setup" + "github.com/e2b-dev/infra/tests/integration/internal/utils" +) + +func TestSandboxTimeout(t *testing.T) { + c := setup.GetAPIClient() + testCases := []struct { + name string + extend bool + + initialDuration int32 + newDuration int32 + }{ + { + name: "extend", + extend: true, + initialDuration: 60, + newDuration: 120, + }, + { + name: "shorten", + extend: false, + initialDuration: 120, + newDuration: 60, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sbx := utils.SetupSandboxWithCleanup(t, c, utils.WithTimeout(tc.initialDuration)) + + // Get initial sandbox details + detailResp, err := c.GetSandboxesSandboxIDWithResponse(t.Context(), sbx.SandboxID, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, detailResp.StatusCode()) + require.NotNil(t, detailResp.JSON200) + + initialEndTime := detailResp.JSON200.EndAt + + timeoutResp, err := c.PostSandboxesSandboxIDTimeoutWithResponse(t.Context(), sbx.SandboxID, api.PostSandboxesSandboxIDTimeoutJSONRequestBody{ + Timeout: tc.newDuration, + }, setup.WithAPIKey()) + require.NoError(t, err) + assert.Equal(t, http.StatusNoContent, timeoutResp.StatusCode()) + + detailResp2, err := c.GetSandboxesSandboxIDWithResponse(t.Context(), sbx.SandboxID, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, detailResp2.StatusCode()) + require.NotNil(t, detailResp2.JSON200) + + newEndTime := detailResp2.JSON200.EndAt + + assert.Equal(t, tc.extend, newEndTime.After(initialEndTime), "End time should be extended") + assert.NotEqual(t, initialEndTime, newEndTime, "End time should be updated") + }) + } +} + +func TestSandboxTimeout_NotFound(t *testing.T) { + c := setup.GetAPIClient() + + timeoutResp, err := c.PostSandboxesSandboxIDTimeoutWithResponse(t.Context(), "nonexistent-sandbox-id", api.PostSandboxesSandboxIDTimeoutJSONRequestBody{ + Timeout: 60, + }, setup.WithAPIKey()) + require.NoError(t, err) + assert.Equal(t, http.StatusNotFound, timeoutResp.StatusCode()) +} From 28c78839f4883ad1a138aac446b85b1f5510500f Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 28 Oct 2025 13:51:22 +0100 Subject: [PATCH 2/9] Fix the expected status --- .../internal/tests/api/sandboxes/sandbox_connect_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go index fd462a36db..50111b279b 100644 --- a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go +++ b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go @@ -58,7 +58,7 @@ func TestSandboxConnect(t *testing.T) { Timeout: 321, }, setup.WithAPIKey()) require.NoError(t, err) - require.Equal(t, http.StatusCreated, sbxConnect.StatusCode()) + require.Equal(t, http.StatusOK, sbxConnect.StatusCode()) require.NotNil(t, sbxConnect.JSON201) assert.Equal(t, sbxConnect.JSON201.SandboxID, sbxId) From bd32906104ec3214922c9e302979fa37d3ac61e7 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 28 Oct 2025 14:46:43 +0100 Subject: [PATCH 3/9] Add 200 response --- packages/api/internal/api/spec.gen.go | 204 +++++++++--------- spec/openapi.yml | 6 + tests/integration/internal/api/client.gen.go | 8 + .../api/sandboxes/sandbox_connect_test.go | 4 +- 4 files changed, 118 insertions(+), 104 deletions(-) diff --git a/packages/api/internal/api/spec.gen.go b/packages/api/internal/api/spec.gen.go index 8fe966e1aa..d39374ee17 100644 --- a/packages/api/internal/api/spec.gen.go +++ b/packages/api/internal/api/spec.gen.go @@ -19,112 +19,112 @@ import ( var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/spec/openapi.yml b/spec/openapi.yml index 1602b0c4a7..3e38ecded4 100644 --- a/spec/openapi.yml +++ b/spec/openapi.yml @@ -1679,6 +1679,12 @@ paths: schema: $ref: "#/components/schemas/ConnectSandbox" responses: + "200": + description: The sandbox was already running + content: + application/json: + schema: + $ref: "#/components/schemas/Sandbox" "201": description: The sandbox was resumed successfully content: diff --git a/tests/integration/internal/api/client.gen.go b/tests/integration/internal/api/client.gen.go index d7fab77a19..0b1a124a51 100644 --- a/tests/integration/internal/api/client.gen.go +++ b/tests/integration/internal/api/client.gen.go @@ -3071,6 +3071,7 @@ func (r GetSandboxesSandboxIDResponse) StatusCode() int { type PostSandboxesSandboxIDConnectResponse struct { Body []byte HTTPResponse *http.Response + JSON200 *Sandbox JSON201 *Sandbox JSON401 *N401 JSON404 *N404 @@ -4657,6 +4658,13 @@ func ParsePostSandboxesSandboxIDConnectResponse(rsp *http.Response) (*PostSandbo } switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Sandbox + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: var dest Sandbox if err := json.Unmarshal(bodyBytes, &dest); err != nil { diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go index 50111b279b..4440abdda5 100644 --- a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go +++ b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go @@ -59,8 +59,8 @@ func TestSandboxConnect(t *testing.T) { }, setup.WithAPIKey()) require.NoError(t, err) require.Equal(t, http.StatusOK, sbxConnect.StatusCode()) - require.NotNil(t, sbxConnect.JSON201) - assert.Equal(t, sbxConnect.JSON201.SandboxID, sbxId) + require.NotNil(t, sbxConnect.JSON200) + assert.Equal(t, sbxConnect.JSON200.SandboxID, sbxId) // Check if the sandbox is running and the timeout isn't changed res, err = c.GetSandboxesSandboxIDWithResponse(t.Context(), sbxId, setup.WithAPIKey()) From 66876ab58acd86413a51eef332bc0f92faef3ef8 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Wed, 29 Oct 2025 09:16:39 +0100 Subject: [PATCH 4/9] Extend time for already running sandbox --- .../api/internal/handlers/sandbox_connect.go | 22 ++++--- spec/openapi.yml | 2 +- .../api/sandboxes/sandbox_connect_test.go | 34 ++++++++++- .../api/sandboxes/sandbox_set_timeout_test.go | 61 ------------------- .../api/sandboxes/sandbox_timeout_test.go | 49 +++++++++++++++ 5 files changed, 98 insertions(+), 70 deletions(-) delete mode 100644 tests/integration/internal/tests/api/sandboxes/sandbox_set_timeout_test.go diff --git a/packages/api/internal/handlers/sandbox_connect.go b/packages/api/internal/handlers/sandbox_connect.go index 1c7785ab58..78971a891b 100644 --- a/packages/api/internal/handlers/sandbox_connect.go +++ b/packages/api/internal/handlers/sandbox_connect.go @@ -43,6 +43,13 @@ func (a *APIStore) PostSandboxesSandboxIDConnect(c *gin.Context, sandboxID api.S return } + timeout := time.Duration(body.Timeout) * time.Second + if timeout > time.Duration(teamInfo.Limits.MaxLengthHours)*time.Hour { + a.sendAPIStoreError(c, http.StatusBadRequest, fmt.Sprintf("Timeout cannot be greater than %d hours", teamInfo.Limits.MaxLengthHours)) + + return + } + sandboxID = utils.ShortID(sandboxID) sandboxData, err := a.orchestrator.GetSandbox(sandboxID) if err == nil { @@ -67,6 +74,14 @@ func (a *APIStore) PostSandboxesSandboxIDConnect(c *gin.Context, sandboxID api.S zap.String("node_id", sandboxData.NodeID), ) + apiErr := a.orchestrator.KeepAliveFor(ctx, sandboxID, timeout, false) + if apiErr != nil { + zap.L().Error("Error when resuming sandbox", zap.Error(apiErr.Err)) + a.sendAPIStoreError(c, apiErr.Code, apiErr.ClientMsg) + + return + } + c.JSON(http.StatusOK, sandboxData.ToAPISandbox()) return @@ -78,13 +93,6 @@ func (a *APIStore) PostSandboxesSandboxIDConnect(c *gin.Context, sandboxID api.S } } - timeout := time.Duration(body.Timeout) * time.Second - if timeout > time.Duration(teamInfo.Limits.MaxLengthHours)*time.Hour { - a.sendAPIStoreError(c, http.StatusBadRequest, fmt.Sprintf("Timeout cannot be greater than %d hours", teamInfo.Limits.MaxLengthHours)) - - return - } - lastSnapshot, err := a.sqlcDB.GetLastSnapshot(ctx, queries.GetLastSnapshotParams{SandboxID: sandboxID, TeamID: teamInfo.Team.ID}) if err != nil { if errors.Is(err, sql.ErrNoRows) { diff --git a/spec/openapi.yml b/spec/openapi.yml index 3e38ecded4..95df4b241e 100644 --- a/spec/openapi.yml +++ b/spec/openapi.yml @@ -1664,7 +1664,7 @@ paths: /sandboxes/{sandboxID}/connect: post: - description: Returns sandbox info if the sandbox is running, resumes it if it is paused. The timeout is set only if the sandbox is paused. + description: Resumes the sandbox if it is paused. If the sandbox is already running, it extends the timeout if the current timeout is shorter. tags: [sandboxes] security: - ApiKeyAuth: [] diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go index 4440abdda5..864f89dd29 100644 --- a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go +++ b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go @@ -41,6 +41,38 @@ func TestSandboxConnect(t *testing.T) { }) t.Run("connect to running sandbox", func(t *testing.T) { + // Create a sandbox with auto-pause disabled + sbx := utils.SetupSandboxWithCleanup(t, c, utils.WithTimeout(100)) + sbxId := sbx.SandboxID + + res, err := c.GetSandboxesSandboxIDWithResponse(t.Context(), sbxId, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, res.StatusCode()) + require.NotNil(t, res.JSON200) + assert.Equal(t, api.Running, res.JSON200.State) + + initialEndTime := res.JSON200.EndAt + + // Connect to the sandbox + sbxConnect, err := c.PostSandboxesSandboxIDConnectWithResponse(t.Context(), sbxId, api.PostSandboxesSandboxIDConnectJSONRequestBody{ + Timeout: 10, + }, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, sbxConnect.StatusCode()) + require.NotNil(t, sbxConnect.JSON200) + assert.Equal(t, sbxConnect.JSON200.SandboxID, sbxId) + + // Check if the sandbox is running and the timeout isn't changed + res, err = c.GetSandboxesSandboxIDWithResponse(t.Context(), sbxId, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusOK, res.StatusCode()) + require.NotNil(t, res.JSON200) + assert.Equal(t, api.Running, res.JSON200.State) + + assert.Equal(t, initialEndTime, res.JSON200.EndAt, "the timeout shouldn't be changed") + }) + + t.Run("connect to running sandbox shorter timeout", func(t *testing.T) { // Create a sandbox with auto-pause disabled sbx := utils.SetupSandboxWithCleanup(t, c) sbxId := sbx.SandboxID @@ -69,7 +101,7 @@ func TestSandboxConnect(t *testing.T) { require.NotNil(t, res.JSON200) assert.Equal(t, api.Running, res.JSON200.State) - assert.Equal(t, initialEndTime, res.JSON200.EndAt, "the timeout shouldn't be changed") + assert.True(t, res.JSON200.EndAt.After(initialEndTime), "End time should be extended") }) t.Run("connect to not existing sandbox", func(t *testing.T) { diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_set_timeout_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_set_timeout_test.go deleted file mode 100644 index 80ae72de92..0000000000 --- a/tests/integration/internal/tests/api/sandboxes/sandbox_set_timeout_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package sandboxes - -import ( - "fmt" - "net/http" - "testing" - "time" - - "github.com/stretchr/testify/require" - "golang.org/x/sync/errgroup" - - "github.com/e2b-dev/infra/tests/integration/internal/api" - "github.com/e2b-dev/infra/tests/integration/internal/setup" - "github.com/e2b-dev/infra/tests/integration/internal/utils" -) - -func TestSandboxSetTimeoutPausingSandbox(t *testing.T) { - c := setup.GetAPIClient() - - t.Run("test set timeout while pausing", func(t *testing.T) { - sbx := utils.SetupSandboxWithCleanup(t, c, utils.WithAutoPause(true)) - sbxId := sbx.SandboxID - - // Pause the sandbox - wg := errgroup.Group{} - wg.Go(func() error { - pauseResp, err := c.PostSandboxesSandboxIDPauseWithResponse(t.Context(), sbxId, setup.WithAPIKey()) - if err != nil { - return err - } - - if pauseResp.StatusCode() != http.StatusNoContent { - return fmt.Errorf("unexpected status code: %d", pauseResp.StatusCode()) - } - - return nil - }) - - for range 5 { - time.Sleep(200 * time.Millisecond) - wg.Go(func() error { - setTimeoutResp, err := c.PostSandboxesSandboxIDTimeoutWithResponse(t.Context(), sbxId, api.PostSandboxesSandboxIDTimeoutJSONRequestBody{ - Timeout: 15, - }, - setup.WithAPIKey()) - if err != nil { - return err - } - - if setTimeoutResp.StatusCode() != http.StatusNotFound { - return fmt.Errorf("unexpected status code: %d", setTimeoutResp.StatusCode()) - } - - return nil - }) - } - - err := wg.Wait() - require.NoError(t, err) - }) -} diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_timeout_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_timeout_test.go index f3c3be495a..258dda9a36 100644 --- a/tests/integration/internal/tests/api/sandboxes/sandbox_timeout_test.go +++ b/tests/integration/internal/tests/api/sandboxes/sandbox_timeout_test.go @@ -1,11 +1,14 @@ package sandboxes import ( + "fmt" "net/http" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" "github.com/e2b-dev/infra/tests/integration/internal/api" "github.com/e2b-dev/infra/tests/integration/internal/setup" @@ -75,3 +78,49 @@ func TestSandboxTimeout_NotFound(t *testing.T) { require.NoError(t, err) assert.Equal(t, http.StatusNotFound, timeoutResp.StatusCode()) } + +func TestSandboxSetTimeoutPausingSandbox(t *testing.T) { + c := setup.GetAPIClient() + + t.Run("test set timeout while pausing", func(t *testing.T) { + sbx := utils.SetupSandboxWithCleanup(t, c, utils.WithAutoPause(true)) + sbxId := sbx.SandboxID + + // Pause the sandbox + wg := errgroup.Group{} + wg.Go(func() error { + pauseResp, err := c.PostSandboxesSandboxIDPauseWithResponse(t.Context(), sbxId, setup.WithAPIKey()) + if err != nil { + return err + } + + if pauseResp.StatusCode() != http.StatusNoContent { + return fmt.Errorf("unexpected status code: %d", pauseResp.StatusCode()) + } + + return nil + }) + + for range 5 { + time.Sleep(200 * time.Millisecond) + wg.Go(func() error { + setTimeoutResp, err := c.PostSandboxesSandboxIDTimeoutWithResponse(t.Context(), sbxId, api.PostSandboxesSandboxIDTimeoutJSONRequestBody{ + Timeout: 15, + }, + setup.WithAPIKey()) + if err != nil { + return err + } + + if setTimeoutResp.StatusCode() != http.StatusNotFound { + return fmt.Errorf("unexpected status code: %d", setTimeoutResp.StatusCode()) + } + + return nil + }) + } + + err := wg.Wait() + require.NoError(t, err) + }) +} From eb0a1d5366af00bc8c7d0aa2f95e65add899b6c9 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Wed, 29 Oct 2025 10:22:39 +0100 Subject: [PATCH 5/9] Regenerate spec --- packages/api/internal/api/spec.gen.go | 214 +++++++++++++------------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/packages/api/internal/api/spec.gen.go b/packages/api/internal/api/spec.gen.go index d39374ee17..297433f482 100644 --- a/packages/api/internal/api/spec.gen.go +++ b/packages/api/internal/api/spec.gen.go @@ -18,113 +18,113 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file From 7298cd44d94fd3e04ac7ebd64034902f9d5851bf Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Wed, 29 Oct 2025 11:14:46 +0100 Subject: [PATCH 6/9] Add test for too long timeout --- .../internal/tests/api/sandboxes/sandbox_connect_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go index 864f89dd29..8d031eb075 100644 --- a/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go +++ b/tests/integration/internal/tests/api/sandboxes/sandbox_connect_test.go @@ -113,6 +113,15 @@ func TestSandboxConnect(t *testing.T) { require.Equal(t, http.StatusNotFound, sbxConnect.StatusCode()) }) + t.Run("connect with too big timeout", func(t *testing.T) { + // Try to connect the sandbox + sbxConnect, err := c.PostSandboxesSandboxIDConnectWithResponse(t.Context(), "it-isnt-there", api.PostSandboxesSandboxIDConnectJSONRequestBody{ + Timeout: 60 * 60 * 72, // 3 days + }, setup.WithAPIKey()) + require.NoError(t, err) + require.Equal(t, http.StatusBadRequest, sbxConnect.StatusCode()) + }) + t.Run("concurrent connects - not returning early", func(t *testing.T) { c := setup.GetAPIClient() From 95b74d449ca1841c600fa3ec0d4cf3f6bf7f785d Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Wed, 29 Oct 2025 11:15:00 +0100 Subject: [PATCH 7/9] Improve error codes --- packages/api/internal/api/spec.gen.go | 214 +++++++++---------- spec/openapi.yml | 8 +- tests/integration/internal/api/client.gen.go | 16 +- 3 files changed, 119 insertions(+), 119 deletions(-) diff --git a/packages/api/internal/api/spec.gen.go b/packages/api/internal/api/spec.gen.go index 297433f482..df822636a4 100644 --- a/packages/api/internal/api/spec.gen.go +++ b/packages/api/internal/api/spec.gen.go @@ -18,113 +18,113 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/spec/openapi.yml b/spec/openapi.yml index 95df4b241e..62d9b50434 100644 --- a/spec/openapi.yml +++ b/spec/openapi.yml @@ -1691,12 +1691,12 @@ paths: application/json: schema: $ref: "#/components/schemas/Sandbox" - "409": - $ref: "#/components/responses/409" - "404": - $ref: "#/components/responses/404" + "400": + $ref: "#/components/responses/400" "401": $ref: "#/components/responses/401" + "404": + $ref: "#/components/responses/404" "500": $ref: "#/components/responses/500" diff --git a/tests/integration/internal/api/client.gen.go b/tests/integration/internal/api/client.gen.go index 0b1a124a51..82e0ba71fc 100644 --- a/tests/integration/internal/api/client.gen.go +++ b/tests/integration/internal/api/client.gen.go @@ -3073,9 +3073,9 @@ type PostSandboxesSandboxIDConnectResponse struct { HTTPResponse *http.Response JSON200 *Sandbox JSON201 *Sandbox + JSON400 *N400 JSON401 *N401 JSON404 *N404 - JSON409 *N409 JSON500 *N500 } @@ -4672,6 +4672,13 @@ func ParsePostSandboxesSandboxIDConnectResponse(rsp *http.Response) (*PostSandbo } response.JSON201 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest N400 + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: var dest N401 if err := json.Unmarshal(bodyBytes, &dest); err != nil { @@ -4686,13 +4693,6 @@ func ParsePostSandboxesSandboxIDConnectResponse(rsp *http.Response) (*PostSandbo } response.JSON404 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: - var dest N409 - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON409 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: var dest N500 if err := json.Unmarshal(bodyBytes, &dest); err != nil { From 51b000816be4d2daacafb88279aab439403dc23d Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Wed, 29 Oct 2025 11:18:46 +0100 Subject: [PATCH 8/9] Improve description --- packages/api/internal/api/spec.gen.go | 48 +++++++++++++-------------- spec/openapi.yml | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/packages/api/internal/api/spec.gen.go b/packages/api/internal/api/spec.gen.go index df822636a4..5ef7251d46 100644 --- a/packages/api/internal/api/spec.gen.go +++ b/packages/api/internal/api/spec.gen.go @@ -101,30 +101,30 @@ var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/spec/openapi.yml b/spec/openapi.yml index 62d9b50434..22f8e10a5f 100644 --- a/spec/openapi.yml +++ b/spec/openapi.yml @@ -1664,7 +1664,7 @@ paths: /sandboxes/{sandboxID}/connect: post: - description: Resumes the sandbox if it is paused. If the sandbox is already running, it extends the timeout if the current timeout is shorter. + description: Resumes the sandbox if it is paused. Returns sandbox data. TTL is only extended. tags: [sandboxes] security: - ApiKeyAuth: [] From 5729df81e281cbf82688ca49c7fa4eb8060bf501 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Wed, 29 Oct 2025 15:05:38 +0100 Subject: [PATCH 9/9] Update description --- packages/api/internal/api/spec.gen.go | 214 +++++++++++++------------- spec/openapi.yml | 2 +- 2 files changed, 108 insertions(+), 108 deletions(-) diff --git a/packages/api/internal/api/spec.gen.go b/packages/api/internal/api/spec.gen.go index 5ef7251d46..a69c86bd7b 100644 --- a/packages/api/internal/api/spec.gen.go +++ b/packages/api/internal/api/spec.gen.go @@ -18,113 +18,113 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/spec/openapi.yml b/spec/openapi.yml index 22f8e10a5f..ba8b077bed 100644 --- a/spec/openapi.yml +++ b/spec/openapi.yml @@ -1664,7 +1664,7 @@ paths: /sandboxes/{sandboxID}/connect: post: - description: Resumes the sandbox if it is paused. Returns sandbox data. TTL is only extended. + description: Returns sandbox details. If the sandbox is paused, it will be resumed. TTL is only extended. tags: [sandboxes] security: - ApiKeyAuth: []