@cobaltcore-dev/aurora 0.6.0 → 0.8.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.
Files changed (102) hide show
  1. package/README.md +160 -20
  2. package/dist/client/AuroraApp.d.ts +38 -0
  3. package/dist/client/{ContentHeader-kx1Th5Sq.mjs → ContentHeader-DqsGNvtD.mjs} +17 -17
  4. package/dist/client/{ContentHeader-kx1Th5Sq.mjs.map → ContentHeader-DqsGNvtD.mjs.map} +1 -1
  5. package/dist/client/{DeleteFlavorModal-C3cb7YiJ.mjs → DeleteFlavorModal-C3m7bQJu.mjs} +163 -163
  6. package/dist/client/{DeleteFlavorModal-C3cb7YiJ.mjs.map → DeleteFlavorModal-C3m7bQJu.mjs.map} +1 -1
  7. package/dist/client/{EditSecurityGroupModal-CpP54WIK.mjs → EditSecurityGroupModal-DKusxfta.mjs} +18 -18
  8. package/dist/client/{EditSecurityGroupModal-CpP54WIK.mjs.map → EditSecurityGroupModal-DKusxfta.mjs.map} +1 -1
  9. package/dist/client/{FiltersInput-DxcyR6Bp.mjs → FiltersInput-GzR4D0q6.mjs} +21 -21
  10. package/dist/client/{FiltersInput-DxcyR6Bp.mjs.map → FiltersInput-GzR4D0q6.mjs.map} +1 -1
  11. package/dist/client/{FloatingIpActionModals-BP8RWHbu.mjs → FloatingIpActionModals-CRvROJ3H.mjs} +51 -51
  12. package/dist/client/{FloatingIpActionModals-BP8RWHbu.mjs.map → FloatingIpActionModals-CRvROJ3H.mjs.map} +1 -1
  13. package/dist/client/{ImageToastNotifications-TZ3EfQg-.mjs → ImageToastNotifications-BuDXpTkl.mjs} +344 -344
  14. package/dist/client/{ImageToastNotifications-TZ3EfQg-.mjs.map → ImageToastNotifications-BuDXpTkl.mjs.map} +1 -1
  15. package/dist/client/{RouteError-QSV7qOoJ.mjs → RouteError-DVAiT0mT.mjs} +2 -2
  16. package/dist/client/{RouteError-QSV7qOoJ.mjs.map → RouteError-DVAiT0mT.mjs.map} +1 -1
  17. package/dist/client/{SortInput-CYv2_Pur.mjs → SortInput-VK7IYqQv.mjs} +6 -6
  18. package/dist/client/{SortInput-CYv2_Pur.mjs.map → SortInput-VK7IYqQv.mjs.map} +1 -1
  19. package/dist/client/_auth-DXJkv9QO.mjs.map +1 -1
  20. package/dist/client/{_flavorId-C2x43-6S.mjs → _flavorId-B9Vqkraj.mjs} +8 -8
  21. package/dist/client/{_flavorId-C2x43-6S.mjs.map → _flavorId-B9Vqkraj.mjs.map} +1 -1
  22. package/dist/client/{_flavorId-CR8ZUI-P.mjs → _flavorId-CFpNGz52.mjs} +62 -62
  23. package/dist/client/{_flavorId-CR8ZUI-P.mjs.map → _flavorId-CFpNGz52.mjs.map} +1 -1
  24. package/dist/client/{_floatingIpId-BCk41_Lb.mjs → _floatingIpId-B5GMSLeQ.mjs} +2 -2
  25. package/dist/client/{_floatingIpId-BCk41_Lb.mjs.map → _floatingIpId-B5GMSLeQ.mjs.map} +1 -1
  26. package/dist/client/{_floatingIpId-BGrOAmPT.mjs → _floatingIpId-C2-BeRmF.mjs} +27 -27
  27. package/dist/client/{_floatingIpId-BGrOAmPT.mjs.map → _floatingIpId-C2-BeRmF.mjs.map} +1 -1
  28. package/dist/client/_imageId-9NZytfNs.mjs +534 -0
  29. package/dist/client/{_imageId-CvfD832b.mjs.map → _imageId-9NZytfNs.mjs.map} +1 -1
  30. package/dist/client/_pcaId-BwTvJJgh.mjs +479 -0
  31. package/dist/client/_pcaId-BwTvJJgh.mjs.map +1 -0
  32. package/dist/client/{_pcaId-DOHycvCf.mjs → _pcaId-DUHQd0rB.mjs} +2 -2
  33. package/dist/client/{_pcaId-DOHycvCf.mjs.map → _pcaId-DUHQd0rB.mjs.map} +1 -1
  34. package/dist/client/{_projectId-DOgwFiqD.mjs → _projectId-B_2sZKk-.mjs} +2 -2
  35. package/dist/client/{_projectId-DOgwFiqD.mjs.map → _projectId-B_2sZKk-.mjs.map} +1 -1
  36. package/dist/client/{_projectId-MxcHrXW4.mjs → _projectId-CLgClx24.mjs} +3 -3
  37. package/dist/client/{_projectId-MxcHrXW4.mjs.map → _projectId-CLgClx24.mjs.map} +1 -1
  38. package/dist/client/_projectId-cW9aQ4Ag.mjs +271 -0
  39. package/dist/client/_projectId-cW9aQ4Ag.mjs.map +1 -0
  40. package/dist/client/{_securityGroupId-KKw4RPdH.mjs → _securityGroupId-DYxmXUOP.mjs} +319 -319
  41. package/dist/client/{_securityGroupId-KKw4RPdH.mjs.map → _securityGroupId-DYxmXUOP.mjs.map} +1 -1
  42. package/dist/client/{_securityGroupId-CJJanWiY.mjs → _securityGroupId-fhK1CuZh.mjs} +2 -2
  43. package/dist/client/{_securityGroupId-CJJanWiY.mjs.map → _securityGroupId-fhK1CuZh.mjs.map} +1 -1
  44. package/dist/client/{_storageType-DYjo-6ej.mjs → _storageType-2_fau4B5.mjs} +698 -698
  45. package/dist/client/{_storageType-DYjo-6ej.mjs.map → _storageType-2_fau4B5.mjs.map} +1 -1
  46. package/dist/client/{_storageType-4wSxI__0.mjs → _storageType-dRTFMKG3.mjs} +2 -2
  47. package/dist/client/{_storageType-4wSxI__0.mjs.map → _storageType-dRTFMKG3.mjs.map} +1 -1
  48. package/dist/client/{about-Bo9vxGHy.mjs → about-Nsxkyh9U.mjs} +2 -2
  49. package/dist/client/{about-Bo9vxGHy.mjs.map → about-Nsxkyh9U.mjs.map} +1 -1
  50. package/dist/client/{build-DeJcDjPi.mjs → build-BdRRmNf5.mjs} +3290 -3274
  51. package/dist/client/{build-DeJcDjPi.mjs.map → build-BdRRmNf5.mjs.map} +1 -1
  52. package/dist/client/{constants-BmcGYeR-.mjs → constants-J5nm9hbP.mjs} +15 -15
  53. package/dist/client/{constants-BmcGYeR-.mjs.map → constants-J5nm9hbP.mjs.map} +1 -1
  54. package/dist/client/{flavors-BxFVqgnb.mjs → flavors-_P7R-CeT.mjs} +2 -2
  55. package/dist/client/{flavors-BxFVqgnb.mjs.map → flavors-_P7R-CeT.mjs.map} +1 -1
  56. package/dist/client/{flavors-CfdgjsZY.mjs → flavors-m1qDHzeS.mjs} +238 -221
  57. package/dist/client/flavors-m1qDHzeS.mjs.map +1 -0
  58. package/dist/client/{floatingips-ByRb82wS.mjs → floatingips-Dq4DXQYb.mjs} +90 -90
  59. package/dist/client/{floatingips-ByRb82wS.mjs.map → floatingips-Dq4DXQYb.mjs.map} +1 -1
  60. package/dist/client/{images-CenluYV8.mjs → images-CpM-T_jM.mjs} +2 -2
  61. package/dist/client/{images-CenluYV8.mjs.map → images-CpM-T_jM.mjs.map} +1 -1
  62. package/dist/client/images-DHmVgQAh2.mjs +1890 -0
  63. package/dist/client/images-DHmVgQAh2.mjs.map +1 -0
  64. package/dist/client/{images-C_dX7nY6.mjs → images-Dbjo4yKn.mjs} +2 -2
  65. package/dist/client/{images-C_dX7nY6.mjs.map → images-Dbjo4yKn.mjs.map} +1 -1
  66. package/dist/client/index.d.ts +1 -1
  67. package/dist/client/index.js +390 -356
  68. package/dist/client/index.js.map +1 -1
  69. package/dist/client/{objects-gxSjvbvF.mjs → objects-DKWp9RtR.mjs} +2 -2
  70. package/dist/client/{objects-gxSjvbvF.mjs.map → objects-DKWp9RtR.mjs.map} +1 -1
  71. package/dist/client/{objects-BJM6YeuF.mjs → objects-DaCuy_CB.mjs} +1156 -1156
  72. package/dist/client/{objects-BJM6YeuF.mjs.map → objects-DaCuy_CB.mjs.map} +1 -1
  73. package/dist/client/{pca-Bl8NmoVZ.mjs → pca-C8zWTSSt.mjs} +2 -2
  74. package/dist/client/{pca-Bl8NmoVZ.mjs.map → pca-C8zWTSSt.mjs.map} +1 -1
  75. package/dist/client/pca-CK5-j7Kk.mjs +202 -0
  76. package/dist/client/pca-CK5-j7Kk.mjs.map +1 -0
  77. package/dist/client/{projects-pe2_dCnV.mjs → projects-CHYn7L5e.mjs} +2 -2
  78. package/dist/client/{projects-pe2_dCnV.mjs.map → projects-CHYn7L5e.mjs.map} +1 -1
  79. package/dist/client/{projects-D2iewAzu.mjs → projects-CeLhtLvf.mjs} +2 -2
  80. package/dist/client/{projects-D2iewAzu.mjs.map → projects-CeLhtLvf.mjs.map} +1 -1
  81. package/dist/client/{projects-CgclWI16.mjs → projects-ClViaUuv.mjs} +11 -11
  82. package/dist/client/{projects-CgclWI16.mjs.map → projects-ClViaUuv.mjs.map} +1 -1
  83. package/dist/client/{_projectId-BDSWnMGj.mjs → routeInfo-DlDJZnpg.mjs} +34 -8
  84. package/dist/client/routeInfo-DlDJZnpg.mjs.map +1 -0
  85. package/dist/client/{securitygroups-DahZkVYQ.mjs → securitygroups-CNFLu9zS.mjs} +112 -112
  86. package/dist/client/{securitygroups-DahZkVYQ.mjs.map → securitygroups-CNFLu9zS.mjs.map} +1 -1
  87. package/dist/client/{useListWithFiltering-DaYcu5AB.mjs → useListWithFiltering-v2A0-SZb.mjs} +9 -9
  88. package/dist/client/{useListWithFiltering-DaYcu5AB.mjs.map → useListWithFiltering-v2A0-SZb.mjs.map} +1 -1
  89. package/dist/server/index.d.ts +576 -2
  90. package/dist/server/index.js +59 -217
  91. package/package.json +4 -5
  92. package/dist/client/_imageId-CvfD832b.mjs +0 -534
  93. package/dist/client/_pcaId-BxBt5DXi.mjs +0 -459
  94. package/dist/client/_pcaId-BxBt5DXi.mjs.map +0 -1
  95. package/dist/client/_projectId-BDSWnMGj.mjs.map +0 -1
  96. package/dist/client/_projectId-DS4nR59B.mjs +0 -299
  97. package/dist/client/_projectId-DS4nR59B.mjs.map +0 -1
  98. package/dist/client/flavors-CfdgjsZY.mjs.map +0 -1
  99. package/dist/client/images-CKqIXUq52.mjs +0 -1873
  100. package/dist/client/images-CKqIXUq52.mjs.map +0 -1
  101. package/dist/client/pca-RSiWpJs9.mjs +0 -182
  102. package/dist/client/pca-RSiWpJs9.mjs.map +0 -1
