@cobaltcore-dev/aurora 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -9
- package/dist/client/App.d.ts +2 -2
- package/dist/client/AuroraApp.d.ts +33 -13
- package/dist/client/{AuthProvider-BS5OVv8n.mjs → AuthProvider-CVSAwW9f.mjs} +22 -8
- package/dist/client/AuthProvider-CVSAwW9f.mjs.map +1 -0
- package/dist/client/{ContentHeader-BHMUzd9H.mjs → ContentHeader-CPJbgYWn.mjs} +18 -18
- package/dist/client/{ContentHeader-BHMUzd9H.mjs.map → ContentHeader-CPJbgYWn.mjs.map} +1 -1
- package/dist/client/DeleteFlavorModal-V44QCJBd.mjs +773 -0
- package/dist/client/DeleteFlavorModal-V44QCJBd.mjs.map +1 -0
- package/dist/client/DynamicBreadcrumbContext-CVcUQFou.mjs +26 -0
- package/dist/client/DynamicBreadcrumbContext-CVcUQFou.mjs.map +1 -0
- package/dist/client/{FiltersInput-B8CNBg1L.mjs → FiltersInput-CKI6zWnm.mjs} +18 -18
- package/dist/client/{FiltersInput-B8CNBg1L.mjs.map → FiltersInput-CKI6zWnm.mjs.map} +1 -1
- package/dist/client/FloatingIpActionModals-CwEC5GR-.mjs +460 -0
- package/dist/client/FloatingIpActionModals-CwEC5GR-.mjs.map +1 -0
- package/dist/client/ImageToastNotifications-m6c3tVPb.mjs +1152 -0
- package/dist/client/ImageToastNotifications-m6c3tVPb.mjs.map +1 -0
- package/dist/client/SortInput-4g7nSTHW.mjs +34 -0
- package/dist/client/SortInput-4g7nSTHW.mjs.map +1 -0
- package/dist/client/{TwoColumnDescriptionList-DiDx3PnH.mjs → TwoColumnDescriptionList-NvgvErua.mjs} +2 -2
- package/dist/client/{TwoColumnDescriptionList-DiDx3PnH.mjs.map → TwoColumnDescriptionList-NvgvErua.mjs.map} +1 -1
- package/dist/client/_-CAsCx-Ay.mjs +6 -0
- package/dist/client/_-CAsCx-Ay.mjs.map +1 -0
- package/dist/client/_auth-SrDjHL6j.mjs +12 -0
- package/dist/client/_auth-SrDjHL6j.mjs.map +1 -0
- package/dist/client/_flavorId-9PcBBW52.mjs +231 -0
- package/dist/client/_flavorId-9PcBBW52.mjs.map +1 -0
- package/dist/client/{_flavorId-BN_qessZ.mjs → _flavorId-a9Gu66R1.mjs} +3 -9
- package/dist/client/_flavorId-a9Gu66R1.mjs.map +1 -0
- package/dist/client/_floatingIpId-AE9Fu8l6.mjs +210 -0
- package/dist/client/_floatingIpId-AE9Fu8l6.mjs.map +1 -0
- package/dist/client/{_floatingIpId-CwDGHkWm.mjs → _floatingIpId-AZ11Ksmu.mjs} +3 -9
- package/dist/client/_floatingIpId-AZ11Ksmu.mjs.map +1 -0
- package/dist/client/{_imageId-BtJ7GmYB.mjs → _imageId-BtAql2Kr.mjs} +104 -92
- package/dist/client/_imageId-BtAql2Kr.mjs.map +1 -0
- package/dist/client/_imageId-D76BxvFY.mjs +39 -0
- package/dist/client/_imageId-D76BxvFY.mjs.map +1 -0
- package/dist/client/{_projectId-Byt3GQDW.mjs → _projectId-7Nl1MQTJ.mjs} +5 -5
- package/dist/client/_projectId-7Nl1MQTJ.mjs.map +1 -0
- package/dist/client/_projectId-B3wmSala.mjs +281 -0
- package/dist/client/_projectId-B3wmSala.mjs.map +1 -0
- package/dist/client/_projectId-DPzv0CCp.mjs +77 -0
- package/dist/client/_projectId-DPzv0CCp.mjs.map +1 -0
- package/dist/client/_projectId-DfeVJy0G.mjs +30 -0
- package/dist/client/_projectId-DfeVJy0G.mjs.map +1 -0
- package/dist/client/_securityGroupId-C5huJNfO.mjs +1810 -0
- package/dist/client/_securityGroupId-C5huJNfO.mjs.map +1 -0
- package/dist/client/{_securityGroupId-BcbkRhsN.mjs → _securityGroupId-D85mSigA.mjs} +3 -9
- package/dist/client/_securityGroupId-D85mSigA.mjs.map +1 -0
- package/dist/client/_serviceType-DS8DxsrP.mjs +20 -0
- package/dist/client/_serviceType-DS8DxsrP.mjs.map +1 -0
- package/dist/client/_serviceType-M8d9rOT6.mjs +6 -0
- package/dist/client/_serviceType-M8d9rOT6.mjs.map +1 -0
- package/dist/client/_storageType-BRWWJtow.mjs +14 -0
- package/dist/client/_storageType-BRWWJtow.mjs.map +1 -0
- package/dist/client/_storageType-CzZ4u9x_.mjs +12 -0
- package/dist/client/_storageType-CzZ4u9x_.mjs.map +1 -0
- package/dist/client/_storageType-Dy9uCVXr.mjs +845 -0
- package/dist/client/_storageType-Dy9uCVXr.mjs.map +1 -0
- package/dist/client/_storageType-zeSZe--V.mjs.map +1 -1
- package/dist/client/{about-_73VmpTB.mjs → about-BmQTyLWc.mjs} +2 -2
- package/dist/client/{about-_73VmpTB.mjs.map → about-BmQTyLWc.mjs.map} +1 -1
- package/dist/client/{aurora-EbwGRLLf.mjs → aurora-CIml-f2f.mjs} +2 -2
- package/dist/client/{aurora-EbwGRLLf.mjs.map → aurora-CIml-f2f.mjs.map} +1 -1
- package/dist/client/{build-C_4vRMCq.mjs → build-WuxXRAqf.mjs} +121 -24
- package/dist/client/{build-C_4vRMCq.mjs.map → build-WuxXRAqf.mjs.map} +1 -1
- package/dist/client/components/Breadcrumbs.d.ts +1 -0
- package/dist/client/components/ListToolbar/SortInput.d.ts +3 -0
- package/dist/client/context/BreadcrumbExtensionContext.d.ts +9 -0
- package/dist/client/context/DynamicBreadcrumbContext.d.ts +9 -0
- package/dist/client/{flavors-CiHCYrtZ.mjs → flavors-B0rbqffG.mjs} +3 -5
- package/dist/client/flavors-B0rbqffG.mjs.map +1 -0
- package/dist/client/flavors-DWMZ6TuJ.mjs.map +1 -1
- package/dist/client/flavors-Rl20bxVU.mjs +628 -0
- package/dist/client/flavors-Rl20bxVU.mjs.map +1 -0
- package/dist/client/floatingips-Cz9k80cc.mjs +8 -0
- package/dist/client/floatingips-Cz9k80cc.mjs.map +1 -0
- package/dist/client/floatingips-xbO_mu4f.mjs +576 -0
- package/dist/client/floatingips-xbO_mu4f.mjs.map +1 -0
- package/dist/client/hooks/useBreadcrumbs.d.ts +16 -0
- package/dist/client/hooks/usePushBreadcrumbs.d.ts +10 -0
- package/dist/client/hooks/useSetBreadcrumb.d.ts +11 -0
- package/dist/client/{hooks-LutR2Yg3.mjs → hooks-D0yKIumu.mjs} +2 -2
- package/dist/client/{hooks-LutR2Yg3.mjs.map → hooks-D0yKIumu.mjs.map} +1 -1
- package/dist/client/images-BGQv9kKT.mjs +1983 -0
- package/dist/client/images-BGQv9kKT.mjs.map +1 -0
- package/dist/client/{images-CS4kZQyu.mjs → images-CPmMa4SQ.mjs} +3 -5
- package/dist/client/images-CPmMa4SQ.mjs.map +1 -0
- package/dist/client/images-NBf2bV43.mjs.map +1 -1
- package/dist/client/index.d.ts +7 -3
- package/dist/client/index.js +549 -535
- package/dist/client/index.js.map +1 -1
- package/dist/client/{objects-C3azvW8m.mjs → objects-BE_u5yRt.mjs} +7087 -4211
- package/dist/client/objects-BE_u5yRt.mjs.map +1 -0
- package/dist/client/objects-BN-59Th0.mjs +66 -0
- package/dist/client/objects-BN-59Th0.mjs.map +1 -0
- package/dist/client/objects-D9Luf9KB.mjs +66 -0
- package/dist/client/objects-D9Luf9KB.mjs.map +1 -0
- package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
- package/dist/client/routeInfo-DP3v74Wg.mjs +19 -0
- package/dist/client/routeInfo-DP3v74Wg.mjs.map +1 -0
- package/dist/client/router.d.ts +2 -2
- package/dist/client/{routes-CdDm-hhO.mjs → routes-CJj7SR_K.mjs} +2 -2
- package/dist/client/routes-CJj7SR_K.mjs.map +1 -0
- package/dist/client/routes-xofA3ksU.mjs +110 -0
- package/dist/client/routes-xofA3ksU.mjs.map +1 -0
- package/dist/client/securitygroups-BjhgLBHm.mjs +620 -0
- package/dist/client/securitygroups-BjhgLBHm.mjs.map +1 -0
- package/dist/client/securitygroups-CtKne8UQ.mjs +8 -0
- package/dist/client/securitygroups-CtKne8UQ.mjs.map +1 -0
- package/dist/client/{securitygroups-Byte-iSp.mjs → securitygroups-DEJQBcxm.mjs} +3 -5
- package/dist/client/securitygroups-DEJQBcxm.mjs.map +1 -0
- package/dist/client/trpcClient.d.ts +135 -3
- package/dist/client/useBreadcrumbs-ha3IlaxX.mjs +54 -0
- package/dist/client/useBreadcrumbs-ha3IlaxX.mjs.map +1 -0
- package/dist/client/useModalTracking-BcOKTYRN.mjs +33 -0
- package/dist/client/useModalTracking-BcOKTYRN.mjs.map +1 -0
- package/dist/client/{useSecurityGroupPermissions-C29mzb3b.mjs → useSecurityGroupPermissions-BOyLQLdC.mjs} +85 -19
- package/dist/client/useSecurityGroupPermissions-BOyLQLdC.mjs.map +1 -0
- package/dist/client/useSetBreadcrumb-tn7lBaQV.mjs +19 -0
- package/dist/client/useSetBreadcrumb-tn7lBaQV.mjs.map +1 -0
- package/dist/client/utils/formatSwiftDate.d.ts +30 -0
- package/dist/server/index.d.ts +136 -4
- package/dist/server/index.js +845 -260
- package/package.json +37 -36
- package/dist/client/AuthProvider-BS5OVv8n.mjs.map +0 -1
- package/dist/client/DeleteFlavorModal-BP83t9zX.mjs +0 -721
- package/dist/client/DeleteFlavorModal-BP83t9zX.mjs.map +0 -1
- package/dist/client/FloatingIpActionModals-BraiJWBi.mjs +0 -417
- package/dist/client/FloatingIpActionModals-BraiJWBi.mjs.map +0 -1
- package/dist/client/ImageToastNotifications-BXMHJaIH.mjs +0 -1131
- package/dist/client/ImageToastNotifications-BXMHJaIH.mjs.map +0 -1
- package/dist/client/RouteError-hAF8_jbe.mjs +0 -25
- package/dist/client/RouteError-hAF8_jbe.mjs.map +0 -1
- package/dist/client/SortInput-Cqs2poV3.mjs +0 -34
- package/dist/client/SortInput-Cqs2poV3.mjs.map +0 -1
- package/dist/client/StatusError-C5KodQOq.mjs +0 -39
- package/dist/client/StatusError-C5KodQOq.mjs.map +0 -1
- package/dist/client/_auth-DJ9wHZaj.mjs +0 -11
- package/dist/client/_auth-DJ9wHZaj.mjs.map +0 -1
- package/dist/client/_flavorId-BN_qessZ.mjs.map +0 -1
- package/dist/client/_flavorId-CJjEB_Ao.mjs +0 -210
- package/dist/client/_flavorId-CJjEB_Ao.mjs.map +0 -1
- package/dist/client/_floatingIpId-CwDGHkWm.mjs.map +0 -1
- package/dist/client/_floatingIpId-foMIwbE4.mjs +0 -215
- package/dist/client/_floatingIpId-foMIwbE4.mjs.map +0 -1
- package/dist/client/_imageId-BtJ7GmYB.mjs.map +0 -1
- package/dist/client/_projectId-BmtCuzJu.mjs +0 -29
- package/dist/client/_projectId-BmtCuzJu.mjs.map +0 -1
- package/dist/client/_projectId-Byt3GQDW.mjs.map +0 -1
- package/dist/client/_projectId-NYk1IN_a.mjs +0 -291
- package/dist/client/_projectId-NYk1IN_a.mjs.map +0 -1
- package/dist/client/_projectId-QueiFczy.mjs +0 -46
- package/dist/client/_projectId-QueiFczy.mjs.map +0 -1
- package/dist/client/_securityGroupId-BcbkRhsN.mjs.map +0 -1
- package/dist/client/_securityGroupId-pPtJsCoe.mjs +0 -1797
- package/dist/client/_securityGroupId-pPtJsCoe.mjs.map +0 -1
- package/dist/client/_storageType-BmqrU06i.mjs +0 -2202
- package/dist/client/_storageType-BmqrU06i.mjs.map +0 -1
- package/dist/client/components/Error/StatusError.d.ts +0 -11
- package/dist/client/components/ProjectView/ProjectInfoBox.d.ts +0 -12
- package/dist/client/flavors-CiHCYrtZ.mjs.map +0 -1
- package/dist/client/flavors-DY-bDc8l.mjs +0 -650
- package/dist/client/flavors-DY-bDc8l.mjs.map +0 -1
- package/dist/client/floatingips-Ci4jHkaG.mjs +0 -591
- package/dist/client/floatingips-Ci4jHkaG.mjs.map +0 -1
- package/dist/client/images-91U7tr9Y2.mjs +0 -1976
- package/dist/client/images-91U7tr9Y2.mjs.map +0 -1
- package/dist/client/images-CS4kZQyu.mjs.map +0 -1
- package/dist/client/objects-C3azvW8m.mjs.map +0 -1
- package/dist/client/objects-CM265S6b.mjs +0 -56
- package/dist/client/objects-CM265S6b.mjs.map +0 -1
- package/dist/client/objects-EE9Cd1wI.mjs +0 -56
- package/dist/client/objects-EE9Cd1wI.mjs.map +0 -1
- package/dist/client/routeInfo-DXqB2HCf.mjs +0 -32
- package/dist/client/routeInfo-DXqB2HCf.mjs.map +0 -1
- package/dist/client/routes-CBd8CCuM.mjs +0 -115
- package/dist/client/routes-CBd8CCuM.mjs.map +0 -1
- package/dist/client/routes-CdDm-hhO.mjs.map +0 -1
- package/dist/client/securitygroups-Bd_uV4S9.mjs +0 -595
- package/dist/client/securitygroups-Bd_uV4S9.mjs.map +0 -1
- package/dist/client/securitygroups-Byte-iSp.mjs.map +0 -1
- package/dist/client/useSecurityGroupPermissions-C29mzb3b.mjs.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -7,11 +7,7 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
8
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
9
|
var __commonJS = (cb, mod) => function __require() {
|
|
10
|
-
|
|
11
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
12
|
-
} catch (e) {
|
|
13
|
-
throw mod = 0, e;
|
|
14
|
-
}
|
|
10
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
11
|
};
|
|
16
12
|
var __export = (target, all) => {
|
|
17
13
|
for (var name in all)
|
|
@@ -260,7 +256,7 @@ var require_error = __commonJS({
|
|
|
260
256
|
}
|
|
261
257
|
};
|
|
262
258
|
exports2.SignalOpenstackError = SignalOpenstackError4;
|
|
263
|
-
var
|
|
259
|
+
var SignalOpenstackApiError2 = class SignalOpenstackApiError extends Error {
|
|
264
260
|
static {
|
|
265
261
|
__name(this, "SignalOpenstackApiError");
|
|
266
262
|
}
|
|
@@ -271,7 +267,7 @@ var require_error = __commonJS({
|
|
|
271
267
|
this.statusCode = statusCode;
|
|
272
268
|
}
|
|
273
269
|
};
|
|
274
|
-
exports2.SignalOpenstackApiError =
|
|
270
|
+
exports2.SignalOpenstackApiError = SignalOpenstackApiError2;
|
|
275
271
|
}
|
|
276
272
|
});
|
|
277
273
|
|
|
@@ -27346,7 +27342,7 @@ var require_esm = __commonJS({
|
|
|
27346
27342
|
Object.defineProperty(exports2, "__esModule", {
|
|
27347
27343
|
value: true
|
|
27348
27344
|
});
|
|
27349
|
-
exports2.validateAndEncodeResourceId = exports2.encodeOpenstackPath = exports2.encodeOpenstackPathSegment = exports2.redactSensitiveData = exports2.loggerConfig = exports2.logger = exports2.SignalOpenstackError = exports2.SignalOpenstackSession = void 0;
|
|
27345
|
+
exports2.validateAndEncodeResourceId = exports2.encodeOpenstackPath = exports2.encodeOpenstackPathSegment = exports2.redactSensitiveData = exports2.loggerConfig = exports2.logger = exports2.SignalOpenstackApiError = exports2.SignalOpenstackError = exports2.SignalOpenstackSession = void 0;
|
|
27350
27346
|
var session_1 = require_session();
|
|
27351
27347
|
Object.defineProperty(exports2, "SignalOpenstackSession", {
|
|
27352
27348
|
enumerable: true,
|
|
@@ -27361,6 +27357,12 @@ var require_esm = __commonJS({
|
|
|
27361
27357
|
return error_1.SignalOpenstackError;
|
|
27362
27358
|
}, "get")
|
|
27363
27359
|
});
|
|
27360
|
+
Object.defineProperty(exports2, "SignalOpenstackApiError", {
|
|
27361
|
+
enumerable: true,
|
|
27362
|
+
get: /* @__PURE__ */ __name(function() {
|
|
27363
|
+
return error_1.SignalOpenstackApiError;
|
|
27364
|
+
}, "get")
|
|
27365
|
+
});
|
|
27364
27366
|
var logger_1 = require_logger();
|
|
27365
27367
|
Object.defineProperty(exports2, "logger", {
|
|
27366
27368
|
enumerable: true,
|
|
@@ -28593,11 +28595,69 @@ var import_zod2 = require("zod");
|
|
|
28593
28595
|
// src/server/trpc.ts
|
|
28594
28596
|
var import_server = require("@trpc/server");
|
|
28595
28597
|
var import_zod = require("zod");
|
|
28598
|
+
var import_signal_openstack = __toESM(require_esm());
|
|
28596
28599
|
var t = import_server.initTRPC.context().create();
|
|
28600
|
+
var openstackErrorMiddleware = t.middleware(async ({ next }) => {
|
|
28601
|
+
const result = await next();
|
|
28602
|
+
if (!result.ok) {
|
|
28603
|
+
const cause = result.error.cause;
|
|
28604
|
+
if (cause instanceof import_signal_openstack.SignalOpenstackApiError) {
|
|
28605
|
+
if (cause.statusCode === 401) {
|
|
28606
|
+
return {
|
|
28607
|
+
...result,
|
|
28608
|
+
error: new import_server.TRPCError({
|
|
28609
|
+
code: "UNAUTHORIZED",
|
|
28610
|
+
message: "Session expired or invalid. Please log in again.",
|
|
28611
|
+
cause
|
|
28612
|
+
})
|
|
28613
|
+
};
|
|
28614
|
+
}
|
|
28615
|
+
if (cause.statusCode === 400) {
|
|
28616
|
+
return {
|
|
28617
|
+
...result,
|
|
28618
|
+
error: new import_server.TRPCError({
|
|
28619
|
+
code: "BAD_REQUEST",
|
|
28620
|
+
message: "The OpenStack request was invalid.",
|
|
28621
|
+
cause
|
|
28622
|
+
})
|
|
28623
|
+
};
|
|
28624
|
+
}
|
|
28625
|
+
if (cause.statusCode === 404) {
|
|
28626
|
+
return {
|
|
28627
|
+
...result,
|
|
28628
|
+
error: new import_server.TRPCError({
|
|
28629
|
+
code: "NOT_FOUND",
|
|
28630
|
+
message: "Resource not found or not accessible. This can happen if you switched domains in another tab.",
|
|
28631
|
+
cause
|
|
28632
|
+
})
|
|
28633
|
+
};
|
|
28634
|
+
}
|
|
28635
|
+
if (cause.statusCode === 403) {
|
|
28636
|
+
return {
|
|
28637
|
+
...result,
|
|
28638
|
+
error: new import_server.TRPCError({
|
|
28639
|
+
code: "FORBIDDEN",
|
|
28640
|
+
message: "Access denied. You may not have the required role assignment.",
|
|
28641
|
+
cause
|
|
28642
|
+
})
|
|
28643
|
+
};
|
|
28644
|
+
}
|
|
28645
|
+
return {
|
|
28646
|
+
...result,
|
|
28647
|
+
error: new import_server.TRPCError({
|
|
28648
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
28649
|
+
message: "An unexpected OpenStack error occurred",
|
|
28650
|
+
cause
|
|
28651
|
+
})
|
|
28652
|
+
};
|
|
28653
|
+
}
|
|
28654
|
+
}
|
|
28655
|
+
return result;
|
|
28656
|
+
});
|
|
28597
28657
|
var router = t.router;
|
|
28598
28658
|
var auroraRouter = t.router;
|
|
28599
28659
|
var mergeRouters = t.mergeRouters;
|
|
28600
|
-
var publicProcedure = t.procedure;
|
|
28660
|
+
var publicProcedure = t.procedure.use(openstackErrorMiddleware);
|
|
28601
28661
|
var createCallerFactory = t.createCallerFactory;
|
|
28602
28662
|
var protectedProcedure = publicProcedure.use(/* @__PURE__ */ __name(async function isAuthenticated(opts) {
|
|
28603
28663
|
if (opts.ctx.validateSession() === false) {
|
|
@@ -28717,6 +28777,7 @@ var sessionRouter = {
|
|
|
28717
28777
|
domain
|
|
28718
28778
|
};
|
|
28719
28779
|
}),
|
|
28780
|
+
// Errors from rescopeSession are handled by openstackErrorMiddleware
|
|
28720
28781
|
setCurrentScope: protectedProcedure.input(discriminatedSchema).mutation(async ({ input, ctx }) => {
|
|
28721
28782
|
switch (input.type) {
|
|
28722
28783
|
case "domain": {
|
|
@@ -28724,9 +28785,15 @@ var sessionRouter = {
|
|
|
28724
28785
|
domainId: input.domainId
|
|
28725
28786
|
});
|
|
28726
28787
|
const token = session?.getToken();
|
|
28788
|
+
if (!token?.tokenData.domain) {
|
|
28789
|
+
throw new import_server2.TRPCError({
|
|
28790
|
+
code: "NOT_FOUND",
|
|
28791
|
+
message: "Failed to rescope to the requested domain."
|
|
28792
|
+
});
|
|
28793
|
+
}
|
|
28727
28794
|
return {
|
|
28728
28795
|
project: null,
|
|
28729
|
-
domain: token
|
|
28796
|
+
domain: token.tokenData.domain
|
|
28730
28797
|
};
|
|
28731
28798
|
}
|
|
28732
28799
|
case "project": {
|
|
@@ -28734,9 +28801,15 @@ var sessionRouter = {
|
|
|
28734
28801
|
projectId: input.projectId
|
|
28735
28802
|
});
|
|
28736
28803
|
const token = session?.getToken();
|
|
28804
|
+
if (!token?.tokenData.project) {
|
|
28805
|
+
throw new import_server2.TRPCError({
|
|
28806
|
+
code: "NOT_FOUND",
|
|
28807
|
+
message: "Failed to rescope to the requested project."
|
|
28808
|
+
});
|
|
28809
|
+
}
|
|
28737
28810
|
return {
|
|
28738
|
-
project: token
|
|
28739
|
-
domain: token
|
|
28811
|
+
project: token.tokenData.project,
|
|
28812
|
+
domain: token.tokenData.project.domain
|
|
28740
28813
|
};
|
|
28741
28814
|
}
|
|
28742
28815
|
case "unscoped": {
|
|
@@ -29859,7 +29932,8 @@ var imagesPaginatedResponseSchema = import_zod4.z.object({
|
|
|
29859
29932
|
images: import_zod4.z.array(imageSchema),
|
|
29860
29933
|
first: import_zod4.z.string().optional(),
|
|
29861
29934
|
next: import_zod4.z.string().optional(),
|
|
29862
|
-
schema: import_zod4.z.string().optional()
|
|
29935
|
+
schema: import_zod4.z.string().optional(),
|
|
29936
|
+
totalCount: import_zod4.z.number().optional()
|
|
29863
29937
|
});
|
|
29864
29938
|
|
|
29865
29939
|
// src/server/Compute/routers/imageRouter.ts
|
|
@@ -29874,22 +29948,26 @@ var imageRouter = {
|
|
|
29874
29948
|
validateGlanceService(glance);
|
|
29875
29949
|
const FRONTEND_PAGE_SIZE = 50;
|
|
29876
29950
|
const OPENSTACK_PAGE_SIZE = 100;
|
|
29877
|
-
const MIN_RESULTS_WHEN_SEARCHING = 50;
|
|
29878
29951
|
const MAX_PAGES_TO_SEARCH = 1e3;
|
|
29879
29952
|
const allImages = [];
|
|
29880
29953
|
const hasSearchTerm = queryInput.name && queryInput.name.trim();
|
|
29881
29954
|
const queryParams = new URLSearchParams();
|
|
29882
|
-
const
|
|
29955
|
+
const apiQuery = {
|
|
29883
29956
|
sort_key: queryInput.sort_key,
|
|
29884
29957
|
sort_dir: queryInput.sort_dir,
|
|
29885
29958
|
sort: queryInput.sort,
|
|
29886
29959
|
limit: OPENSTACK_PAGE_SIZE,
|
|
29887
|
-
|
|
29960
|
+
// Only pass single-value filters to API (multi-value filters start with "in:")
|
|
29961
|
+
status: queryInput.status?.startsWith("in:") ? void 0 : queryInput.status,
|
|
29962
|
+
visibility: queryInput.visibility === "all" ? void 0 : queryInput.visibility,
|
|
29963
|
+
disk_format: queryInput.disk_format?.startsWith("in:") ? void 0 : queryInput.disk_format,
|
|
29964
|
+
container_format: queryInput.container_format?.startsWith("in:") ? void 0 : queryInput.container_format,
|
|
29965
|
+
protected: queryInput.protected,
|
|
29966
|
+
owner: queryInput.owner
|
|
29888
29967
|
};
|
|
29889
|
-
applyImageQueryParams(queryParams,
|
|
29968
|
+
applyImageQueryParams(queryParams, apiQuery);
|
|
29890
29969
|
let currentUrl = `v2/images?${queryParams.toString()}`;
|
|
29891
29970
|
let pageCount = 0;
|
|
29892
|
-
let nextMarker;
|
|
29893
29971
|
while (currentUrl && pageCount < MAX_PAGES_TO_SEARCH) {
|
|
29894
29972
|
const response = await glance.get(currentUrl).catch((error) => {
|
|
29895
29973
|
throw mapErrorResponseToTRPCError(error, {
|
|
@@ -29902,41 +29980,7 @@ var imageRouter = {
|
|
|
29902
29980
|
}
|
|
29903
29981
|
allImages.push(...parsedData.data.images);
|
|
29904
29982
|
pageCount++;
|
|
29905
|
-
|
|
29906
|
-
let filteredSoFar = filterBySearchParams(allImages, queryInput.name, [
|
|
29907
|
-
"name"
|
|
29908
|
-
]);
|
|
29909
|
-
if (queryInput.visibility && queryInput.visibility !== "all") {
|
|
29910
|
-
filteredSoFar = filteredSoFar.filter((img) => img.visibility === queryInput.visibility);
|
|
29911
|
-
}
|
|
29912
|
-
if (queryInput.status) {
|
|
29913
|
-
const values = parseMultiValue(queryInput.status);
|
|
29914
|
-
filteredSoFar = filteredSoFar.filter((img) => values.includes(img.status ?? ""));
|
|
29915
|
-
}
|
|
29916
|
-
if (queryInput.disk_format) {
|
|
29917
|
-
const values = parseMultiValue(queryInput.disk_format);
|
|
29918
|
-
filteredSoFar = filteredSoFar.filter((img) => values.includes(img.disk_format ?? ""));
|
|
29919
|
-
}
|
|
29920
|
-
if (queryInput.container_format) {
|
|
29921
|
-
const values = parseMultiValue(queryInput.container_format);
|
|
29922
|
-
filteredSoFar = filteredSoFar.filter((img) => values.includes(img.container_format ?? ""));
|
|
29923
|
-
}
|
|
29924
|
-
if (queryInput.protected !== void 0 && queryInput.protected !== null) {
|
|
29925
|
-
const wantProtected = queryInput.protected === "true";
|
|
29926
|
-
filteredSoFar = filteredSoFar.filter((img) => !!img.protected === wantProtected);
|
|
29927
|
-
}
|
|
29928
|
-
if (queryInput.owner) {
|
|
29929
|
-
filteredSoFar = filteredSoFar.filter((img) => img.owner === queryInput.owner);
|
|
29930
|
-
}
|
|
29931
|
-
if (filteredSoFar.length >= MIN_RESULTS_WHEN_SEARCHING) {
|
|
29932
|
-
nextMarker = parsedData.data.next;
|
|
29933
|
-
break;
|
|
29934
|
-
}
|
|
29935
|
-
}
|
|
29936
|
-
if (!hasSearchTerm) {
|
|
29937
|
-
nextMarker = parsedData.data.next;
|
|
29938
|
-
break;
|
|
29939
|
-
}
|
|
29983
|
+
validateRelativeUrl(parsedData.data.next, "pagination URL");
|
|
29940
29984
|
currentUrl = parsedData.data.next;
|
|
29941
29985
|
}
|
|
29942
29986
|
let filteredImages = allImages;
|
|
@@ -29967,16 +30011,21 @@ var imageRouter = {
|
|
|
29967
30011
|
if (queryInput.owner) {
|
|
29968
30012
|
filteredImages = filteredImages.filter((img) => img.owner === queryInput.owner);
|
|
29969
30013
|
}
|
|
29970
|
-
|
|
29971
|
-
|
|
30014
|
+
let startIndex = 0;
|
|
30015
|
+
if (marker) {
|
|
30016
|
+
const markerIndex = filteredImages.findIndex((img) => img.id === marker);
|
|
30017
|
+
startIndex = markerIndex >= 0 ? markerIndex + 1 : 0;
|
|
30018
|
+
}
|
|
30019
|
+
const endIndex = startIndex + FRONTEND_PAGE_SIZE;
|
|
29972
30020
|
const paginatedImages = filteredImages.slice(startIndex, endIndex);
|
|
29973
|
-
const hasMore = filteredImages.length
|
|
29974
|
-
const nextPageMarker =
|
|
30021
|
+
const hasMore = endIndex < filteredImages.length;
|
|
30022
|
+
const nextPageMarker = hasMore ? filteredImages[endIndex - 1]?.id : void 0;
|
|
29975
30023
|
return {
|
|
29976
30024
|
images: paginatedImages,
|
|
29977
30025
|
first: void 0,
|
|
29978
30026
|
next: hasMore ? nextPageMarker : void 0,
|
|
29979
|
-
schema: "/v2/schemas/images"
|
|
30027
|
+
schema: "/v2/schemas/images",
|
|
30028
|
+
totalCount: filteredImages.length
|
|
29980
30029
|
};
|
|
29981
30030
|
}, "list images");
|
|
29982
30031
|
}),
|
|
@@ -30112,16 +30161,25 @@ var imageRouter = {
|
|
|
30112
30161
|
validateGlanceService(glance);
|
|
30113
30162
|
const fileStream = import_node_stream.Readable.fromWeb(input);
|
|
30114
30163
|
const { validatedImageId, validatedFileSize, validatedFile } = validateUploadInput(imageId, fileSize, fileStream);
|
|
30115
|
-
|
|
30164
|
+
const token = openstackSession.getToken();
|
|
30165
|
+
const tokenProjectId = token?.tokenData.project?.id;
|
|
30166
|
+
if (!tokenProjectId) {
|
|
30167
|
+
throw new import_server6.TRPCError({
|
|
30168
|
+
code: "UNAUTHORIZED",
|
|
30169
|
+
message: "Project scope required for upload progress tracking"
|
|
30170
|
+
});
|
|
30171
|
+
}
|
|
30172
|
+
const scopedUploadId = `${tokenProjectId}:${validatedImageId}`;
|
|
30173
|
+
uploadProgress.set(scopedUploadId, {
|
|
30116
30174
|
uploaded: 0,
|
|
30117
30175
|
total: validatedFileSize
|
|
30118
30176
|
});
|
|
30119
30177
|
try {
|
|
30120
|
-
const progress = uploadProgress.get(
|
|
30178
|
+
const progress = uploadProgress.get(scopedUploadId);
|
|
30121
30179
|
const progressTracker = new import_node_stream.Transform({
|
|
30122
30180
|
transform(chunk, _encoding, callback) {
|
|
30123
30181
|
progress.uploaded += chunk.length;
|
|
30124
|
-
uploadProgressEmitter.emit(`progress:${
|
|
30182
|
+
uploadProgressEmitter.emit(`progress:${scopedUploadId}`, {
|
|
30125
30183
|
uploaded: progress.uploaded,
|
|
30126
30184
|
total: progress.total,
|
|
30127
30185
|
percent: progress.total > 0 ? Math.round(progress.uploaded / progress.total * 100) : 0
|
|
@@ -30155,24 +30213,39 @@ var imageRouter = {
|
|
|
30155
30213
|
progressTracker.destroy();
|
|
30156
30214
|
throw ImageErrorHandlers.upload(uploadResponse, validatedImageId, "application/octet-stream");
|
|
30157
30215
|
}
|
|
30158
|
-
uploadProgressEmitter.emit(`progress:${
|
|
30216
|
+
uploadProgressEmitter.emit(`progress:${scopedUploadId}:complete`);
|
|
30159
30217
|
return {
|
|
30160
30218
|
success: true,
|
|
30161
30219
|
imageId: validatedImageId
|
|
30162
30220
|
};
|
|
30163
30221
|
} catch (error) {
|
|
30164
|
-
uploadProgressEmitter.emit(`progress:${
|
|
30222
|
+
uploadProgressEmitter.emit(`progress:${scopedUploadId}:error`, error);
|
|
30165
30223
|
throw ImageErrorHandlers.upload(error, validatedImageId, "application/octet-stream");
|
|
30166
30224
|
} finally {
|
|
30167
|
-
uploadProgress.delete(
|
|
30225
|
+
uploadProgress.delete(scopedUploadId);
|
|
30168
30226
|
}
|
|
30169
30227
|
}, "upload image");
|
|
30170
30228
|
}),
|
|
30171
30229
|
watchUploadProgress: projectScopedProcedure.input(import_zod5.z.object({
|
|
30172
30230
|
uploadId: import_zod5.z.string()
|
|
30173
|
-
})).subscription(async function* ({ input }) {
|
|
30231
|
+
})).subscription(async function* ({ input, ctx }) {
|
|
30174
30232
|
const uploadId = input.uploadId;
|
|
30175
|
-
|
|
30233
|
+
if (uploadId.includes(":")) {
|
|
30234
|
+
throw new import_server6.TRPCError({
|
|
30235
|
+
code: "BAD_REQUEST",
|
|
30236
|
+
message: "Invalid uploadId format"
|
|
30237
|
+
});
|
|
30238
|
+
}
|
|
30239
|
+
const token = ctx.openstack?.getToken();
|
|
30240
|
+
const projectId = token?.tokenData.project?.id;
|
|
30241
|
+
if (!projectId) {
|
|
30242
|
+
throw new import_server6.TRPCError({
|
|
30243
|
+
code: "UNAUTHORIZED",
|
|
30244
|
+
message: "Project scope required for upload progress tracking"
|
|
30245
|
+
});
|
|
30246
|
+
}
|
|
30247
|
+
const scopedUploadId = `${projectId}:${uploadId}`;
|
|
30248
|
+
const current = uploadProgress.get(scopedUploadId);
|
|
30176
30249
|
if (current) {
|
|
30177
30250
|
yield {
|
|
30178
30251
|
...current,
|
|
@@ -30200,9 +30273,9 @@ var imageRouter = {
|
|
|
30200
30273
|
waitResolver?.();
|
|
30201
30274
|
waitResolver = null;
|
|
30202
30275
|
}, "onError");
|
|
30203
|
-
uploadProgressEmitter.on(`progress:${
|
|
30204
|
-
uploadProgressEmitter.on(`progress:${
|
|
30205
|
-
uploadProgressEmitter.on(`progress:${
|
|
30276
|
+
uploadProgressEmitter.on(`progress:${scopedUploadId}`, onProgress);
|
|
30277
|
+
uploadProgressEmitter.on(`progress:${scopedUploadId}:complete`, onComplete);
|
|
30278
|
+
uploadProgressEmitter.on(`progress:${scopedUploadId}:error`, onError);
|
|
30206
30279
|
try {
|
|
30207
30280
|
while (!isComplete && !isError) {
|
|
30208
30281
|
while (queue.length > 0) {
|
|
@@ -30229,9 +30302,9 @@ var imageRouter = {
|
|
|
30229
30302
|
throw error;
|
|
30230
30303
|
}
|
|
30231
30304
|
} finally {
|
|
30232
|
-
uploadProgressEmitter.off(`progress:${
|
|
30233
|
-
uploadProgressEmitter.off(`progress:${
|
|
30234
|
-
uploadProgressEmitter.off(`progress:${
|
|
30305
|
+
uploadProgressEmitter.off(`progress:${scopedUploadId}`, onProgress);
|
|
30306
|
+
uploadProgressEmitter.off(`progress:${scopedUploadId}:complete`, onComplete);
|
|
30307
|
+
uploadProgressEmitter.off(`progress:${scopedUploadId}:error`, onError);
|
|
30235
30308
|
}
|
|
30236
30309
|
}),
|
|
30237
30310
|
updateImage: projectScopedProcedure.input(updateImageInputSchema).mutation(async ({ input, ctx }) => {
|
|
@@ -30772,7 +30845,7 @@ var ERROR_CODES = {
|
|
|
30772
30845
|
};
|
|
30773
30846
|
|
|
30774
30847
|
// src/server/Compute/helpers/flavorHelpers.ts
|
|
30775
|
-
var
|
|
30848
|
+
var import_signal_openstack2 = __toESM(require_esm());
|
|
30776
30849
|
function isErrorWithStatus(error) {
|
|
30777
30850
|
return typeof error === "object" && error !== null && ("statusCode" in error || "status" in error);
|
|
30778
30851
|
}
|
|
@@ -31127,9 +31200,9 @@ async function getFlavorById(compute, flavorId) {
|
|
|
31127
31200
|
}
|
|
31128
31201
|
let encodedId;
|
|
31129
31202
|
try {
|
|
31130
|
-
encodedId = (0,
|
|
31203
|
+
encodedId = (0, import_signal_openstack2.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31131
31204
|
} catch (error) {
|
|
31132
|
-
if (error instanceof
|
|
31205
|
+
if (error instanceof import_signal_openstack2.SignalOpenstackError) {
|
|
31133
31206
|
throw new import_server7.TRPCError({
|
|
31134
31207
|
code: "BAD_REQUEST",
|
|
31135
31208
|
message: ERROR_CODES.GET_FLAVOR_DETAILS_INVALID_ID,
|
|
@@ -31243,9 +31316,9 @@ async function deleteFlavor(compute, flavorId) {
|
|
|
31243
31316
|
}
|
|
31244
31317
|
let encodedId;
|
|
31245
31318
|
try {
|
|
31246
|
-
encodedId = (0,
|
|
31319
|
+
encodedId = (0, import_signal_openstack2.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31247
31320
|
} catch (error) {
|
|
31248
|
-
if (error instanceof
|
|
31321
|
+
if (error instanceof import_signal_openstack2.SignalOpenstackError) {
|
|
31249
31322
|
throw new import_server7.TRPCError({
|
|
31250
31323
|
code: "BAD_REQUEST",
|
|
31251
31324
|
message: ERROR_CODES.DELETE_FLAVOR_INVALID_ID,
|
|
@@ -31274,9 +31347,9 @@ __name(deleteFlavor, "deleteFlavor");
|
|
|
31274
31347
|
async function createExtraSpecs(compute, flavorId, extra_specs) {
|
|
31275
31348
|
let encodedId;
|
|
31276
31349
|
try {
|
|
31277
|
-
encodedId = (0,
|
|
31350
|
+
encodedId = (0, import_signal_openstack2.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31278
31351
|
} catch (error) {
|
|
31279
|
-
if (error instanceof
|
|
31352
|
+
if (error instanceof import_signal_openstack2.SignalOpenstackError) {
|
|
31280
31353
|
throw new import_server7.TRPCError({
|
|
31281
31354
|
code: "BAD_REQUEST",
|
|
31282
31355
|
message: ERROR_CODES.CREATE_EXTRA_SPECS_FAILED,
|
|
@@ -31314,9 +31387,9 @@ __name(createExtraSpecs, "createExtraSpecs");
|
|
|
31314
31387
|
async function getExtraSpecs(compute, flavorId) {
|
|
31315
31388
|
let encodedId;
|
|
31316
31389
|
try {
|
|
31317
|
-
encodedId = (0,
|
|
31390
|
+
encodedId = (0, import_signal_openstack2.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31318
31391
|
} catch (error) {
|
|
31319
|
-
if (error instanceof
|
|
31392
|
+
if (error instanceof import_signal_openstack2.SignalOpenstackError) {
|
|
31320
31393
|
throw new import_server7.TRPCError({
|
|
31321
31394
|
code: "BAD_REQUEST",
|
|
31322
31395
|
message: ERROR_CODES.GET_EXTRA_SPECS_FAILED,
|
|
@@ -31352,10 +31425,10 @@ __name(getExtraSpecs, "getExtraSpecs");
|
|
|
31352
31425
|
async function deleteExtraSpec(compute, flavorId, key) {
|
|
31353
31426
|
let encodedId, encodedKey;
|
|
31354
31427
|
try {
|
|
31355
|
-
encodedId = (0,
|
|
31356
|
-
encodedKey = (0,
|
|
31428
|
+
encodedId = (0, import_signal_openstack2.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31429
|
+
encodedKey = (0, import_signal_openstack2.encodeOpenstackPathSegment)(key, "Extra spec key");
|
|
31357
31430
|
} catch (error) {
|
|
31358
|
-
if (error instanceof
|
|
31431
|
+
if (error instanceof import_signal_openstack2.SignalOpenstackError) {
|
|
31359
31432
|
throw new import_server7.TRPCError({
|
|
31360
31433
|
code: "BAD_REQUEST",
|
|
31361
31434
|
message: ERROR_CODES.DELETE_EXTRA_SPEC_FAILED,
|
|
@@ -31380,9 +31453,9 @@ __name(deleteExtraSpec, "deleteExtraSpec");
|
|
|
31380
31453
|
async function getFlavorAccess(compute, flavorId) {
|
|
31381
31454
|
let encodedId;
|
|
31382
31455
|
try {
|
|
31383
|
-
encodedId = (0,
|
|
31456
|
+
encodedId = (0, import_signal_openstack2.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31384
31457
|
} catch (error) {
|
|
31385
|
-
if (error instanceof
|
|
31458
|
+
if (error instanceof import_signal_openstack2.SignalOpenstackError) {
|
|
31386
31459
|
throw new import_server7.TRPCError({
|
|
31387
31460
|
code: "BAD_REQUEST",
|
|
31388
31461
|
message: ERROR_CODES.GET_FLAVOR_ACCESS_FAILED,
|
|
@@ -31418,9 +31491,9 @@ __name(getFlavorAccess, "getFlavorAccess");
|
|
|
31418
31491
|
async function addTenantAccess(compute, flavorId, tenantId) {
|
|
31419
31492
|
let encodedId;
|
|
31420
31493
|
try {
|
|
31421
|
-
encodedId = (0,
|
|
31494
|
+
encodedId = (0, import_signal_openstack2.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31422
31495
|
} catch (error) {
|
|
31423
|
-
if (error instanceof
|
|
31496
|
+
if (error instanceof import_signal_openstack2.SignalOpenstackError) {
|
|
31424
31497
|
throw new import_server7.TRPCError({
|
|
31425
31498
|
code: "BAD_REQUEST",
|
|
31426
31499
|
message: ERROR_CODES.ADD_TENANT_ACCESS_FAILED,
|
|
@@ -31461,9 +31534,9 @@ __name(addTenantAccess, "addTenantAccess");
|
|
|
31461
31534
|
async function removeTenantAccess(compute, flavorId, tenantId) {
|
|
31462
31535
|
let encodedId;
|
|
31463
31536
|
try {
|
|
31464
|
-
encodedId = (0,
|
|
31537
|
+
encodedId = (0, import_signal_openstack2.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31465
31538
|
} catch (error) {
|
|
31466
|
-
if (error instanceof
|
|
31539
|
+
if (error instanceof import_signal_openstack2.SignalOpenstackError) {
|
|
31467
31540
|
throw new import_server7.TRPCError({
|
|
31468
31541
|
code: "BAD_REQUEST",
|
|
31469
31542
|
message: ERROR_CODES.REMOVE_TENANT_ACCESS_FAILED,
|
|
@@ -31504,7 +31577,7 @@ __name(removeTenantAccess, "removeTenantAccess");
|
|
|
31504
31577
|
|
|
31505
31578
|
// src/server/Compute/routers/flavorRouter.ts
|
|
31506
31579
|
var import_server8 = require("@trpc/server");
|
|
31507
|
-
var
|
|
31580
|
+
var import_signal_openstack3 = __toESM(require_esm());
|
|
31508
31581
|
var flavorRouter = {
|
|
31509
31582
|
getFlavorById: projectScopedProcedure.input(import_zod9.z.object({
|
|
31510
31583
|
project_id: import_zod9.z.string(),
|
|
@@ -31749,9 +31822,9 @@ var flavorRouter = {
|
|
|
31749
31822
|
}
|
|
31750
31823
|
let encodedId;
|
|
31751
31824
|
try {
|
|
31752
|
-
encodedId = (0,
|
|
31825
|
+
encodedId = (0, import_signal_openstack3.validateAndEncodeResourceId)(flavorId, "Flavor");
|
|
31753
31826
|
} catch (error) {
|
|
31754
|
-
if (error instanceof
|
|
31827
|
+
if (error instanceof import_signal_openstack3.SignalOpenstackError) {
|
|
31755
31828
|
throw new import_server8.TRPCError({
|
|
31756
31829
|
code: "BAD_REQUEST",
|
|
31757
31830
|
message: ERROR_CODES.GET_FLAVOR_ACCESS_FAILED,
|
|
@@ -34421,7 +34494,7 @@ var cephUploadProcedure = protectedProcedure.use(/* @__PURE__ */ __name(async fu
|
|
|
34421
34494
|
|
|
34422
34495
|
// src/server/Storage/helpers/s3ErrorMapper.ts
|
|
34423
34496
|
var import_server13 = require("@trpc/server");
|
|
34424
|
-
var
|
|
34497
|
+
var import_signal_openstack4 = __toESM(require_esm());
|
|
34425
34498
|
var S3_ERROR_MAP = {
|
|
34426
34499
|
NoSuchBucket: "NOT_FOUND",
|
|
34427
34500
|
NoSuchKey: "NOT_FOUND",
|
|
@@ -34429,6 +34502,7 @@ var S3_ERROR_MAP = {
|
|
|
34429
34502
|
NoSuchVersion: "NOT_FOUND",
|
|
34430
34503
|
NoSuchBucketPolicy: "NOT_FOUND",
|
|
34431
34504
|
NoSuchCORSConfiguration: "NOT_FOUND",
|
|
34505
|
+
NoSuchLifecycleConfiguration: "NOT_FOUND",
|
|
34432
34506
|
BucketAlreadyExists: "CONFLICT",
|
|
34433
34507
|
BucketAlreadyOwnedByYou: "CONFLICT",
|
|
34434
34508
|
BucketNotEmpty: "PRECONDITION_FAILED",
|
|
@@ -34458,7 +34532,7 @@ function mapS3ErrorToTRPCError(error, context) {
|
|
|
34458
34532
|
const errorCode = s3Error.Code ?? s3Error.name ?? "";
|
|
34459
34533
|
const trpcCode = S3_ERROR_MAP[errorCode] ?? "INTERNAL_SERVER_ERROR";
|
|
34460
34534
|
if (!S3_ERROR_MAP[errorCode] && errorCode) {
|
|
34461
|
-
|
|
34535
|
+
import_signal_openstack4.logger.warn("Unmapped S3 error code", {
|
|
34462
34536
|
errorCode,
|
|
34463
34537
|
operation: context.operation,
|
|
34464
34538
|
errorName: s3Error.name
|
|
@@ -34884,6 +34958,187 @@ var setCorsInputSchema = projectScopedInputSchema.extend({
|
|
|
34884
34958
|
var deleteCorsInputSchema = projectScopedInputSchema.extend({
|
|
34885
34959
|
bucketName: existingBucketNameSchema
|
|
34886
34960
|
});
|
|
34961
|
+
var lifecycleRuleStatusSchema = import_zod13.z.enum([
|
|
34962
|
+
"Enabled",
|
|
34963
|
+
"Disabled"
|
|
34964
|
+
]);
|
|
34965
|
+
var lifecycleExpirationSchema = import_zod13.z.object({
|
|
34966
|
+
Days: import_zod13.z.number().int().min(1).max(3650).optional(),
|
|
34967
|
+
Date: import_zod13.z.string().datetime({
|
|
34968
|
+
offset: true
|
|
34969
|
+
}).optional(),
|
|
34970
|
+
ExpiredObjectDeleteMarker: import_zod13.z.boolean().optional()
|
|
34971
|
+
}).refine((val) => {
|
|
34972
|
+
return val.Days !== void 0 || val.Date !== void 0 || val.ExpiredObjectDeleteMarker !== void 0;
|
|
34973
|
+
}, "Expiration must specify either Days, Date, or ExpiredObjectDeleteMarker").refine((val) => {
|
|
34974
|
+
return !(val.Days !== void 0 && val.Date !== void 0);
|
|
34975
|
+
}, "Expiration cannot specify both Days and Date").refine((val) => !(val.ExpiredObjectDeleteMarker !== void 0 && (val.Days !== void 0 || val.Date !== void 0)), "ExpiredObjectDeleteMarker cannot be combined with Days or Date");
|
|
34976
|
+
var lifecycleTransitionSchema = import_zod13.z.object({
|
|
34977
|
+
Days: import_zod13.z.number().int().min(1).optional(),
|
|
34978
|
+
Date: import_zod13.z.string().datetime({
|
|
34979
|
+
offset: true
|
|
34980
|
+
}).optional(),
|
|
34981
|
+
StorageClass: import_zod13.z.string().min(1)
|
|
34982
|
+
}).refine((val) => {
|
|
34983
|
+
return val.Days !== void 0 !== (val.Date !== void 0);
|
|
34984
|
+
}, "Transition must specify exactly one of Days or Date");
|
|
34985
|
+
var lifecycleNoncurrentVersionExpirationSchema = import_zod13.z.object({
|
|
34986
|
+
NoncurrentDays: import_zod13.z.number().int().min(1),
|
|
34987
|
+
NewerNoncurrentVersions: import_zod13.z.number().int().min(1).optional()
|
|
34988
|
+
});
|
|
34989
|
+
var lifecycleNoncurrentVersionTransitionSchema = import_zod13.z.object({
|
|
34990
|
+
NoncurrentDays: import_zod13.z.number().int().min(1),
|
|
34991
|
+
StorageClass: import_zod13.z.string().min(1),
|
|
34992
|
+
NewerNoncurrentVersions: import_zod13.z.number().int().min(1).optional()
|
|
34993
|
+
});
|
|
34994
|
+
var lifecycleAbortIncompleteMultipartUploadSchema = import_zod13.z.object({
|
|
34995
|
+
DaysAfterInitiation: import_zod13.z.number().int().min(1)
|
|
34996
|
+
});
|
|
34997
|
+
var lifecycleTagSchema = import_zod13.z.object({
|
|
34998
|
+
Key: import_zod13.z.string().min(1).max(128),
|
|
34999
|
+
Value: import_zod13.z.string().max(256)
|
|
35000
|
+
});
|
|
35001
|
+
var lifecycleFilterAndSchema = import_zod13.z.object({
|
|
35002
|
+
Prefix: import_zod13.z.string().optional(),
|
|
35003
|
+
Tags: import_zod13.z.array(lifecycleTagSchema).optional(),
|
|
35004
|
+
ObjectSizeGreaterThan: import_zod13.z.number().int().min(0).optional(),
|
|
35005
|
+
ObjectSizeLessThan: import_zod13.z.number().int().min(0).optional()
|
|
35006
|
+
}).refine((val) => {
|
|
35007
|
+
const predicateCount = (val.Prefix !== void 0 && val.Prefix !== "" ? 1 : 0) + (val.Tags?.length ?? 0) + (val.ObjectSizeGreaterThan !== void 0 ? 1 : 0) + (val.ObjectSizeLessThan !== void 0 ? 1 : 0);
|
|
35008
|
+
return predicateCount >= 2;
|
|
35009
|
+
}, {
|
|
35010
|
+
message: "And filter must contain at least 2 predicates"
|
|
35011
|
+
});
|
|
35012
|
+
var lifecycleFilterSchema = import_zod13.z.object({
|
|
35013
|
+
Prefix: import_zod13.z.string().optional(),
|
|
35014
|
+
Tag: lifecycleTagSchema.optional(),
|
|
35015
|
+
ObjectSizeGreaterThan: import_zod13.z.number().int().min(0).optional(),
|
|
35016
|
+
ObjectSizeLessThan: import_zod13.z.number().int().min(0).optional(),
|
|
35017
|
+
And: lifecycleFilterAndSchema.optional()
|
|
35018
|
+
}).refine((val) => {
|
|
35019
|
+
const topLevelConditions = [
|
|
35020
|
+
val.Prefix !== void 0,
|
|
35021
|
+
val.Tag !== void 0,
|
|
35022
|
+
val.ObjectSizeGreaterThan !== void 0,
|
|
35023
|
+
val.ObjectSizeLessThan !== void 0
|
|
35024
|
+
].filter(Boolean).length;
|
|
35025
|
+
if (topLevelConditions > 1) {
|
|
35026
|
+
return false;
|
|
35027
|
+
}
|
|
35028
|
+
if (val.And && topLevelConditions > 0) {
|
|
35029
|
+
return false;
|
|
35030
|
+
}
|
|
35031
|
+
return true;
|
|
35032
|
+
}, {
|
|
35033
|
+
message: "Multiple filter conditions (Prefix, Tag, ObjectSize) must be wrapped in an And clause"
|
|
35034
|
+
});
|
|
35035
|
+
var lifecycleRuleSchema = import_zod13.z.object({
|
|
35036
|
+
ID: import_zod13.z.string().max(255, "Rule ID must be at most 255 characters").optional(),
|
|
35037
|
+
Status: lifecycleRuleStatusSchema,
|
|
35038
|
+
Prefix: import_zod13.z.string().optional(),
|
|
35039
|
+
Filter: lifecycleFilterSchema.optional(),
|
|
35040
|
+
Expiration: lifecycleExpirationSchema.optional(),
|
|
35041
|
+
Transitions: import_zod13.z.array(lifecycleTransitionSchema).optional(),
|
|
35042
|
+
NoncurrentVersionExpiration: lifecycleNoncurrentVersionExpirationSchema.optional(),
|
|
35043
|
+
NoncurrentVersionTransitions: import_zod13.z.array(lifecycleNoncurrentVersionTransitionSchema).optional(),
|
|
35044
|
+
AbortIncompleteMultipartUpload: lifecycleAbortIncompleteMultipartUploadSchema.optional()
|
|
35045
|
+
}).refine((val) => {
|
|
35046
|
+
return val.Expiration !== void 0 || val.Transitions !== void 0 && val.Transitions.length > 0 || val.NoncurrentVersionExpiration !== void 0 || val.NoncurrentVersionTransitions !== void 0 && val.NoncurrentVersionTransitions.length > 0 || val.AbortIncompleteMultipartUpload !== void 0;
|
|
35047
|
+
}, {
|
|
35048
|
+
message: "Rule must have at least one action (Expiration, Transition, NoncurrentVersion, or AbortIncompleteMultipartUpload)"
|
|
35049
|
+
}).refine((val) => {
|
|
35050
|
+
return !(val.Filter !== void 0 && val.Prefix !== void 0);
|
|
35051
|
+
}, {
|
|
35052
|
+
message: "Rule cannot have both Filter and legacy Prefix field set (use Filter.Prefix instead)"
|
|
35053
|
+
}).refine((val) => {
|
|
35054
|
+
if (val.Expiration?.ExpiredObjectDeleteMarker !== true) {
|
|
35055
|
+
return true;
|
|
35056
|
+
}
|
|
35057
|
+
const hasTagFilter = val.Filter?.Tag !== void 0 || val.Filter?.And?.Tags !== void 0 && val.Filter.And.Tags.length > 0;
|
|
35058
|
+
return !hasTagFilter;
|
|
35059
|
+
}, {
|
|
35060
|
+
message: "ExpiredObjectDeleteMarker cannot be combined with tag-based filters"
|
|
35061
|
+
}).refine((val) => {
|
|
35062
|
+
if (val.AbortIncompleteMultipartUpload === void 0) return true;
|
|
35063
|
+
const hasTagFilter = val.Filter?.Tag !== void 0 || val.Filter?.And?.Tags !== void 0 && val.Filter.And.Tags.length > 0;
|
|
35064
|
+
return !hasTagFilter;
|
|
35065
|
+
}, {
|
|
35066
|
+
message: "AbortIncompleteMultipartUpload cannot be combined with tag-based filters"
|
|
35067
|
+
});
|
|
35068
|
+
var lifecycleRuleReadSchema = import_zod13.z.object({
|
|
35069
|
+
ID: import_zod13.z.string().optional(),
|
|
35070
|
+
Status: import_zod13.z.string(),
|
|
35071
|
+
Prefix: import_zod13.z.string().optional(),
|
|
35072
|
+
Filter: import_zod13.z.object({
|
|
35073
|
+
Prefix: import_zod13.z.string().optional(),
|
|
35074
|
+
Tag: import_zod13.z.object({
|
|
35075
|
+
Key: import_zod13.z.string(),
|
|
35076
|
+
Value: import_zod13.z.string()
|
|
35077
|
+
}).optional(),
|
|
35078
|
+
ObjectSizeGreaterThan: import_zod13.z.number().optional(),
|
|
35079
|
+
ObjectSizeLessThan: import_zod13.z.number().optional(),
|
|
35080
|
+
And: import_zod13.z.object({
|
|
35081
|
+
Prefix: import_zod13.z.string().optional(),
|
|
35082
|
+
Tags: import_zod13.z.array(import_zod13.z.object({
|
|
35083
|
+
Key: import_zod13.z.string(),
|
|
35084
|
+
Value: import_zod13.z.string()
|
|
35085
|
+
})).optional(),
|
|
35086
|
+
ObjectSizeGreaterThan: import_zod13.z.number().optional(),
|
|
35087
|
+
ObjectSizeLessThan: import_zod13.z.number().optional()
|
|
35088
|
+
}).optional()
|
|
35089
|
+
}).passthrough().optional(),
|
|
35090
|
+
Expiration: import_zod13.z.object({
|
|
35091
|
+
Days: import_zod13.z.number().optional(),
|
|
35092
|
+
Date: import_zod13.z.union([
|
|
35093
|
+
import_zod13.z.string(),
|
|
35094
|
+
import_zod13.z.date()
|
|
35095
|
+
]).optional(),
|
|
35096
|
+
ExpiredObjectDeleteMarker: import_zod13.z.boolean().optional()
|
|
35097
|
+
}).passthrough().optional(),
|
|
35098
|
+
Transitions: import_zod13.z.array(import_zod13.z.object({
|
|
35099
|
+
Days: import_zod13.z.number().optional(),
|
|
35100
|
+
Date: import_zod13.z.union([
|
|
35101
|
+
import_zod13.z.string(),
|
|
35102
|
+
import_zod13.z.date()
|
|
35103
|
+
]).optional(),
|
|
35104
|
+
StorageClass: import_zod13.z.string()
|
|
35105
|
+
}).passthrough()).optional(),
|
|
35106
|
+
NoncurrentVersionExpiration: import_zod13.z.object({
|
|
35107
|
+
NoncurrentDays: import_zod13.z.number().optional(),
|
|
35108
|
+
NewerNoncurrentVersions: import_zod13.z.number().optional()
|
|
35109
|
+
}).passthrough().optional(),
|
|
35110
|
+
NoncurrentVersionTransitions: import_zod13.z.array(import_zod13.z.object({
|
|
35111
|
+
NoncurrentDays: import_zod13.z.number().optional(),
|
|
35112
|
+
StorageClass: import_zod13.z.string(),
|
|
35113
|
+
NewerNoncurrentVersions: import_zod13.z.number().optional()
|
|
35114
|
+
}).passthrough()).optional(),
|
|
35115
|
+
AbortIncompleteMultipartUpload: import_zod13.z.object({
|
|
35116
|
+
DaysAfterInitiation: import_zod13.z.number().optional()
|
|
35117
|
+
}).passthrough().optional()
|
|
35118
|
+
});
|
|
35119
|
+
var lifecycleConfigurationSchema = import_zod13.z.object({
|
|
35120
|
+
Rules: import_zod13.z.array(lifecycleRuleSchema).min(1, "At least one lifecycle rule is required").max(100, "Maximum 100 lifecycle rules per bucket")
|
|
35121
|
+
}).refine((val) => {
|
|
35122
|
+
const ids = val.Rules.map((r) => r.ID).filter((id) => id !== void 0 && id !== "");
|
|
35123
|
+
const uniqueIds = new Set(ids);
|
|
35124
|
+
return ids.length === uniqueIds.size;
|
|
35125
|
+
}, {
|
|
35126
|
+
message: "Rule IDs must be unique within a lifecycle configuration"
|
|
35127
|
+
});
|
|
35128
|
+
var getLifecycleInputSchema = projectScopedInputSchema.extend({
|
|
35129
|
+
bucketName: existingBucketNameSchema
|
|
35130
|
+
});
|
|
35131
|
+
var getLifecycleOutputSchema = import_zod13.z.object({
|
|
35132
|
+
rules: import_zod13.z.array(lifecycleRuleReadSchema).nullable(),
|
|
35133
|
+
skippedRuleCount: import_zod13.z.number().int().min(0)
|
|
35134
|
+
});
|
|
35135
|
+
var setLifecycleInputSchema = projectScopedInputSchema.extend({
|
|
35136
|
+
bucketName: existingBucketNameSchema,
|
|
35137
|
+
lifecycleConfiguration: lifecycleConfigurationSchema
|
|
35138
|
+
});
|
|
35139
|
+
var deleteLifecycleInputSchema = projectScopedInputSchema.extend({
|
|
35140
|
+
bucketName: existingBucketNameSchema
|
|
35141
|
+
});
|
|
34887
35142
|
|
|
34888
35143
|
// src/server/Storage/routers/ceph/containerRouter.ts
|
|
34889
35144
|
var containerRouter = {
|
|
@@ -36796,17 +37051,18 @@ function checkPolicySetRateLimit(bucketName, projectId) {
|
|
|
36796
37051
|
const key = `${projectId}:${bucketName}`;
|
|
36797
37052
|
const now = Date.now();
|
|
36798
37053
|
const windowMs = 5 * 60 * 1e3;
|
|
36799
|
-
for (const [k, v] of policySetRateLimits.entries()) {
|
|
36800
|
-
if (now > v.resetAt) {
|
|
36801
|
-
policySetRateLimits.delete(k);
|
|
36802
|
-
}
|
|
36803
|
-
}
|
|
36804
37054
|
const limit = policySetRateLimits.get(key);
|
|
36805
37055
|
if (!limit || now > limit.resetAt) {
|
|
36806
37056
|
policySetRateLimits.set(key, {
|
|
36807
37057
|
count: 1,
|
|
36808
37058
|
resetAt: now + windowMs
|
|
36809
37059
|
});
|
|
37060
|
+
setTimeout(() => {
|
|
37061
|
+
const current = policySetRateLimits.get(key);
|
|
37062
|
+
if (current && current.resetAt <= Date.now()) {
|
|
37063
|
+
policySetRateLimits.delete(key);
|
|
37064
|
+
}
|
|
37065
|
+
}, windowMs).unref();
|
|
36810
37066
|
return;
|
|
36811
37067
|
}
|
|
36812
37068
|
if (limit.count >= 10) {
|
|
@@ -37024,17 +37280,18 @@ function checkCorsSetRateLimit(bucketName, projectId) {
|
|
|
37024
37280
|
const key = `${projectId}:${bucketName}`;
|
|
37025
37281
|
const now = Date.now();
|
|
37026
37282
|
const windowMs = 60 * 1e3;
|
|
37027
|
-
for (const [k, v] of corsSetRateLimits.entries()) {
|
|
37028
|
-
if (now > v.resetAt) {
|
|
37029
|
-
corsSetRateLimits.delete(k);
|
|
37030
|
-
}
|
|
37031
|
-
}
|
|
37032
37283
|
const limit = corsSetRateLimits.get(key);
|
|
37033
37284
|
if (!limit || now > limit.resetAt) {
|
|
37034
37285
|
corsSetRateLimits.set(key, {
|
|
37035
37286
|
count: 1,
|
|
37036
37287
|
resetAt: now + windowMs
|
|
37037
37288
|
});
|
|
37289
|
+
setTimeout(() => {
|
|
37290
|
+
const current = corsSetRateLimits.get(key);
|
|
37291
|
+
if (current && current.resetAt <= Date.now()) {
|
|
37292
|
+
corsSetRateLimits.delete(key);
|
|
37293
|
+
}
|
|
37294
|
+
}, windowMs).unref();
|
|
37038
37295
|
return;
|
|
37039
37296
|
}
|
|
37040
37297
|
if (limit.count >= 10) {
|
|
@@ -37153,6 +37410,274 @@ var corsRouter = {
|
|
|
37153
37410
|
})
|
|
37154
37411
|
};
|
|
37155
37412
|
|
|
37413
|
+
// src/server/Storage/routers/ceph/lifecycleRouter.ts
|
|
37414
|
+
var import_client_s37 = require("@aws-sdk/client-s3");
|
|
37415
|
+
var import_server18 = require("@trpc/server");
|
|
37416
|
+
|
|
37417
|
+
// src/server/Storage/helpers/lifecycleMapper.ts
|
|
37418
|
+
function toMidnightUTC(date) {
|
|
37419
|
+
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
|
|
37420
|
+
}
|
|
37421
|
+
__name(toMidnightUTC, "toMidnightUTC");
|
|
37422
|
+
function toSdkLifecycleRules(wireRules) {
|
|
37423
|
+
return wireRules.map((rule) => {
|
|
37424
|
+
const result = {
|
|
37425
|
+
Status: rule.Status,
|
|
37426
|
+
ID: rule.ID,
|
|
37427
|
+
Prefix: rule.Prefix,
|
|
37428
|
+
Filter: rule.Filter
|
|
37429
|
+
};
|
|
37430
|
+
if (rule.Expiration) {
|
|
37431
|
+
result.Expiration = {
|
|
37432
|
+
Days: rule.Expiration.Days,
|
|
37433
|
+
ExpiredObjectDeleteMarker: rule.Expiration.ExpiredObjectDeleteMarker,
|
|
37434
|
+
// Only normalize Expiration.Date to midnight UTC (AWS requirement)
|
|
37435
|
+
Date: rule.Expiration.Date !== void 0 ? typeof rule.Expiration.Date === "string" ? toMidnightUTC(new Date(rule.Expiration.Date)) : toMidnightUTC(rule.Expiration.Date) : void 0
|
|
37436
|
+
};
|
|
37437
|
+
}
|
|
37438
|
+
if (rule.Transitions) {
|
|
37439
|
+
result.Transitions = rule.Transitions.map((t2) => ({
|
|
37440
|
+
Days: t2.Days,
|
|
37441
|
+
StorageClass: t2.StorageClass,
|
|
37442
|
+
Date: t2.Date !== void 0 ? typeof t2.Date === "string" ? new Date(t2.Date) : t2.Date : void 0
|
|
37443
|
+
}));
|
|
37444
|
+
}
|
|
37445
|
+
if (rule.NoncurrentVersionExpiration) {
|
|
37446
|
+
result.NoncurrentVersionExpiration = {
|
|
37447
|
+
NoncurrentDays: rule.NoncurrentVersionExpiration.NoncurrentDays,
|
|
37448
|
+
NewerNoncurrentVersions: rule.NoncurrentVersionExpiration.NewerNoncurrentVersions
|
|
37449
|
+
};
|
|
37450
|
+
}
|
|
37451
|
+
if (rule.NoncurrentVersionTransitions) {
|
|
37452
|
+
result.NoncurrentVersionTransitions = rule.NoncurrentVersionTransitions.map((t2) => ({
|
|
37453
|
+
NoncurrentDays: t2.NoncurrentDays,
|
|
37454
|
+
StorageClass: t2.StorageClass,
|
|
37455
|
+
NewerNoncurrentVersions: t2.NewerNoncurrentVersions
|
|
37456
|
+
}));
|
|
37457
|
+
}
|
|
37458
|
+
if (rule.AbortIncompleteMultipartUpload) {
|
|
37459
|
+
result.AbortIncompleteMultipartUpload = {
|
|
37460
|
+
DaysAfterInitiation: rule.AbortIncompleteMultipartUpload.DaysAfterInitiation
|
|
37461
|
+
};
|
|
37462
|
+
}
|
|
37463
|
+
return result;
|
|
37464
|
+
});
|
|
37465
|
+
}
|
|
37466
|
+
__name(toSdkLifecycleRules, "toSdkLifecycleRules");
|
|
37467
|
+
var toIso = /* @__PURE__ */ __name((d) => d === void 0 ? void 0 : d instanceof Date ? d.toISOString() : String(d), "toIso");
|
|
37468
|
+
function toWireLifecycleRule(rule) {
|
|
37469
|
+
const result = {
|
|
37470
|
+
Status: rule.Status ?? "Enabled"
|
|
37471
|
+
};
|
|
37472
|
+
if (rule.ID !== void 0) result.ID = rule.ID;
|
|
37473
|
+
if (rule.Prefix !== void 0) result.Prefix = rule.Prefix;
|
|
37474
|
+
if (rule.Filter !== void 0) result.Filter = rule.Filter;
|
|
37475
|
+
if (rule.Expiration) {
|
|
37476
|
+
result.Expiration = {
|
|
37477
|
+
Days: rule.Expiration.Days,
|
|
37478
|
+
ExpiredObjectDeleteMarker: rule.Expiration.ExpiredObjectDeleteMarker,
|
|
37479
|
+
Date: toIso(rule.Expiration.Date)
|
|
37480
|
+
};
|
|
37481
|
+
}
|
|
37482
|
+
if (rule.Transitions) {
|
|
37483
|
+
result.Transitions = rule.Transitions.map((t2) => ({
|
|
37484
|
+
Days: t2.Days,
|
|
37485
|
+
StorageClass: t2.StorageClass,
|
|
37486
|
+
Date: toIso(t2.Date)
|
|
37487
|
+
}));
|
|
37488
|
+
}
|
|
37489
|
+
if (rule.NoncurrentVersionExpiration) {
|
|
37490
|
+
result.NoncurrentVersionExpiration = {
|
|
37491
|
+
NoncurrentDays: rule.NoncurrentVersionExpiration.NoncurrentDays,
|
|
37492
|
+
NewerNoncurrentVersions: rule.NoncurrentVersionExpiration.NewerNoncurrentVersions
|
|
37493
|
+
};
|
|
37494
|
+
}
|
|
37495
|
+
if (rule.NoncurrentVersionTransitions) {
|
|
37496
|
+
result.NoncurrentVersionTransitions = rule.NoncurrentVersionTransitions.map((t2) => ({
|
|
37497
|
+
NoncurrentDays: t2.NoncurrentDays,
|
|
37498
|
+
StorageClass: t2.StorageClass,
|
|
37499
|
+
NewerNoncurrentVersions: t2.NewerNoncurrentVersions
|
|
37500
|
+
}));
|
|
37501
|
+
}
|
|
37502
|
+
if (rule.AbortIncompleteMultipartUpload) {
|
|
37503
|
+
result.AbortIncompleteMultipartUpload = {
|
|
37504
|
+
DaysAfterInitiation: rule.AbortIncompleteMultipartUpload.DaysAfterInitiation
|
|
37505
|
+
};
|
|
37506
|
+
}
|
|
37507
|
+
return result;
|
|
37508
|
+
}
|
|
37509
|
+
__name(toWireLifecycleRule, "toWireLifecycleRule");
|
|
37510
|
+
|
|
37511
|
+
// src/server/Storage/routers/ceph/lifecycleRouter.ts
|
|
37512
|
+
var lifecycleSetRateLimits = /* @__PURE__ */ new Map();
|
|
37513
|
+
function checkLifecycleSetRateLimit(bucketName, projectId) {
|
|
37514
|
+
const key = `${projectId}:${bucketName}`;
|
|
37515
|
+
const now = Date.now();
|
|
37516
|
+
const windowMs = 60 * 1e3;
|
|
37517
|
+
const limit = lifecycleSetRateLimits.get(key);
|
|
37518
|
+
if (!limit || now >= limit.resetAt) {
|
|
37519
|
+
lifecycleSetRateLimits.set(key, {
|
|
37520
|
+
count: 1,
|
|
37521
|
+
resetAt: now + windowMs
|
|
37522
|
+
});
|
|
37523
|
+
setTimeout(() => {
|
|
37524
|
+
const current = lifecycleSetRateLimits.get(key);
|
|
37525
|
+
if (current && current.resetAt <= Date.now()) {
|
|
37526
|
+
lifecycleSetRateLimits.delete(key);
|
|
37527
|
+
}
|
|
37528
|
+
}, windowMs).unref();
|
|
37529
|
+
return;
|
|
37530
|
+
}
|
|
37531
|
+
if (limit.count >= 10) {
|
|
37532
|
+
throw new import_server18.TRPCError({
|
|
37533
|
+
code: "TOO_MANY_REQUESTS",
|
|
37534
|
+
message: "Lifecycle modification rate limit exceeded. Maximum 10 lifecycle changes per minute per bucket."
|
|
37535
|
+
});
|
|
37536
|
+
}
|
|
37537
|
+
limit.count++;
|
|
37538
|
+
}
|
|
37539
|
+
__name(checkLifecycleSetRateLimit, "checkLifecycleSetRateLimit");
|
|
37540
|
+
var lifecycleRouter = {
|
|
37541
|
+
/**
|
|
37542
|
+
* Get the current lifecycle configuration for a bucket.
|
|
37543
|
+
*
|
|
37544
|
+
* Returns an array of lifecycle rules, or null if no lifecycle configuration is set.
|
|
37545
|
+
* Not having a lifecycle configuration is a normal state (not an error).
|
|
37546
|
+
*
|
|
37547
|
+
* Rules are mapped and validated individually a rule that fails the lenient read schema
|
|
37548
|
+
* (e.g. authored outside Aurora) is skipped rather than failing the whole response;
|
|
37549
|
+
* `skippedRuleCount` reports how many were skipped so the client can warn and disable mutations.
|
|
37550
|
+
*
|
|
37551
|
+
* @returns { rules: LifecycleRule[] | null; skippedRuleCount: number }
|
|
37552
|
+
* @throws TRPCError NOT_FOUND - bucket does not exist
|
|
37553
|
+
* @throws TRPCError FORBIDDEN - no credentials or access denied
|
|
37554
|
+
*/
|
|
37555
|
+
get: cephProtectedProcedure.input(getLifecycleInputSchema).query(async ({ ctx, input }) => {
|
|
37556
|
+
const s3 = ctx.getCephClient();
|
|
37557
|
+
const { bucketName } = input;
|
|
37558
|
+
try {
|
|
37559
|
+
const response = await s3.send(new import_client_s37.GetBucketLifecycleConfigurationCommand({
|
|
37560
|
+
Bucket: bucketName
|
|
37561
|
+
}));
|
|
37562
|
+
const rawRules = response.Rules ?? null;
|
|
37563
|
+
if (!rawRules) {
|
|
37564
|
+
return {
|
|
37565
|
+
rules: null,
|
|
37566
|
+
skippedRuleCount: 0
|
|
37567
|
+
};
|
|
37568
|
+
}
|
|
37569
|
+
const rules = [];
|
|
37570
|
+
let skippedRuleCount = 0;
|
|
37571
|
+
for (const rawRule of rawRules) {
|
|
37572
|
+
try {
|
|
37573
|
+
const parsed = lifecycleRuleReadSchema.safeParse(toWireLifecycleRule(rawRule));
|
|
37574
|
+
if (parsed.success) {
|
|
37575
|
+
rules.push(parsed.data);
|
|
37576
|
+
continue;
|
|
37577
|
+
}
|
|
37578
|
+
skippedRuleCount++;
|
|
37579
|
+
} catch {
|
|
37580
|
+
skippedRuleCount++;
|
|
37581
|
+
}
|
|
37582
|
+
}
|
|
37583
|
+
return {
|
|
37584
|
+
rules,
|
|
37585
|
+
skippedRuleCount
|
|
37586
|
+
};
|
|
37587
|
+
} catch (error) {
|
|
37588
|
+
const s3Error = error;
|
|
37589
|
+
if (s3Error.name === "NoSuchLifecycleConfiguration" || s3Error.Code === "NoSuchLifecycleConfiguration") {
|
|
37590
|
+
return {
|
|
37591
|
+
rules: null,
|
|
37592
|
+
skippedRuleCount: 0
|
|
37593
|
+
};
|
|
37594
|
+
}
|
|
37595
|
+
throw mapS3ErrorToTRPCError(error, {
|
|
37596
|
+
operation: "get lifecycle configuration",
|
|
37597
|
+
bucket: bucketName
|
|
37598
|
+
});
|
|
37599
|
+
}
|
|
37600
|
+
}),
|
|
37601
|
+
/**
|
|
37602
|
+
* Set (create or replace) a lifecycle configuration for a bucket.
|
|
37603
|
+
*
|
|
37604
|
+
* Accepts a lifecycle configuration with an array of rules. Validates structure
|
|
37605
|
+
* before sending to S3. Replaces any existing lifecycle configuration completely.
|
|
37606
|
+
*
|
|
37607
|
+
* Rules are validated for:
|
|
37608
|
+
* - At least one action (Expiration, Transition, NoncurrentVersion, or AbortIncompleteMultipartUpload)
|
|
37609
|
+
* - ID: max 255 characters (optional)
|
|
37610
|
+
* - Filter: proper structure for Prefix, Tag, ObjectSize conditions
|
|
37611
|
+
* - Total rules: 1-100 per bucket
|
|
37612
|
+
*
|
|
37613
|
+
* @returns boolean - true on success
|
|
37614
|
+
* @throws TRPCError BAD_REQUEST - invalid lifecycle configuration structure
|
|
37615
|
+
* @throws TRPCError NOT_FOUND - bucket does not exist
|
|
37616
|
+
* @throws TRPCError FORBIDDEN - no credentials or access denied
|
|
37617
|
+
* @throws TRPCError TOO_MANY_REQUESTS - rate limit exceeded (10 changes per minute per bucket)
|
|
37618
|
+
*/
|
|
37619
|
+
set: cephProtectedProcedure.input(setLifecycleInputSchema).mutation(async ({ ctx, input }) => {
|
|
37620
|
+
const s3 = ctx.getCephClient();
|
|
37621
|
+
const { bucketName, lifecycleConfiguration, project_id } = input;
|
|
37622
|
+
checkLifecycleSetRateLimit(bucketName, project_id);
|
|
37623
|
+
const transformedRules = toSdkLifecycleRules(lifecycleConfiguration.Rules).map((rule) => {
|
|
37624
|
+
const transformed = {
|
|
37625
|
+
...rule
|
|
37626
|
+
};
|
|
37627
|
+
if (transformed.Prefix !== void 0 && transformed.Filter === void 0) {
|
|
37628
|
+
transformed.Filter = {
|
|
37629
|
+
Prefix: transformed.Prefix
|
|
37630
|
+
};
|
|
37631
|
+
}
|
|
37632
|
+
delete transformed.Prefix;
|
|
37633
|
+
return transformed;
|
|
37634
|
+
});
|
|
37635
|
+
try {
|
|
37636
|
+
await s3.send(new import_client_s37.PutBucketLifecycleConfigurationCommand({
|
|
37637
|
+
Bucket: bucketName,
|
|
37638
|
+
LifecycleConfiguration: {
|
|
37639
|
+
Rules: transformedRules
|
|
37640
|
+
}
|
|
37641
|
+
}));
|
|
37642
|
+
return true;
|
|
37643
|
+
} catch (error) {
|
|
37644
|
+
throw mapS3ErrorToTRPCError(error, {
|
|
37645
|
+
operation: "set lifecycle configuration",
|
|
37646
|
+
bucket: bucketName
|
|
37647
|
+
});
|
|
37648
|
+
}
|
|
37649
|
+
}),
|
|
37650
|
+
/**
|
|
37651
|
+
* Delete (remove) a lifecycle configuration from a bucket.
|
|
37652
|
+
*
|
|
37653
|
+
* Removes all lifecycle rules from the bucket. The bucket reverts to having no lifecycle config.
|
|
37654
|
+
* Not an error if no lifecycle configuration was set (idempotent).
|
|
37655
|
+
*
|
|
37656
|
+
* @returns boolean - true on success
|
|
37657
|
+
* @throws TRPCError NOT_FOUND - bucket does not exist
|
|
37658
|
+
* @throws TRPCError FORBIDDEN - no credentials or access denied
|
|
37659
|
+
*/
|
|
37660
|
+
delete: cephProtectedProcedure.input(deleteLifecycleInputSchema).mutation(async ({ ctx, input }) => {
|
|
37661
|
+
const s3 = ctx.getCephClient();
|
|
37662
|
+
const { bucketName } = input;
|
|
37663
|
+
try {
|
|
37664
|
+
await s3.send(new import_client_s37.DeleteBucketLifecycleCommand({
|
|
37665
|
+
Bucket: bucketName
|
|
37666
|
+
}));
|
|
37667
|
+
return true;
|
|
37668
|
+
} catch (error) {
|
|
37669
|
+
const s3Error = error;
|
|
37670
|
+
if (s3Error.name === "NoSuchLifecycleConfiguration" || s3Error.Code === "NoSuchLifecycleConfiguration") {
|
|
37671
|
+
return true;
|
|
37672
|
+
}
|
|
37673
|
+
throw mapS3ErrorToTRPCError(error, {
|
|
37674
|
+
operation: "delete lifecycle configuration",
|
|
37675
|
+
bucket: bucketName
|
|
37676
|
+
});
|
|
37677
|
+
}
|
|
37678
|
+
})
|
|
37679
|
+
};
|
|
37680
|
+
|
|
37156
37681
|
// src/server/Storage/routers/permissionRouter.ts
|
|
37157
37682
|
var STORAGE_MAPPINGS = {
|
|
37158
37683
|
// Container Operations (works for both Swift containers and Ceph buckets)
|
|
@@ -37192,6 +37717,10 @@ var STORAGE_MAPPINGS = {
|
|
|
37192
37717
|
engine: "storage",
|
|
37193
37718
|
rule: "storage:container_update_access_control"
|
|
37194
37719
|
},
|
|
37720
|
+
"storage:containers:update_versioning": {
|
|
37721
|
+
engine: "storage",
|
|
37722
|
+
rule: "storage:container_versioning_update"
|
|
37723
|
+
},
|
|
37195
37724
|
// Object Operations
|
|
37196
37725
|
"storage:objects:read": {
|
|
37197
37726
|
engine: "storage",
|
|
@@ -37225,6 +37754,10 @@ var STORAGE_MAPPINGS = {
|
|
|
37225
37754
|
engine: "storage",
|
|
37226
37755
|
rule: "storage:object_move"
|
|
37227
37756
|
},
|
|
37757
|
+
"storage:objects:share": {
|
|
37758
|
+
engine: "storage",
|
|
37759
|
+
rule: "storage:object_share"
|
|
37760
|
+
},
|
|
37228
37761
|
// Folder Operations
|
|
37229
37762
|
"storage:folders:create_object": {
|
|
37230
37763
|
engine: "storage",
|
|
@@ -37237,6 +37770,47 @@ var STORAGE_MAPPINGS = {
|
|
|
37237
37770
|
"storage:folders:delete": {
|
|
37238
37771
|
engine: "storage",
|
|
37239
37772
|
rule: "storage:folder_delete"
|
|
37773
|
+
},
|
|
37774
|
+
// Object Version Operations
|
|
37775
|
+
"storage:object_versions:delete": {
|
|
37776
|
+
engine: "storage",
|
|
37777
|
+
rule: "storage:object_version_delete"
|
|
37778
|
+
},
|
|
37779
|
+
"storage:object_versions:restore": {
|
|
37780
|
+
engine: "storage",
|
|
37781
|
+
rule: "storage:object_version_restore"
|
|
37782
|
+
},
|
|
37783
|
+
// Container Policy Operations
|
|
37784
|
+
"storage:container_policies:update": {
|
|
37785
|
+
engine: "storage",
|
|
37786
|
+
rule: "storage:container_policy_update"
|
|
37787
|
+
},
|
|
37788
|
+
"storage:container_policies:delete": {
|
|
37789
|
+
engine: "storage",
|
|
37790
|
+
rule: "storage:container_policy_delete"
|
|
37791
|
+
},
|
|
37792
|
+
// CORS Operations
|
|
37793
|
+
"storage:container_cors_rules:update": {
|
|
37794
|
+
engine: "storage",
|
|
37795
|
+
rule: "storage:container_cors_update"
|
|
37796
|
+
},
|
|
37797
|
+
"storage:container_cors_rules:delete": {
|
|
37798
|
+
engine: "storage",
|
|
37799
|
+
rule: "storage:container_cors_delete"
|
|
37800
|
+
},
|
|
37801
|
+
// Lifecycle Operations
|
|
37802
|
+
"storage:container_lifecycle_rules:update": {
|
|
37803
|
+
engine: "storage",
|
|
37804
|
+
rule: "storage:container_lifecycle_update"
|
|
37805
|
+
},
|
|
37806
|
+
"storage:container_lifecycle_rules:delete": {
|
|
37807
|
+
engine: "storage",
|
|
37808
|
+
rule: "storage:container_lifecycle_delete"
|
|
37809
|
+
},
|
|
37810
|
+
// Credential Operations
|
|
37811
|
+
"storage:credentials:create": {
|
|
37812
|
+
engine: "storage",
|
|
37813
|
+
rule: "storage:credential_create"
|
|
37240
37814
|
}
|
|
37241
37815
|
};
|
|
37242
37816
|
var buildStoragePermissionRouter = /* @__PURE__ */ __name((policyDir) => createPermissionRouter({
|
|
@@ -37273,6 +37847,9 @@ var buildObjectStorageRouters = /* @__PURE__ */ __name((policyDir) => ({
|
|
|
37273
37847
|
}),
|
|
37274
37848
|
cors: auroraRouter({
|
|
37275
37849
|
...corsRouter
|
|
37850
|
+
}),
|
|
37851
|
+
lifecycle: auroraRouter({
|
|
37852
|
+
...lifecycleRouter
|
|
37276
37853
|
})
|
|
37277
37854
|
}),
|
|
37278
37855
|
...buildStoragePermissionRouter(policyDir)
|
|
@@ -37281,7 +37858,7 @@ var buildObjectStorageRouters = /* @__PURE__ */ __name((policyDir) => ({
|
|
|
37281
37858
|
|
|
37282
37859
|
// src/server/Project/routers/projectRouter.ts
|
|
37283
37860
|
var import_zod20 = require("zod");
|
|
37284
|
-
var
|
|
37861
|
+
var import_server19 = require("@trpc/server");
|
|
37285
37862
|
|
|
37286
37863
|
// src/server/Project/types/models.ts
|
|
37287
37864
|
var import_zod19 = require("zod");
|
|
@@ -37318,10 +37895,10 @@ var projectsResponseSchema = import_zod19.z.object({
|
|
|
37318
37895
|
});
|
|
37319
37896
|
|
|
37320
37897
|
// src/server/Project/routers/projectRouter.ts
|
|
37321
|
-
var
|
|
37898
|
+
var import_signal_openstack5 = __toESM(require_esm());
|
|
37322
37899
|
async function callIdentityAPI(identityEndpoint, authToken, path3) {
|
|
37323
37900
|
if (!identityEndpoint) {
|
|
37324
|
-
throw new
|
|
37901
|
+
throw new import_server19.TRPCError({
|
|
37325
37902
|
code: "INTERNAL_SERVER_ERROR",
|
|
37326
37903
|
message: "Identity endpoint not configured"
|
|
37327
37904
|
});
|
|
@@ -37337,7 +37914,7 @@ async function callIdentityAPI(identityEndpoint, authToken, path3) {
|
|
|
37337
37914
|
}
|
|
37338
37915
|
});
|
|
37339
37916
|
if (!response.ok) {
|
|
37340
|
-
throw new
|
|
37917
|
+
throw new import_server19.TRPCError({
|
|
37341
37918
|
code: "INTERNAL_SERVER_ERROR",
|
|
37342
37919
|
message: `Identity API call failed: ${response.status} ${response.statusText}`
|
|
37343
37920
|
});
|
|
@@ -37377,14 +37954,14 @@ var projectRouter = {
|
|
|
37377
37954
|
*/
|
|
37378
37955
|
getAuthProjects: protectedProcedure.query(async ({ ctx }) => {
|
|
37379
37956
|
if (!ctx.openstack) {
|
|
37380
|
-
throw new
|
|
37957
|
+
throw new import_server19.TRPCError({
|
|
37381
37958
|
code: "UNAUTHORIZED",
|
|
37382
37959
|
message: "No authenticated session"
|
|
37383
37960
|
});
|
|
37384
37961
|
}
|
|
37385
37962
|
const token = ctx.openstack.getToken();
|
|
37386
37963
|
if (!token?.authToken) {
|
|
37387
|
-
throw new
|
|
37964
|
+
throw new import_server19.TRPCError({
|
|
37388
37965
|
code: "UNAUTHORIZED",
|
|
37389
37966
|
message: "No auth token available"
|
|
37390
37967
|
});
|
|
@@ -37427,14 +38004,14 @@ var projectRouter = {
|
|
|
37427
38004
|
search: import_zod20.z.string().optional()
|
|
37428
38005
|
}).optional()).query(async ({ ctx, input }) => {
|
|
37429
38006
|
if (!ctx.openstack) {
|
|
37430
|
-
throw new
|
|
38007
|
+
throw new import_server19.TRPCError({
|
|
37431
38008
|
code: "UNAUTHORIZED",
|
|
37432
38009
|
message: "No authenticated session"
|
|
37433
38010
|
});
|
|
37434
38011
|
}
|
|
37435
38012
|
const token = ctx.openstack.getToken();
|
|
37436
38013
|
if (!token?.authToken) {
|
|
37437
|
-
throw new
|
|
38014
|
+
throw new import_server19.TRPCError({
|
|
37438
38015
|
code: "UNAUTHORIZED",
|
|
37439
38016
|
message: "No auth token available"
|
|
37440
38017
|
});
|
|
@@ -37458,21 +38035,21 @@ var projectRouter = {
|
|
|
37458
38035
|
projectId: import_zod20.z.string()
|
|
37459
38036
|
})).query(async ({ ctx, input }) => {
|
|
37460
38037
|
if (!ctx.openstack) {
|
|
37461
|
-
throw new
|
|
38038
|
+
throw new import_server19.TRPCError({
|
|
37462
38039
|
code: "UNAUTHORIZED",
|
|
37463
38040
|
message: "No authenticated session"
|
|
37464
38041
|
});
|
|
37465
38042
|
}
|
|
37466
38043
|
const token = ctx.openstack.getToken();
|
|
37467
38044
|
if (!token?.authToken) {
|
|
37468
|
-
throw new
|
|
38045
|
+
throw new import_server19.TRPCError({
|
|
37469
38046
|
code: "UNAUTHORIZED",
|
|
37470
38047
|
message: "No auth token available"
|
|
37471
38048
|
});
|
|
37472
38049
|
}
|
|
37473
38050
|
let encodedId;
|
|
37474
38051
|
try {
|
|
37475
|
-
encodedId = (0,
|
|
38052
|
+
encodedId = (0, import_signal_openstack5.validateAndEncodeResourceId)(input.projectId, "Project");
|
|
37476
38053
|
} catch {
|
|
37477
38054
|
return null;
|
|
37478
38055
|
}
|
|
@@ -37491,22 +38068,25 @@ var projectRouters = {
|
|
|
37491
38068
|
})
|
|
37492
38069
|
};
|
|
37493
38070
|
|
|
38071
|
+
// src/server/Network/routers/floatingIpRouter.ts
|
|
38072
|
+
var import_server24 = require("@trpc/server");
|
|
38073
|
+
|
|
37494
38074
|
// src/server/helpers/errorHandling.ts
|
|
37495
|
-
var
|
|
37496
|
-
var
|
|
38075
|
+
var import_server20 = require("@trpc/server");
|
|
38076
|
+
var import_signal_openstack6 = __toESM(require_esm());
|
|
37497
38077
|
function wrapError3(error, operation) {
|
|
37498
|
-
if (error instanceof
|
|
38078
|
+
if (error instanceof import_server20.TRPCError) {
|
|
37499
38079
|
return error;
|
|
37500
38080
|
}
|
|
37501
|
-
if (error instanceof
|
|
37502
|
-
return new
|
|
38081
|
+
if (error instanceof import_signal_openstack6.SignalOpenstackError) {
|
|
38082
|
+
return new import_server20.TRPCError({
|
|
37503
38083
|
code: "BAD_REQUEST",
|
|
37504
38084
|
message: error.message,
|
|
37505
38085
|
cause: error
|
|
37506
38086
|
});
|
|
37507
38087
|
}
|
|
37508
38088
|
const baseErrorMessage = `Error during ${operation}`;
|
|
37509
|
-
return new
|
|
38089
|
+
return new import_server20.TRPCError({
|
|
37510
38090
|
code: "INTERNAL_SERVER_ERROR",
|
|
37511
38091
|
message: typeof error !== "string" && error.message ? `${baseErrorMessage}: ${error.message}` : baseErrorMessage,
|
|
37512
38092
|
cause: error
|
|
@@ -37546,11 +38126,11 @@ function appendQueryParamsFromObject(source, options) {
|
|
|
37546
38126
|
__name(appendQueryParamsFromObject, "appendQueryParamsFromObject");
|
|
37547
38127
|
|
|
37548
38128
|
// src/server/helpers/validateOpenstackService.ts
|
|
37549
|
-
var
|
|
38129
|
+
var import_server21 = require("@trpc/server");
|
|
37550
38130
|
var capitalize = /* @__PURE__ */ __name((str) => str.charAt(0).toUpperCase() + str.slice(1), "capitalize");
|
|
37551
38131
|
function validateOpenstackService(service, serviceName) {
|
|
37552
38132
|
if (!service) {
|
|
37553
|
-
throw new
|
|
38133
|
+
throw new import_server21.TRPCError({
|
|
37554
38134
|
code: "INTERNAL_SERVER_ERROR",
|
|
37555
38135
|
message: `${capitalize(serviceName)} service is not available`
|
|
37556
38136
|
});
|
|
@@ -37559,7 +38139,7 @@ function validateOpenstackService(service, serviceName) {
|
|
|
37559
38139
|
__name(validateOpenstackService, "validateOpenstackService");
|
|
37560
38140
|
|
|
37561
38141
|
// src/server/Network/routers/floatingIpRouter.ts
|
|
37562
|
-
var
|
|
38142
|
+
var import_signal_openstack7 = __toESM(require_esm());
|
|
37563
38143
|
|
|
37564
38144
|
// src/server/Network/types/floatingIp.ts
|
|
37565
38145
|
var import_zod22 = require("zod");
|
|
@@ -37672,8 +38252,7 @@ var FloatingIpIdInputSchema = import_zod22.z.object({
|
|
|
37672
38252
|
floatingip_id: import_zod22.z.string()
|
|
37673
38253
|
});
|
|
37674
38254
|
var FloatingIpCreateRequestSchema = import_zod22.z.object({
|
|
37675
|
-
|
|
37676
|
-
project_id: import_zod22.z.string(),
|
|
38255
|
+
project_id: import_zod22.z.string().trim().min(1, "project_id must be a non-empty string"),
|
|
37677
38256
|
floating_network_id: import_zod22.z.string(),
|
|
37678
38257
|
fixed_ip_address: import_zod22.z.string().optional(),
|
|
37679
38258
|
floating_ip_address: import_zod22.z.string().optional(),
|
|
@@ -37807,10 +38386,10 @@ var AvailablePortsResponseSchema = import_zod22.z.object({
|
|
|
37807
38386
|
});
|
|
37808
38387
|
|
|
37809
38388
|
// src/server/Network/helpers/errorHandling.ts
|
|
37810
|
-
var
|
|
38389
|
+
var import_server23 = require("@trpc/server");
|
|
37811
38390
|
|
|
37812
38391
|
// src/server/Network/helpers/index.ts
|
|
37813
|
-
var
|
|
38392
|
+
var import_server22 = require("@trpc/server");
|
|
37814
38393
|
var HTTP_STATUS_ERROR_MAP = {
|
|
37815
38394
|
400: "BAD_REQUEST",
|
|
37816
38395
|
401: "UNAUTHORIZED",
|
|
@@ -37830,7 +38409,7 @@ var parseOrThrow = /* @__PURE__ */ __name((schema, data, context) => {
|
|
|
37830
38409
|
const parsed = schema.safeParse(data);
|
|
37831
38410
|
if (!parsed.success) {
|
|
37832
38411
|
console.error(`Zod Parsing Error in ${context}:`, parsed.error.issues);
|
|
37833
|
-
throw new
|
|
38412
|
+
throw new import_server22.TRPCError({
|
|
37834
38413
|
code: "PARSE_ERROR",
|
|
37835
38414
|
message: `Failed to parse response in ${context}`
|
|
37836
38415
|
});
|
|
@@ -37840,27 +38419,27 @@ var parseOrThrow = /* @__PURE__ */ __name((schema, data, context) => {
|
|
|
37840
38419
|
|
|
37841
38420
|
// src/server/Network/helpers/errorHandling.ts
|
|
37842
38421
|
var DEFAULT_HANDLERS = {
|
|
37843
|
-
400: (response, resourceLabel) => new
|
|
38422
|
+
400: (response, resourceLabel) => new import_server23.TRPCError({
|
|
37844
38423
|
code: HTTP_STATUS_ERROR_MAP[400],
|
|
37845
38424
|
message: `Invalid request data for ${resourceLabel}: ${response.statusText || "Unknown error"}`
|
|
37846
38425
|
}),
|
|
37847
|
-
401: (response, resourceLabel) => new
|
|
38426
|
+
401: (response, resourceLabel) => new import_server23.TRPCError({
|
|
37848
38427
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
37849
38428
|
message: `Unauthorized access to ${resourceLabel}: ${response.statusText || "Unknown error"}`
|
|
37850
38429
|
}),
|
|
37851
|
-
403: (response, resourceLabel) => new
|
|
38430
|
+
403: (response, resourceLabel) => new import_server23.TRPCError({
|
|
37852
38431
|
code: HTTP_STATUS_ERROR_MAP[403],
|
|
37853
38432
|
message: `Access forbidden to ${resourceLabel}: ${response.statusText || "Unknown error"}`
|
|
37854
38433
|
}),
|
|
37855
|
-
404: (response, resourceLabel) => new
|
|
38434
|
+
404: (response, resourceLabel) => new import_server23.TRPCError({
|
|
37856
38435
|
code: HTTP_STATUS_ERROR_MAP[404],
|
|
37857
38436
|
message: `${resourceLabel} not found: ${response.statusText || "Unknown error"}`
|
|
37858
38437
|
}),
|
|
37859
|
-
409: (response, resourceLabel) => new
|
|
38438
|
+
409: (response, resourceLabel) => new import_server23.TRPCError({
|
|
37860
38439
|
code: HTTP_STATUS_ERROR_MAP[409],
|
|
37861
38440
|
message: `Conflict - ${resourceLabel} is in use: ${response.statusText || "Unknown error"}`
|
|
37862
38441
|
}),
|
|
37863
|
-
412: (response, resourceLabel) => new
|
|
38442
|
+
412: (response, resourceLabel) => new import_server23.TRPCError({
|
|
37864
38443
|
code: HTTP_STATUS_ERROR_MAP[412],
|
|
37865
38444
|
message: `Precondition failed - revision number mismatch in ${resourceLabel}: ${response.statusText || "Unknown error"}`
|
|
37866
38445
|
})
|
|
@@ -37875,7 +38454,7 @@ var ErrorHandler = /* @__PURE__ */ __name((resourceName, customHandlers) => {
|
|
|
37875
38454
|
if (response.status && handlers[response.status]) {
|
|
37876
38455
|
return handlers[response.status](response, resourceLabel);
|
|
37877
38456
|
}
|
|
37878
|
-
return new
|
|
38457
|
+
return new import_server23.TRPCError({
|
|
37879
38458
|
code: DEFAULT_ERROR_NAME,
|
|
37880
38459
|
message: `Failed to process ${resourceLabel}: ${response.statusText || "Unknown error"}`
|
|
37881
38460
|
});
|
|
@@ -37921,10 +38500,18 @@ var floatingIpRouter = {
|
|
|
37921
38500
|
create: projectScopedProcedure.input(FloatingIpCreateRequestSchema).mutation(async ({ input, ctx }) => {
|
|
37922
38501
|
return withErrorHandling3(async () => {
|
|
37923
38502
|
const network = getNetworkService(ctx);
|
|
38503
|
+
const token = ctx.openstack?.getToken();
|
|
38504
|
+
const projectId = token?.tokenData.project?.id;
|
|
38505
|
+
if (!projectId) {
|
|
38506
|
+
throw new import_server24.TRPCError({
|
|
38507
|
+
code: "UNAUTHORIZED",
|
|
38508
|
+
message: "No project scope in session"
|
|
38509
|
+
});
|
|
38510
|
+
}
|
|
37924
38511
|
const requestBody = {
|
|
37925
38512
|
floatingip: {
|
|
37926
|
-
tenant_id:
|
|
37927
|
-
project_id:
|
|
38513
|
+
tenant_id: projectId,
|
|
38514
|
+
project_id: projectId,
|
|
37928
38515
|
floating_network_id: input.floating_network_id,
|
|
37929
38516
|
...input.fixed_ip_address !== void 0 && {
|
|
37930
38517
|
fixed_ip_address: input.fixed_ip_address
|
|
@@ -37967,7 +38554,7 @@ var floatingIpRouter = {
|
|
|
37967
38554
|
return withErrorHandling3(async () => {
|
|
37968
38555
|
const { floatingip_id } = input;
|
|
37969
38556
|
const network = getNetworkService(ctx);
|
|
37970
|
-
const encodedId = (0,
|
|
38557
|
+
const encodedId = (0, import_signal_openstack7.validateAndEncodeResourceId)(floatingip_id, "Floating IP");
|
|
37971
38558
|
const response = await network.get(`${FLOATING_IPS_BASE_URL}/${encodedId}`);
|
|
37972
38559
|
if (!response.ok) {
|
|
37973
38560
|
throw FloatingIpErrorHandlers.get(response, floatingip_id);
|
|
@@ -37994,7 +38581,7 @@ var floatingIpRouter = {
|
|
|
37994
38581
|
}
|
|
37995
38582
|
}
|
|
37996
38583
|
};
|
|
37997
|
-
const encodedId = (0,
|
|
38584
|
+
const encodedId = (0, import_signal_openstack7.validateAndEncodeResourceId)(floatingip_id, "Floating IP");
|
|
37998
38585
|
const response = await network.put(`${FLOATING_IPS_BASE_URL}/${encodedId}`, requestBody);
|
|
37999
38586
|
if (!response.ok) {
|
|
38000
38587
|
throw FloatingIpErrorHandlers.update(response, floatingip_id);
|
|
@@ -38007,7 +38594,7 @@ var floatingIpRouter = {
|
|
|
38007
38594
|
return withErrorHandling3(async () => {
|
|
38008
38595
|
const { floatingip_id } = input;
|
|
38009
38596
|
const network = getNetworkService(ctx);
|
|
38010
|
-
const encodedId = (0,
|
|
38597
|
+
const encodedId = (0, import_signal_openstack7.validateAndEncodeResourceId)(floatingip_id, "Floating IP");
|
|
38011
38598
|
const response = await network.del(`${FLOATING_IPS_BASE_URL}/${encodedId}`);
|
|
38012
38599
|
if (!response.ok) {
|
|
38013
38600
|
throw FloatingIpErrorHandlers.delete(response, floatingip_id);
|
|
@@ -38163,7 +38750,7 @@ var createSecurityGroupRuleInputSchema = projectScopedInputSchema.extend({
|
|
|
38163
38750
|
});
|
|
38164
38751
|
|
|
38165
38752
|
// src/server/Network/helpers/securityGroupHelpers.ts
|
|
38166
|
-
var
|
|
38753
|
+
var import_server25 = require("@trpc/server");
|
|
38167
38754
|
var SecurityGroupErrorHandlers = {
|
|
38168
38755
|
/**
|
|
38169
38756
|
* Handles errors specific to security group list operations
|
|
@@ -38173,17 +38760,17 @@ var SecurityGroupErrorHandlers = {
|
|
|
38173
38760
|
list: /* @__PURE__ */ __name((response) => {
|
|
38174
38761
|
switch (response.status) {
|
|
38175
38762
|
case 401:
|
|
38176
|
-
return new
|
|
38763
|
+
return new import_server25.TRPCError({
|
|
38177
38764
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38178
38765
|
message: "Unauthorized access"
|
|
38179
38766
|
});
|
|
38180
38767
|
case 403:
|
|
38181
|
-
return new
|
|
38768
|
+
return new import_server25.TRPCError({
|
|
38182
38769
|
code: HTTP_STATUS_ERROR_MAP[403],
|
|
38183
38770
|
message: `Access forbidden: ${response.statusText || "Unknown error"}`
|
|
38184
38771
|
});
|
|
38185
38772
|
default:
|
|
38186
|
-
return new
|
|
38773
|
+
return new import_server25.TRPCError({
|
|
38187
38774
|
code: DEFAULT_ERROR_NAME,
|
|
38188
38775
|
message: `Failed to list security groups: ${response.statusText || "Unknown error"}`
|
|
38189
38776
|
});
|
|
@@ -38198,22 +38785,22 @@ var SecurityGroupErrorHandlers = {
|
|
|
38198
38785
|
getById: /* @__PURE__ */ __name((response, securityGroupId) => {
|
|
38199
38786
|
switch (response.status) {
|
|
38200
38787
|
case 401:
|
|
38201
|
-
return new
|
|
38788
|
+
return new import_server25.TRPCError({
|
|
38202
38789
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38203
38790
|
message: "Unauthorized access"
|
|
38204
38791
|
});
|
|
38205
38792
|
case 403:
|
|
38206
|
-
return new
|
|
38793
|
+
return new import_server25.TRPCError({
|
|
38207
38794
|
code: HTTP_STATUS_ERROR_MAP[403],
|
|
38208
38795
|
message: `Access forbidden: ${response.statusText || "Unknown error"}`
|
|
38209
38796
|
});
|
|
38210
38797
|
case 404:
|
|
38211
|
-
return new
|
|
38798
|
+
return new import_server25.TRPCError({
|
|
38212
38799
|
code: HTTP_STATUS_ERROR_MAP[404],
|
|
38213
38800
|
message: `Security group not found: ${securityGroupId}`
|
|
38214
38801
|
});
|
|
38215
38802
|
default:
|
|
38216
|
-
return new
|
|
38803
|
+
return new import_server25.TRPCError({
|
|
38217
38804
|
code: DEFAULT_ERROR_NAME,
|
|
38218
38805
|
message: `Failed to fetch security group: ${response.statusText || "Unknown error"}`
|
|
38219
38806
|
});
|
|
@@ -38227,32 +38814,32 @@ var SecurityGroupErrorHandlers = {
|
|
|
38227
38814
|
create: /* @__PURE__ */ __name((response) => {
|
|
38228
38815
|
switch (response.status) {
|
|
38229
38816
|
case 401:
|
|
38230
|
-
return new
|
|
38817
|
+
return new import_server25.TRPCError({
|
|
38231
38818
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38232
38819
|
message: "Unauthorized access"
|
|
38233
38820
|
});
|
|
38234
38821
|
case 403:
|
|
38235
|
-
return new
|
|
38822
|
+
return new import_server25.TRPCError({
|
|
38236
38823
|
code: HTTP_STATUS_ERROR_MAP[403],
|
|
38237
38824
|
message: `Access forbidden: ${response.statusText || "Unknown error"}`
|
|
38238
38825
|
});
|
|
38239
38826
|
case 409:
|
|
38240
|
-
return new
|
|
38827
|
+
return new import_server25.TRPCError({
|
|
38241
38828
|
code: HTTP_STATUS_ERROR_MAP[409],
|
|
38242
38829
|
message: `Conflict: ${response.statusText || "Security group already exists"}`
|
|
38243
38830
|
});
|
|
38244
38831
|
case 413:
|
|
38245
|
-
return new
|
|
38832
|
+
return new import_server25.TRPCError({
|
|
38246
38833
|
code: "BAD_REQUEST",
|
|
38247
38834
|
message: `Quota exceeded for security groups. Please delete an existing security group or contact your administrator to increase your quota.`
|
|
38248
38835
|
});
|
|
38249
38836
|
case 400:
|
|
38250
|
-
return new
|
|
38837
|
+
return new import_server25.TRPCError({
|
|
38251
38838
|
code: "BAD_REQUEST",
|
|
38252
38839
|
message: `Invalid request: ${response.statusText || "Unknown error"}`
|
|
38253
38840
|
});
|
|
38254
38841
|
default:
|
|
38255
|
-
return new
|
|
38842
|
+
return new import_server25.TRPCError({
|
|
38256
38843
|
code: "INTERNAL_SERVER_ERROR",
|
|
38257
38844
|
message: `Failed to create security group: ${response.statusText || "Unknown error"}`
|
|
38258
38845
|
});
|
|
@@ -38267,22 +38854,22 @@ var SecurityGroupErrorHandlers = {
|
|
|
38267
38854
|
delete: /* @__PURE__ */ __name((response, securityGroupId) => {
|
|
38268
38855
|
switch (response.status) {
|
|
38269
38856
|
case 401:
|
|
38270
|
-
return new
|
|
38857
|
+
return new import_server25.TRPCError({
|
|
38271
38858
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38272
38859
|
message: "Unauthorized access"
|
|
38273
38860
|
});
|
|
38274
38861
|
case 404:
|
|
38275
|
-
return new
|
|
38862
|
+
return new import_server25.TRPCError({
|
|
38276
38863
|
code: HTTP_STATUS_ERROR_MAP[404],
|
|
38277
38864
|
message: `Security group not found: ${securityGroupId}`
|
|
38278
38865
|
});
|
|
38279
38866
|
case 409:
|
|
38280
|
-
return new
|
|
38867
|
+
return new import_server25.TRPCError({
|
|
38281
38868
|
code: HTTP_STATUS_ERROR_MAP[409],
|
|
38282
38869
|
message: "Cannot delete security group because it is in use by one or more ports. Please remove all associations before deleting."
|
|
38283
38870
|
});
|
|
38284
38871
|
default:
|
|
38285
|
-
return new
|
|
38872
|
+
return new import_server25.TRPCError({
|
|
38286
38873
|
code: DEFAULT_ERROR_NAME,
|
|
38287
38874
|
message: `Failed to delete security group: ${response.statusText || "Unknown error"}`
|
|
38288
38875
|
});
|
|
@@ -38297,39 +38884,39 @@ var SecurityGroupErrorHandlers = {
|
|
|
38297
38884
|
update: /* @__PURE__ */ __name((response, securityGroupId) => {
|
|
38298
38885
|
const errorMessage = response.statusText || "";
|
|
38299
38886
|
if (errorMessage.toLowerCase().includes("stateful") && errorMessage.toLowerCase().includes("in use")) {
|
|
38300
|
-
return new
|
|
38887
|
+
return new import_server25.TRPCError({
|
|
38301
38888
|
code: "CONFLICT",
|
|
38302
38889
|
message: "Cannot update the 'stateful' attribute because this security group is in use by one or more ports."
|
|
38303
38890
|
});
|
|
38304
38891
|
}
|
|
38305
38892
|
switch (response.status) {
|
|
38306
38893
|
case 401:
|
|
38307
|
-
return new
|
|
38894
|
+
return new import_server25.TRPCError({
|
|
38308
38895
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38309
38896
|
message: "Unauthorized access"
|
|
38310
38897
|
});
|
|
38311
38898
|
case 403:
|
|
38312
|
-
return new
|
|
38899
|
+
return new import_server25.TRPCError({
|
|
38313
38900
|
code: HTTP_STATUS_ERROR_MAP[403],
|
|
38314
38901
|
message: `Access forbidden: ${errorMessage || "Unknown error"}`
|
|
38315
38902
|
});
|
|
38316
38903
|
case 404:
|
|
38317
|
-
return new
|
|
38904
|
+
return new import_server25.TRPCError({
|
|
38318
38905
|
code: HTTP_STATUS_ERROR_MAP[404],
|
|
38319
38906
|
message: `Security group not found: ${securityGroupId}`
|
|
38320
38907
|
});
|
|
38321
38908
|
case 409:
|
|
38322
|
-
return new
|
|
38909
|
+
return new import_server25.TRPCError({
|
|
38323
38910
|
code: HTTP_STATUS_ERROR_MAP[409],
|
|
38324
38911
|
message: `Conflict: ${errorMessage || "Security group conflict"}`
|
|
38325
38912
|
});
|
|
38326
38913
|
case 400:
|
|
38327
|
-
return new
|
|
38914
|
+
return new import_server25.TRPCError({
|
|
38328
38915
|
code: HTTP_STATUS_ERROR_MAP[400],
|
|
38329
38916
|
message: `Invalid request: ${errorMessage || "Unknown error"}`
|
|
38330
38917
|
});
|
|
38331
38918
|
default:
|
|
38332
|
-
return new
|
|
38919
|
+
return new import_server25.TRPCError({
|
|
38333
38920
|
code: DEFAULT_ERROR_NAME,
|
|
38334
38921
|
message: `Failed to update security group: ${errorMessage || "Unknown error"}`
|
|
38335
38922
|
});
|
|
@@ -38347,48 +38934,48 @@ var SecurityGroupRuleErrorHandlers = {
|
|
|
38347
38934
|
switch (response.status) {
|
|
38348
38935
|
case 400:
|
|
38349
38936
|
if (statusText.toLowerCase().includes("cidr")) {
|
|
38350
|
-
return new
|
|
38937
|
+
return new import_server25.TRPCError({
|
|
38351
38938
|
code: "BAD_REQUEST",
|
|
38352
38939
|
message: "Invalid CIDR format. Please provide a valid IP address block (e.g., 0.0.0.0/0)"
|
|
38353
38940
|
});
|
|
38354
38941
|
}
|
|
38355
38942
|
if (statusText.toLowerCase().includes("port")) {
|
|
38356
|
-
return new
|
|
38943
|
+
return new import_server25.TRPCError({
|
|
38357
38944
|
code: "BAD_REQUEST",
|
|
38358
38945
|
message: "Invalid port range. Ports must be between 1 and 65535, and min must be <= max"
|
|
38359
38946
|
});
|
|
38360
38947
|
}
|
|
38361
|
-
return new
|
|
38948
|
+
return new import_server25.TRPCError({
|
|
38362
38949
|
code: "BAD_REQUEST",
|
|
38363
38950
|
message: `Invalid request: ${statusText}`
|
|
38364
38951
|
});
|
|
38365
38952
|
case 401:
|
|
38366
|
-
return new
|
|
38953
|
+
return new import_server25.TRPCError({
|
|
38367
38954
|
code: "UNAUTHORIZED",
|
|
38368
38955
|
message: "Unauthorized access"
|
|
38369
38956
|
});
|
|
38370
38957
|
case 403:
|
|
38371
|
-
return new
|
|
38958
|
+
return new import_server25.TRPCError({
|
|
38372
38959
|
code: "FORBIDDEN",
|
|
38373
38960
|
message: `Access forbidden: ${statusText}`
|
|
38374
38961
|
});
|
|
38375
38962
|
case 404:
|
|
38376
|
-
return new
|
|
38963
|
+
return new import_server25.TRPCError({
|
|
38377
38964
|
code: "NOT_FOUND",
|
|
38378
38965
|
message: "Security group not found"
|
|
38379
38966
|
});
|
|
38380
38967
|
case 409:
|
|
38381
|
-
return new
|
|
38968
|
+
return new import_server25.TRPCError({
|
|
38382
38969
|
code: "CONFLICT",
|
|
38383
38970
|
message: "A rule with these parameters already exists in this security group"
|
|
38384
38971
|
});
|
|
38385
38972
|
case 413:
|
|
38386
|
-
return new
|
|
38973
|
+
return new import_server25.TRPCError({
|
|
38387
38974
|
code: "BAD_REQUEST",
|
|
38388
38975
|
message: "Quota exceeded for security group rules. Please delete existing rules or contact your administrator."
|
|
38389
38976
|
});
|
|
38390
38977
|
default:
|
|
38391
|
-
return new
|
|
38978
|
+
return new import_server25.TRPCError({
|
|
38392
38979
|
code: "INTERNAL_SERVER_ERROR",
|
|
38393
38980
|
message: `Failed to create security group rule: ${statusText}`
|
|
38394
38981
|
});
|
|
@@ -38407,22 +38994,22 @@ var SecurityGroupRuleErrorHandlers = {
|
|
|
38407
38994
|
delete: /* @__PURE__ */ __name((response, ruleId) => {
|
|
38408
38995
|
switch (response.status) {
|
|
38409
38996
|
case 401:
|
|
38410
|
-
return new
|
|
38997
|
+
return new import_server25.TRPCError({
|
|
38411
38998
|
code: "UNAUTHORIZED",
|
|
38412
38999
|
message: "Unauthorized access"
|
|
38413
39000
|
});
|
|
38414
39001
|
case 404:
|
|
38415
|
-
return new
|
|
39002
|
+
return new import_server25.TRPCError({
|
|
38416
39003
|
code: "NOT_FOUND",
|
|
38417
39004
|
message: `Security group rule not found: ${ruleId}`
|
|
38418
39005
|
});
|
|
38419
39006
|
case 412:
|
|
38420
|
-
return new
|
|
39007
|
+
return new import_server25.TRPCError({
|
|
38421
39008
|
code: "PRECONDITION_FAILED",
|
|
38422
39009
|
message: `Cannot delete security group rule: precondition failed`
|
|
38423
39010
|
});
|
|
38424
39011
|
default:
|
|
38425
|
-
return new
|
|
39012
|
+
return new import_server25.TRPCError({
|
|
38426
39013
|
code: "INTERNAL_SERVER_ERROR",
|
|
38427
39014
|
message: `Failed to delete security group rule: ${response.statusText || "Unknown error"}`
|
|
38428
39015
|
});
|
|
@@ -38433,7 +39020,7 @@ var parseOpenStackResponse = /* @__PURE__ */ __name((data, schema, operation, er
|
|
|
38433
39020
|
const parsed = schema.safeParse(data);
|
|
38434
39021
|
if (!parsed.success) {
|
|
38435
39022
|
console.error(`Zod Parsing Error in ${operation}:`, parsed.error.format());
|
|
38436
|
-
throw new
|
|
39023
|
+
throw new import_server25.TRPCError({
|
|
38437
39024
|
code: "INTERNAL_SERVER_ERROR",
|
|
38438
39025
|
message: errorMessage
|
|
38439
39026
|
});
|
|
@@ -38488,7 +39075,7 @@ var sortSecurityGroups = /* @__PURE__ */ __name((items, sortKey, sortDir = "asc"
|
|
|
38488
39075
|
}, "sortSecurityGroups");
|
|
38489
39076
|
|
|
38490
39077
|
// src/server/Network/routers/securityGroupRouter.ts
|
|
38491
|
-
var
|
|
39078
|
+
var import_signal_openstack8 = __toESM(require_esm());
|
|
38492
39079
|
var SECURITY_GROUPS_BASE_URL = "v2.0/security-groups";
|
|
38493
39080
|
var LIST_SECURITY_GROUPS_QUERY_KEY_MAP = {
|
|
38494
39081
|
tags_any: "tags-any",
|
|
@@ -38555,7 +39142,7 @@ var securityGroupRouter = {
|
|
|
38555
39142
|
return withErrorHandling3(async () => {
|
|
38556
39143
|
const { securityGroupId } = input;
|
|
38557
39144
|
const network = getNetworkService(ctx);
|
|
38558
|
-
const encodedId = (0,
|
|
39145
|
+
const encodedId = (0, import_signal_openstack8.validateAndEncodeResourceId)(securityGroupId, "Security group");
|
|
38559
39146
|
const response = await network.get(`${SECURITY_GROUPS_BASE_URL}/${encodedId}`);
|
|
38560
39147
|
if (!response.ok) {
|
|
38561
39148
|
throw SecurityGroupErrorHandlers.getById(response, securityGroupId);
|
|
@@ -38591,7 +39178,7 @@ var securityGroupRouter = {
|
|
|
38591
39178
|
return withErrorHandling3(async () => {
|
|
38592
39179
|
const { securityGroupId } = input;
|
|
38593
39180
|
const network = getNetworkService(ctx);
|
|
38594
|
-
const encodedId = (0,
|
|
39181
|
+
const encodedId = (0, import_signal_openstack8.validateAndEncodeResourceId)(securityGroupId, "Security group");
|
|
38595
39182
|
const response = await network.del(`${SECURITY_GROUPS_BASE_URL}/${encodedId}`);
|
|
38596
39183
|
if (!response?.ok) {
|
|
38597
39184
|
throw SecurityGroupErrorHandlers.delete(response, securityGroupId);
|
|
@@ -38615,7 +39202,7 @@ var securityGroupRouter = {
|
|
|
38615
39202
|
}
|
|
38616
39203
|
}
|
|
38617
39204
|
};
|
|
38618
|
-
const encodedId = (0,
|
|
39205
|
+
const encodedId = (0, import_signal_openstack8.validateAndEncodeResourceId)(securityGroupId, "Security group");
|
|
38619
39206
|
const response = await network.put(`${SECURITY_GROUPS_BASE_URL}/${encodedId}`, requestBody);
|
|
38620
39207
|
if (!response.ok) {
|
|
38621
39208
|
throw SecurityGroupErrorHandlers.update(response, securityGroupId);
|
|
@@ -38720,7 +39307,7 @@ var deleteRBACPolicyInputSchema = projectScopedInputSchema.extend({
|
|
|
38720
39307
|
});
|
|
38721
39308
|
|
|
38722
39309
|
// src/server/Network/helpers/rbacPolicyHelpers.ts
|
|
38723
|
-
var
|
|
39310
|
+
var import_server26 = require("@trpc/server");
|
|
38724
39311
|
var RBACPolicyErrorHandlers = {
|
|
38725
39312
|
/**
|
|
38726
39313
|
* Handles errors specific to RBAC policy list operations
|
|
@@ -38730,17 +39317,17 @@ var RBACPolicyErrorHandlers = {
|
|
|
38730
39317
|
list: /* @__PURE__ */ __name((response) => {
|
|
38731
39318
|
switch (response.status) {
|
|
38732
39319
|
case 401:
|
|
38733
|
-
return new
|
|
39320
|
+
return new import_server26.TRPCError({
|
|
38734
39321
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38735
39322
|
message: "Unauthorized access"
|
|
38736
39323
|
});
|
|
38737
39324
|
case 403:
|
|
38738
|
-
return new
|
|
39325
|
+
return new import_server26.TRPCError({
|
|
38739
39326
|
code: HTTP_STATUS_ERROR_MAP[403],
|
|
38740
39327
|
message: `Access forbidden: ${response.statusText || "Unknown error"}`
|
|
38741
39328
|
});
|
|
38742
39329
|
default:
|
|
38743
|
-
return new
|
|
39330
|
+
return new import_server26.TRPCError({
|
|
38744
39331
|
code: DEFAULT_ERROR_NAME,
|
|
38745
39332
|
message: `Failed to list RBAC policies: ${response.statusText || "Unknown error"}`
|
|
38746
39333
|
});
|
|
@@ -38754,32 +39341,32 @@ var RBACPolicyErrorHandlers = {
|
|
|
38754
39341
|
create: /* @__PURE__ */ __name((response) => {
|
|
38755
39342
|
switch (response.status) {
|
|
38756
39343
|
case 400:
|
|
38757
|
-
return new
|
|
39344
|
+
return new import_server26.TRPCError({
|
|
38758
39345
|
code: HTTP_STATUS_ERROR_MAP[400],
|
|
38759
39346
|
message: `Invalid request: ${response.statusText || "Unknown error"}`
|
|
38760
39347
|
});
|
|
38761
39348
|
case 401:
|
|
38762
|
-
return new
|
|
39349
|
+
return new import_server26.TRPCError({
|
|
38763
39350
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38764
39351
|
message: "Unauthorized access"
|
|
38765
39352
|
});
|
|
38766
39353
|
case 403:
|
|
38767
|
-
return new
|
|
39354
|
+
return new import_server26.TRPCError({
|
|
38768
39355
|
code: HTTP_STATUS_ERROR_MAP[403],
|
|
38769
39356
|
message: "You don't have permission to share this security group"
|
|
38770
39357
|
});
|
|
38771
39358
|
case 404:
|
|
38772
|
-
return new
|
|
39359
|
+
return new import_server26.TRPCError({
|
|
38773
39360
|
code: HTTP_STATUS_ERROR_MAP[404],
|
|
38774
39361
|
message: "Security group not found or target project does not exist"
|
|
38775
39362
|
});
|
|
38776
39363
|
case 409:
|
|
38777
|
-
return new
|
|
39364
|
+
return new import_server26.TRPCError({
|
|
38778
39365
|
code: HTTP_STATUS_ERROR_MAP[409],
|
|
38779
39366
|
message: "This security group is already shared with the specified project"
|
|
38780
39367
|
});
|
|
38781
39368
|
default:
|
|
38782
|
-
return new
|
|
39369
|
+
return new import_server26.TRPCError({
|
|
38783
39370
|
code: "INTERNAL_SERVER_ERROR",
|
|
38784
39371
|
message: `Failed to create RBAC policy: ${response.statusText || "Unknown error"}`
|
|
38785
39372
|
});
|
|
@@ -38794,27 +39381,27 @@ var RBACPolicyErrorHandlers = {
|
|
|
38794
39381
|
update: /* @__PURE__ */ __name((response, policyId) => {
|
|
38795
39382
|
switch (response.status) {
|
|
38796
39383
|
case 400:
|
|
38797
|
-
return new
|
|
39384
|
+
return new import_server26.TRPCError({
|
|
38798
39385
|
code: HTTP_STATUS_ERROR_MAP[400],
|
|
38799
39386
|
message: `Invalid request: ${response.statusText || "Unknown error"}`
|
|
38800
39387
|
});
|
|
38801
39388
|
case 401:
|
|
38802
|
-
return new
|
|
39389
|
+
return new import_server26.TRPCError({
|
|
38803
39390
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38804
39391
|
message: "Unauthorized access"
|
|
38805
39392
|
});
|
|
38806
39393
|
case 403:
|
|
38807
|
-
return new
|
|
39394
|
+
return new import_server26.TRPCError({
|
|
38808
39395
|
code: HTTP_STATUS_ERROR_MAP[403],
|
|
38809
39396
|
message: `Access forbidden: ${response.statusText || "Unknown error"}`
|
|
38810
39397
|
});
|
|
38811
39398
|
case 404:
|
|
38812
|
-
return new
|
|
39399
|
+
return new import_server26.TRPCError({
|
|
38813
39400
|
code: HTTP_STATUS_ERROR_MAP[404],
|
|
38814
39401
|
message: `RBAC policy not found: ${policyId}`
|
|
38815
39402
|
});
|
|
38816
39403
|
default:
|
|
38817
|
-
return new
|
|
39404
|
+
return new import_server26.TRPCError({
|
|
38818
39405
|
code: "INTERNAL_SERVER_ERROR",
|
|
38819
39406
|
message: `Failed to update RBAC policy: ${response.statusText || "Unknown error"}`
|
|
38820
39407
|
});
|
|
@@ -38829,22 +39416,22 @@ var RBACPolicyErrorHandlers = {
|
|
|
38829
39416
|
delete: /* @__PURE__ */ __name((response, policyId) => {
|
|
38830
39417
|
switch (response.status) {
|
|
38831
39418
|
case 401:
|
|
38832
|
-
return new
|
|
39419
|
+
return new import_server26.TRPCError({
|
|
38833
39420
|
code: HTTP_STATUS_ERROR_MAP[401],
|
|
38834
39421
|
message: "Unauthorized access"
|
|
38835
39422
|
});
|
|
38836
39423
|
case 404:
|
|
38837
|
-
return new
|
|
39424
|
+
return new import_server26.TRPCError({
|
|
38838
39425
|
code: HTTP_STATUS_ERROR_MAP[404],
|
|
38839
39426
|
message: `RBAC policy not found: ${policyId}`
|
|
38840
39427
|
});
|
|
38841
39428
|
case 409:
|
|
38842
|
-
return new
|
|
39429
|
+
return new import_server26.TRPCError({
|
|
38843
39430
|
code: HTTP_STATUS_ERROR_MAP[409],
|
|
38844
39431
|
message: "Cannot delete RBAC policy because it is in use"
|
|
38845
39432
|
});
|
|
38846
39433
|
default:
|
|
38847
|
-
return new
|
|
39434
|
+
return new import_server26.TRPCError({
|
|
38848
39435
|
code: DEFAULT_ERROR_NAME,
|
|
38849
39436
|
message: `Failed to delete RBAC policy: ${response.statusText || "Unknown error"}`
|
|
38850
39437
|
});
|
|
@@ -38855,7 +39442,7 @@ var parseOpenStackResponse2 = /* @__PURE__ */ __name((data, schema, operation, e
|
|
|
38855
39442
|
const parsed = schema.safeParse(data);
|
|
38856
39443
|
if (!parsed.success) {
|
|
38857
39444
|
console.error(`Zod Parsing Error in ${operation}:`, parsed.error.format());
|
|
38858
|
-
throw new
|
|
39445
|
+
throw new import_server26.TRPCError({
|
|
38859
39446
|
code: "INTERNAL_SERVER_ERROR",
|
|
38860
39447
|
message: errorMessage
|
|
38861
39448
|
});
|
|
@@ -39179,7 +39766,7 @@ var buildAppRouter = /* @__PURE__ */ __name((policyDir, extraRouters = []) => {
|
|
|
39179
39766
|
}, "buildAppRouter");
|
|
39180
39767
|
|
|
39181
39768
|
// src/server/context.ts
|
|
39182
|
-
var
|
|
39769
|
+
var import_signal_openstack9 = __toESM(require_esm());
|
|
39183
39770
|
|
|
39184
39771
|
// src/server/sessionCookie.ts
|
|
39185
39772
|
var import_cookie = require("@fastify/cookie");
|
|
@@ -39267,7 +39854,7 @@ async function createContext(opts, config) {
|
|
|
39267
39854
|
writable: false
|
|
39268
39855
|
});
|
|
39269
39856
|
if (currentAuthToken) {
|
|
39270
|
-
openstackSession = await (0,
|
|
39857
|
+
openstackSession = await (0, import_signal_openstack9.SignalOpenstackSession)(normalizedEndpoint, {
|
|
39271
39858
|
auth: {
|
|
39272
39859
|
identity: {
|
|
39273
39860
|
methods: [
|
|
@@ -39330,7 +39917,7 @@ async function createContext(opts, config) {
|
|
|
39330
39917
|
}
|
|
39331
39918
|
}, "getUserInfo");
|
|
39332
39919
|
const createSession = /* @__PURE__ */ __name(async (params) => {
|
|
39333
|
-
openstackSession = await (0,
|
|
39920
|
+
openstackSession = await (0, import_signal_openstack9.SignalOpenstackSession)(normalizedEndpoint, {
|
|
39334
39921
|
auth: {
|
|
39335
39922
|
identity: {
|
|
39336
39923
|
methods: [
|
|
@@ -39390,53 +39977,51 @@ async function createContext(opts, config) {
|
|
|
39390
39977
|
return openstackSession;
|
|
39391
39978
|
}
|
|
39392
39979
|
const rescopeTokenPromise = (async () => {
|
|
39393
|
-
|
|
39394
|
-
|
|
39395
|
-
|
|
39396
|
-
|
|
39397
|
-
|
|
39398
|
-
|
|
39399
|
-
|
|
39400
|
-
|
|
39401
|
-
|
|
39402
|
-
|
|
39403
|
-
|
|
39404
|
-
|
|
39405
|
-
|
|
39406
|
-
|
|
39407
|
-
|
|
39408
|
-
|
|
39409
|
-
|
|
39410
|
-
|
|
39411
|
-
|
|
39412
|
-
|
|
39413
|
-
existingRescopes.set(key, value);
|
|
39414
|
-
}
|
|
39980
|
+
const newScope = newScopeProjectId ? {
|
|
39981
|
+
project: {
|
|
39982
|
+
id: newScopeProjectId
|
|
39983
|
+
}
|
|
39984
|
+
} : newScopeDomainId ? {
|
|
39985
|
+
domain: {
|
|
39986
|
+
id: newScopeDomainId
|
|
39987
|
+
}
|
|
39988
|
+
} : "unscoped";
|
|
39989
|
+
await openstackSession.rescope(newScope);
|
|
39990
|
+
const newToken = openstackSession.getToken();
|
|
39991
|
+
const newAuthToken2 = newToken?.authToken;
|
|
39992
|
+
if (newAuthToken2 && newAuthToken2 !== sessionToken) {
|
|
39993
|
+
const oldPendingRescopes = sessionRescopes.get(sessionToken);
|
|
39994
|
+
if (oldPendingRescopes) {
|
|
39995
|
+
const existingRescopes = sessionRescopes.get(newAuthToken2);
|
|
39996
|
+
if (existingRescopes) {
|
|
39997
|
+
for (const [key, value] of oldPendingRescopes.entries()) {
|
|
39998
|
+
if (!existingRescopes.has(key)) {
|
|
39999
|
+
existingRescopes.set(key, value);
|
|
39415
40000
|
}
|
|
39416
|
-
} else {
|
|
39417
|
-
sessionRescopes.set(newAuthToken2, oldPendingRescopes);
|
|
39418
40001
|
}
|
|
39419
|
-
|
|
40002
|
+
} else {
|
|
40003
|
+
sessionRescopes.set(newAuthToken2, oldPendingRescopes);
|
|
39420
40004
|
}
|
|
39421
|
-
}
|
|
39422
|
-
cachedUserId = void 0;
|
|
39423
|
-
cachedUserInfo = void 0;
|
|
39424
|
-
return newAuthToken2 || null;
|
|
39425
|
-
} catch (err) {
|
|
39426
|
-
console.error("Rescope error:", err);
|
|
39427
|
-
return null;
|
|
39428
|
-
} finally {
|
|
39429
|
-
pendingRescopes.delete(scopeKey);
|
|
39430
|
-
if (pendingRescopes.size === 0) {
|
|
39431
40005
|
sessionRescopes.delete(sessionToken);
|
|
39432
|
-
const currentToken = openstackSession?.getToken()?.authToken;
|
|
39433
|
-
if (currentToken && currentToken !== sessionToken && sessionRescopes.get(currentToken)?.size === 0) {
|
|
39434
|
-
sessionRescopes.delete(currentToken);
|
|
39435
|
-
}
|
|
39436
40006
|
}
|
|
39437
40007
|
}
|
|
40008
|
+
cachedUserId = void 0;
|
|
40009
|
+
cachedUserInfo = void 0;
|
|
40010
|
+
return newAuthToken2 || null;
|
|
39438
40011
|
})();
|
|
40012
|
+
const cleanupPromise = rescopeTokenPromise.finally(() => {
|
|
40013
|
+
pendingRescopes.delete(scopeKey);
|
|
40014
|
+
if (pendingRescopes.size === 0) {
|
|
40015
|
+
sessionRescopes.delete(sessionToken);
|
|
40016
|
+
const currentToken = openstackSession?.getToken()?.authToken;
|
|
40017
|
+
if (currentToken && currentToken !== sessionToken && sessionRescopes.get(currentToken)?.size === 0) {
|
|
40018
|
+
sessionRescopes.delete(currentToken);
|
|
40019
|
+
}
|
|
40020
|
+
}
|
|
40021
|
+
});
|
|
39439
40022
|
pendingRescopes.set(scopeKey, rescopeTokenPromise);
|
|
40023
|
+
cleanupPromise.catch(() => {
|
|
40024
|
+
});
|
|
39440
40025
|
const newAuthToken = await rescopeTokenPromise;
|
|
39441
40026
|
if (!newAuthToken) {
|
|
39442
40027
|
return null;
|
|
@@ -39586,6 +40171,19 @@ async function createServer(config) {
|
|
|
39586
40171
|
}, (_req, payload, done) => {
|
|
39587
40172
|
done(null, payload);
|
|
39588
40173
|
});
|
|
40174
|
+
server.register(csrfProtection_default, {
|
|
40175
|
+
tokenRoute: "/csrf-token",
|
|
40176
|
+
cookieKey: "aurora-csrf-protection",
|
|
40177
|
+
tokenHeader: "x-csrf-token",
|
|
40178
|
+
excludePaths: [
|
|
40179
|
+
"/extensions"
|
|
40180
|
+
],
|
|
40181
|
+
protectionMethods: [
|
|
40182
|
+
"POST",
|
|
40183
|
+
"PUT",
|
|
40184
|
+
"DELETE"
|
|
40185
|
+
]
|
|
40186
|
+
});
|
|
39589
40187
|
server.post(`${bffEndpoint}/upload-image-direct`, {
|
|
39590
40188
|
config: {
|
|
39591
40189
|
rawBody: false
|
|
@@ -39652,19 +40250,6 @@ async function createServer(config) {
|
|
|
39652
40250
|
});
|
|
39653
40251
|
}
|
|
39654
40252
|
});
|
|
39655
|
-
server.register(csrfProtection_default, {
|
|
39656
|
-
tokenRoute: "/csrf-token",
|
|
39657
|
-
cookieKey: "aurora-csrf-protection",
|
|
39658
|
-
tokenHeader: "x-csrf-token",
|
|
39659
|
-
excludePaths: [
|
|
39660
|
-
"/extensions"
|
|
39661
|
-
],
|
|
39662
|
-
protectionMethods: [
|
|
39663
|
-
"POST",
|
|
39664
|
-
"PUT",
|
|
39665
|
-
"DELETE"
|
|
39666
|
-
]
|
|
39667
|
-
});
|
|
39668
40253
|
server.addHook("onRequest", (request, _reply, done) => {
|
|
39669
40254
|
if (request.url.includes("/compute.uploadImage")) {
|
|
39670
40255
|
request.raw.setTimeout(0);
|