@@ -1,4 +1,13 @@
1
- import { FastifyInstance } from 'fastify';
1
+ import * as fastify from 'fastify';
2
+ import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
3
+ import * as _trpc_server from '@trpc/server';
4
+ import { AnyRouter } from '@trpc/server';
5
+ import * as _cobaltcore_dev_signal_openstack from '@cobaltcore-dev/signal-openstack';
6
+ import { SignalOpenstackSessionType } from '@cobaltcore-dev/signal-openstack';
7
+ import { ProxyConfig } from './shared-types';
8
+ import * as fastify_types_type_provider from 'fastify/types/type-provider';
9
+ import * as http from 'http';
10
+ import { z } from 'zod';
2
11
 
3
12
  declare module "fastify" {
4
13
  interface FastifyRequest {
@@ -34,8 +43,573 @@ interface AuroraServerConfig {
34
43
  * over the legacy in-tree permission_custom_policies/ directory.
35
44
  */
36
45
  policyDir: string;
46
+ /**
47
+ * Additional tRPC routers to merge into the Aurora router at startup.
48
+ *
49
+ * Routers passed here share the same Fastify request context as the built-in
50
+ * Aurora routers (session cookies, OpenStack client, rescoping helpers).
51
+ *
52
+ * **Requirements:**
53
+ * - Routers MUST be created with the `auroraRouter` function exported from
54
+ * `@cobaltcore-dev/aurora/server`. Using a different `initTRPC` instance
55
+ * produces an incompatible context type and will cause runtime failures when
56
+ * procedures attempt to access `ctx.openstack`, `ctx.validateSession`, etc.
57
+ * - Use `protectedProcedure` (or `projectScopedProcedure` /
58
+ * `domainScopedProcedure`) for any procedure that requires an authenticated
59
+ * session. All of these are exported from `@cobaltcore-dev/aurora/server`.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * import { auroraRouter, protectedProcedure, createServer } from "@cobaltcore-dev/aurora/server"
64
+ * import { z } from "zod"
65
+ *
66
+ * const customRouter = auroraRouter({
67
+ * feedback: protectedProcedure
68
+ * .input(z.object({ message: z.string() }))
69
+ * .mutation(async ({ input }) => ({ status: "received" })),
70
+ * })
71
+ *
72
+ * createServer({ ..., routers: [customRouter] })
73
+ * ```
74
+ */
75
+ routers?: AnyRouter[];
37
76
  }
38
77
 
39
78
  declare function createServer(config: AuroraServerConfig): Promise<FastifyInstance>;
40
79
 
41
- export { type AuroraServerConfig, createServer };
80
+ interface AuroraContext {
81
+ validateSession: () => boolean;
82
+ openstack?: Awaited<SignalOpenstackSessionType>;
83
+ signal: AbortSignal;
84
+ getUserInfo?: () => Promise<{
85
+ availableDomains: Array<{
86
+ id: string;
87
+ name: string;
88
+ }>;
89
+ } | undefined>;
90
+ }
91
+ interface FormFieldData {
92
+ [key: string]: string | string[];
93
+ }
94
+ interface AuroraPortalContext extends AuroraContext {
95
+ req: FastifyRequest;
96
+ /** Fastify reply object for setting response headers/cookies */
97
+ res: FastifyReply;
98
+ /** Normalised identity endpoint (always ends with /) */
99
+ identityEndpoint: string;
100
+ /** Ceph/S3 region from consumer config */
101
+ cephRegion?: string;
102
+ /** Parsed list of image metadata keys excluded from the UI */
103
+ imageMetadataExcludedProperties: string[];
104
+ createSession: (params: {
105
+ user: string;
106
+ password: string;
107
+ domain: string;
108
+ }) => SignalOpenstackSessionType;
109
+ rescopeSession: (scope: {
110
+ projectId?: string;
111
+ domainId?: string;
112
+ }) => Promise<Awaited<SignalOpenstackSessionType | null>>;
113
+ terminateSession: () => Promise<void>;
114
+ formFields?: FormFieldData;
115
+ }
116
+
117
+ interface RequestParams {
118
+ method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD";
119
+ path: string;
120
+ options?: {
121
+ host?: string;
122
+ headers?: Record<string, string>;
123
+ body?: string | object | FormData | Blob | ArrayBuffer | ReadableStream;
124
+ queryParams?: Record<string, string | string[] | number | boolean | null | undefined>;
125
+ signal?: AbortSignal;
126
+ debug?: boolean;
127
+ proxy?: ProxyConfig;
128
+ };
129
+ }
130
+ type ActionBody = NonNullable<RequestParams["options"]>["body"];
131
+ type ActionPath = RequestParams["path"];
132
+
133
+ declare const auroraRouter: _trpc_server.TRPCRouterBuilder<{
134
+ ctx: AuroraPortalContext;
135
+ meta: object;
136
+ errorShape: _trpc_server.TRPCDefaultErrorShape;
137
+ transformer: false;
138
+ }>;
139
+ declare const publicProcedure: _trpc_server.TRPCProcedureBuilder<AuroraPortalContext, object, object, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
140
+ declare const protectedProcedure: _trpc_server.TRPCProcedureBuilder<AuroraPortalContext, object, {
141
+ req: fastify.FastifyRequest<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown, fastify.FastifyBaseLogger, fastify_types_type_provider.ResolveFastifyRequestType<fastify.FastifyTypeProviderDefault, fastify.FastifySchema, fastify.RouteGenericInterface>>;
142
+ res: fastify.FastifyReply<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, unknown, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown>;
143
+ signal: AbortSignal;
144
+ createSession: (params: {
145
+ user: string;
146
+ password: string;
147
+ domain: string;
148
+ }) => _cobaltcore_dev_signal_openstack.SignalOpenstackSessionType;
149
+ rescopeSession: (scope: {
150
+ projectId?: string;
151
+ domainId?: string;
152
+ }) => Promise<Awaited<_cobaltcore_dev_signal_openstack.SignalOpenstackSessionType | null>>;
153
+ identityEndpoint: string;
154
+ cephRegion: string | undefined;
155
+ terminateSession: () => Promise<void>;
156
+ validateSession: () => boolean;
157
+ openstack: {
158
+ service: (name: string, serviceDefaultOptions?: _cobaltcore_dev_signal_openstack.SignalOpenstackOptions) => {
159
+ availableEndpoints: () => {
160
+ id: string;
161
+ interface: string;
162
+ region: string;
163
+ region_id: string;
164
+ url: string;
165
+ }[] | undefined;
166
+ getEndpoint: (options?: {
167
+ region?: string;
168
+ interfaceName?: string;
169
+ }) => string | null;
170
+ head: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
171
+ get: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
172
+ post: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
173
+ put: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
174
+ patch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
175
+ del: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
176
+ cancellableHead: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
177
+ cancellableGet: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
178
+ cancellablePost: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
179
+ cancellablePut: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
180
+ cancellablePatch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
181
+ cancellableDel: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
182
+ };
183
+ hasService: (name: string) => boolean;
184
+ terminate: () => Promise<void>;
185
+ rescope: (scope: _cobaltcore_dev_signal_openstack.AuthConfig["auth"]["scope"]) => Promise<void>;
186
+ getToken: () => {
187
+ authToken: string;
188
+ tokenData: {
189
+ application_credential?: {
190
+ id: string;
191
+ name: string;
192
+ restricted: boolean;
193
+ };
194
+ audit_ids?: string[];
195
+ catalog?: {
196
+ endpoints: {
197
+ id: string;
198
+ interface: string;
199
+ region: string;
200
+ region_id: string;
201
+ url: string;
202
+ }[];
203
+ type: string;
204
+ id: string;
205
+ name: string;
206
+ }[];
207
+ expires_at: string;
208
+ issued_at: string;
209
+ methods: string[];
210
+ roles: {
211
+ id: string;
212
+ name: string;
213
+ }[];
214
+ system: {
215
+ all: boolean;
216
+ };
217
+ project?: {
218
+ domain?: {
219
+ id?: string;
220
+ name?: string;
221
+ };
222
+ id?: string;
223
+ name?: string;
224
+ };
225
+ domain?: {
226
+ id?: string;
227
+ name?: string;
228
+ };
229
+ user: {
230
+ domain: {
231
+ id: string;
232
+ name: string;
233
+ };
234
+ id: string;
235
+ name: string;
236
+ password_expires_at: string;
237
+ };
238
+ };
239
+ isExpired: () => boolean;
240
+ expiresAtDate: Date;
241
+ availableRegions: string[];
242
+ serviceEndpoint: (nameOrType: string, { region, interfaceName }: {
243
+ region?: string;
244
+ interfaceName: string;
245
+ }) => string | null;
246
+ hasService: (nameOrType: string) => boolean;
247
+ hasRole: (name: string) => boolean;
248
+ } | undefined;
249
+ isValid: () => boolean | "" | undefined;
250
+ } | undefined;
251
+ getUserInfo: (() => Promise<{
252
+ availableDomains: Array<{
253
+ id: string;
254
+ name: string;
255
+ }>;
256
+ } | undefined>) | undefined;
257
+ imageMetadataExcludedProperties: string[];
258
+ formFields: FormFieldData | undefined;
259
+ }, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
260
+ /**
261
+ * Base input schema that all project-scoped procedures must extend
262
+ * Ensures project_id is always present and validated
263
+ */
264
+ declare const projectScopedInputSchema: z.ZodObject<{
265
+ project_id: z.ZodString;
266
+ }, z.core.$strip>;
267
+ /**
268
+ * Base input schema that all domain-scoped procedures must extend
269
+ * Ensures domain_id is always present and validated
270
+ */
271
+ declare const domainScopedInputSchema: z.ZodObject<{
272
+ domain_id: z.ZodString;
273
+ }, z.core.$strip>;
274
+ /**
275
+ * Project-scoped procedure middleware
276
+ *
277
+ * Automatically handles OpenStack token rescoping to a specific project.
278
+ * This middleware ensures that all subsequent API calls have the correct
279
+ * project-scoped token, which is required for accessing project-level resources
280
+ * like compute instances, networks, volumes, etc.
281
+ *
282
+ * Requirements:
283
+ * - User must be authenticated (extends protectedProcedure)
284
+ * - Input is pre-validated with projectScopedInputSchema (base schema applied)
285
+ * - Additional input fields can be added by extending the base schema
286
+ *
287
+ * Behavior:
288
+ * - Validates project_id through Zod schema (no manual validation needed)
289
+ * - Rescopes the OpenStack session to the specified project using Keystone
290
+ * - Caches the scoped token in a cookie to avoid unnecessary rescoping on subsequent requests
291
+ * - Passes the rescoped session to downstream procedures via ctx.openstack
292
+ *
293
+ * Error handling:
294
+ * - BAD_REQUEST: If project_id is missing or invalid (handled by Zod schema)
295
+ * - UNAUTHORIZED: If token rescoping fails, including when the session cannot be
296
+ * rescoped to the specified project (for example, due to an invalid token,
297
+ * Keystone unavailability, or missing role assignment on that project)
298
+ *
299
+ * Usage example:
300
+ * ```ts
301
+ * export const computeRouter = {
302
+ * listServers: projectScopedProcedure
303
+ * .input(projectScopedInputSchema.extend({ limit: z.number().optional() }))
304
+ * .query(async ({ ctx, input }) => {
305
+ * // Token is already rescoped to the project
306
+ * const compute = ctx.openstack.service("compute")
307
+ * return compute.servers.list()
308
+ * })
309
+ * }
310
+ * ```
311
+ *
312
+ * @important When extending the input schema, use projectScopedInputSchema.extend({ ... })
313
+ */
314
+ declare const projectScopedProcedure: _trpc_server.TRPCProcedureBuilder<AuroraPortalContext, object, {
315
+ req: fastify.FastifyRequest<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown, fastify.FastifyBaseLogger, fastify_types_type_provider.ResolveFastifyRequestType<fastify.FastifyTypeProviderDefault, fastify.FastifySchema, fastify.RouteGenericInterface>>;
316
+ res: fastify.FastifyReply<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, unknown, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown>;
317
+ signal: AbortSignal;
318
+ createSession: (params: {
319
+ user: string;
320
+ password: string;
321
+ domain: string;
322
+ }) => _cobaltcore_dev_signal_openstack.SignalOpenstackSessionType;
323
+ rescopeSession: (scope: {
324
+ projectId?: string;
325
+ domainId?: string;
326
+ }) => Promise<Awaited<_cobaltcore_dev_signal_openstack.SignalOpenstackSessionType | null>>;
327
+ identityEndpoint: string;
328
+ cephRegion: string | undefined;
329
+ terminateSession: () => Promise<void>;
330
+ validateSession: () => boolean;
331
+ openstack: {
332
+ service: (name: string, serviceDefaultOptions?: _cobaltcore_dev_signal_openstack.SignalOpenstackOptions) => {
333
+ availableEndpoints: () => {
334
+ id: string;
335
+ interface: string;
336
+ region: string;
337
+ region_id: string;
338
+ url: string;
339
+ }[] | undefined;
340
+ getEndpoint: (options?: {
341
+ region?: string;
342
+ interfaceName?: string;
343
+ }) => string | null;
344
+ head: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
345
+ get: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
346
+ post: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
347
+ put: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
348
+ patch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
349
+ del: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
350
+ cancellableHead: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
351
+ cancellableGet: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
352
+ cancellablePost: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
353
+ cancellablePut: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
354
+ cancellablePatch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
355
+ cancellableDel: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
356
+ };
357
+ hasService: (name: string) => boolean;
358
+ terminate: () => Promise<void>;
359
+ rescope: (scope: _cobaltcore_dev_signal_openstack.AuthConfig["auth"]["scope"]) => Promise<void>;
360
+ getToken: () => {
361
+ authToken: string;
362
+ tokenData: {
363
+ application_credential?: {
364
+ id: string;
365
+ name: string;
366
+ restricted: boolean;
367
+ };
368
+ audit_ids?: string[];
369
+ catalog?: {
370
+ endpoints: {
371
+ id: string;
372
+ interface: string;
373
+ region: string;
374
+ region_id: string;
375
+ url: string;
376
+ }[];
377
+ type: string;
378
+ id: string;
379
+ name: string;
380
+ }[];
381
+ expires_at: string;
382
+ issued_at: string;
383
+ methods: string[];
384
+ roles: {
385
+ id: string;
386
+ name: string;
387
+ }[];
388
+ system: {
389
+ all: boolean;
390
+ };
391
+ project?: {
392
+ domain?: {
393
+ id?: string;
394
+ name?: string;
395
+ };
396
+ id?: string;
397
+ name?: string;
398
+ };
399
+ domain?: {
400
+ id?: string;
401
+ name?: string;
402
+ };
403
+ user: {
404
+ domain: {
405
+ id: string;
406
+ name: string;
407
+ };
408
+ id: string;
409
+ name: string;
410
+ password_expires_at: string;
411
+ };
412
+ };
413
+ isExpired: () => boolean;
414
+ expiresAtDate: Date;
415
+ availableRegions: string[];
416
+ serviceEndpoint: (nameOrType: string, { region, interfaceName }: {
417
+ region?: string;
418
+ interfaceName: string;
419
+ }) => string | null;
420
+ hasService: (nameOrType: string) => boolean;
421
+ hasRole: (name: string) => boolean;
422
+ } | undefined;
423
+ isValid: () => boolean | "" | undefined;
424
+ };
425
+ getUserInfo: (() => Promise<{
426
+ availableDomains: Array<{
427
+ id: string;
428
+ name: string;
429
+ }>;
430
+ } | undefined>) | undefined;
431
+ imageMetadataExcludedProperties: string[];
432
+ formFields: FormFieldData | undefined;
433
+ }, {
434
+ project_id: string;
435
+ }, {
436
+ project_id: string;
437
+ }, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
438
+ /**
439
+ * Domain-scoped procedure middleware
440
+ *
441
+ * Automatically handles OpenStack token rescoping to a specific domain.
442
+ * This middleware ensures that all subsequent API calls have the correct
443
+ * domain-scoped token, which is required for accessing domain-level resources
444
+ * and performing administrative operations like user management, project creation, etc.
445
+ *
446
+ * Requirements:
447
+ * - User must be authenticated (extends protectedProcedure)
448
+ * - Input is pre-validated with domainScopedInputSchema (base schema applied)
449
+ * - User must have access to the requested domain (validated via lazy-loaded getUserInfo)
450
+ * - Additional input fields can be added by extending the base schema
451
+ *
452
+ * Behavior:
453
+ * - Validates domain_id through Zod schema (no manual validation needed)
454
+ * - Lazy-loads user info (calls /v3/auth/domains) only when this procedure is invoked
455
+ * - Verifies that the domain is in the user's available domains list
456
+ * - Rescopes the OpenStack session to the specified domain using Keystone
457
+ * - Keystone enforces permissions based on user's actual role assignments in that domain
458
+ * - Caches the scoped token in a cookie to avoid unnecessary rescoping on subsequent requests
459
+ * - Passes the rescoped session to downstream procedures via ctx.openstack
460
+ *
461
+ * Performance:
462
+ * - User info is fetched lazily (only when domainScopedProcedure is used)
463
+ * - This avoids unnecessary Keystone API calls for project-scoped or public procedures
464
+ * - User info is cached per session to avoid repeated API calls
465
+ *
466
+ * Error handling:
467
+ * - BAD_REQUEST: If domain_id is missing or invalid (handled by Zod schema)
468
+ * - FORBIDDEN: If user lacks access to the requested domain
469
+ * - UNAUTHORIZED: If token rescoping fails (e.g., invalid token, Keystone unavailable)
470
+ *
471
+ * Note: We don't check for specific role names (like "admin") because OpenStack roles
472
+ * are configurable. Instead, we rely on Keystone to enforce permissions when rescoping.
473
+ *
474
+ * Usage example:
475
+ * ```ts
476
+ * export const identityRouter = {
477
+ * listUsers: domainScopedProcedure
478
+ * .input(domainScopedInputSchema.extend({ includeDisabled: z.boolean().optional() }))
479
+ * .query(async ({ ctx, input }) => {
480
+ * // Token is already rescoped to the domain
481
+ * // Keystone has validated user's permissions in this domain
482
+ * const identity = ctx.openstack.service("identity")
483
+ * return identity.users.list()
484
+ * })
485
+ * }
486
+ * ```
487
+ *
488
+ * @important When extending the input schema, use domainScopedInputSchema.extend({ ... })
489
+ */
490
+ declare const domainScopedProcedure: _trpc_server.TRPCProcedureBuilder<AuroraPortalContext, object, {
491
+ req: fastify.FastifyRequest<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown, fastify.FastifyBaseLogger, fastify_types_type_provider.ResolveFastifyRequestType<fastify.FastifyTypeProviderDefault, fastify.FastifySchema, fastify.RouteGenericInterface>>;
492
+ res: fastify.FastifyReply<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, unknown, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown>;
493
+ signal: AbortSignal;
494
+ createSession: (params: {
495
+ user: string;
496
+ password: string;
497
+ domain: string;
498
+ }) => _cobaltcore_dev_signal_openstack.SignalOpenstackSessionType;
499
+ rescopeSession: (scope: {
500
+ projectId?: string;
501
+ domainId?: string;
502
+ }) => Promise<Awaited<_cobaltcore_dev_signal_openstack.SignalOpenstackSessionType | null>>;
503
+ identityEndpoint: string;
504
+ cephRegion: string | undefined;
505
+ terminateSession: () => Promise<void>;
506
+ validateSession: () => boolean;
507
+ openstack: {
508
+ service: (name: string, serviceDefaultOptions?: _cobaltcore_dev_signal_openstack.SignalOpenstackOptions) => {
509
+ availableEndpoints: () => {
510
+ id: string;
511
+ interface: string;
512
+ region: string;
513
+ region_id: string;
514
+ url: string;
515
+ }[] | undefined;
516
+ getEndpoint: (options?: {
517
+ region?: string;
518
+ interfaceName?: string;
519
+ }) => string | null;
520
+ head: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
521
+ get: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
522
+ post: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
523
+ put: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
524
+ patch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
525
+ del: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
526
+ cancellableHead: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
527
+ cancellableGet: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
528
+ cancellablePost: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
529
+ cancellablePut: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
530
+ cancellablePatch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
531
+ cancellableDel: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
532
+ };
533
+ hasService: (name: string) => boolean;
534
+ terminate: () => Promise<void>;
535
+ rescope: (scope: _cobaltcore_dev_signal_openstack.AuthConfig["auth"]["scope"]) => Promise<void>;
536
+ getToken: () => {
537
+ authToken: string;
538
+ tokenData: {
539
+ application_credential?: {
540
+ id: string;
541
+ name: string;
542
+ restricted: boolean;
543
+ };
544
+ audit_ids?: string[];
545
+ catalog?: {
546
+ endpoints: {
547
+ id: string;
548
+ interface: string;
549
+ region: string;
550
+ region_id: string;
551
+ url: string;
552
+ }[];
553
+ type: string;
554
+ id: string;
555
+ name: string;
556
+ }[];
557
+ expires_at: string;
558
+ issued_at: string;
559
+ methods: string[];
560
+ roles: {
561
+ id: string;
562
+ name: string;
563
+ }[];
564
+ system: {
565
+ all: boolean;
566
+ };
567
+ project?: {
568
+ domain?: {
569
+ id?: string;
570
+ name?: string;
571
+ };
572
+ id?: string;
573
+ name?: string;
574
+ };
575
+ domain?: {
576
+ id?: string;
577
+ name?: string;
578
+ };
579
+ user: {
580
+ domain: {
581
+ id: string;
582
+ name: string;
583
+ };
584
+ id: string;
585
+ name: string;
586
+ password_expires_at: string;
587
+ };
588
+ };
589
+ isExpired: () => boolean;
590
+ expiresAtDate: Date;
591
+ availableRegions: string[];
592
+ serviceEndpoint: (nameOrType: string, { region, interfaceName }: {
593
+ region?: string;
594
+ interfaceName: string;
595
+ }) => string | null;
596
+ hasService: (nameOrType: string) => boolean;
597
+ hasRole: (name: string) => boolean;
598
+ } | undefined;
599
+ isValid: () => boolean | "" | undefined;
600
+ };
601
+ getUserInfo: (() => Promise<{
602
+ availableDomains: Array<{
603
+ id: string;
604
+ name: string;
605
+ }>;
606
+ } | undefined>) | undefined;
607
+ imageMetadataExcludedProperties: string[];
608
+ formFields: FormFieldData | undefined;
609
+ }, {
610
+ domain_id: string;
611
+ }, {
612
+ domain_id: string;
613
+ }, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
614
+
615
+ export { type AuroraServerConfig, auroraRouter, createServer, domainScopedInputSchema, domainScopedProcedure, projectScopedInputSchema, projectScopedProcedure, protectedProcedure, publicProcedure };