@kumori/aurora-backend-handler 1.0.36 → 1.0.38
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/helpers/revision-helper.ts +170 -111
- package/package.json +1 -1
- package/websocket-manager.ts +2 -0
|
@@ -370,7 +370,14 @@ export const handleRevisionEvent = ({
|
|
|
370
370
|
serviceId,
|
|
371
371
|
roleMap,
|
|
372
372
|
);
|
|
373
|
+
const existingRevision = revisionsMap.get(revisionKey);
|
|
373
374
|
const newRevision = createRevision(entityId, eventData, usedCpu, usedMemory);
|
|
375
|
+
if (
|
|
376
|
+
existingRevision?.schema &&
|
|
377
|
+
Object.keys(existingRevision.schema).length > 0
|
|
378
|
+
) {
|
|
379
|
+
newRevision.schema = existingRevision.schema;
|
|
380
|
+
}
|
|
374
381
|
|
|
375
382
|
let updatedService: Service | null = null;
|
|
376
383
|
let updatedEnvironment: Environment | null = null;
|
|
@@ -462,9 +469,122 @@ export const handleRevisionEvent = ({
|
|
|
462
469
|
};
|
|
463
470
|
};
|
|
464
471
|
|
|
472
|
+
const collectNamedTypes = (schema: any): string[] => {
|
|
473
|
+
if (!schema || typeof schema !== "object") return [];
|
|
474
|
+
const names: string[] = [];
|
|
475
|
+
if (schema.$kdsl?.const?.NamedType?.Name)
|
|
476
|
+
names.push(schema.$kdsl.const.NamedType.Name as string);
|
|
477
|
+
if (Array.isArray(schema.oneOf)) {
|
|
478
|
+
for (const branch of schema.oneOf) names.push(...collectNamedTypes(branch));
|
|
479
|
+
}
|
|
480
|
+
return names;
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
const namedTypeToResourceKind = (
|
|
484
|
+
namedTypes: string[],
|
|
485
|
+
): { type: string; kind?: string } => {
|
|
486
|
+
for (const name of namedTypes) {
|
|
487
|
+
switch (name) {
|
|
488
|
+
case "Secret":
|
|
489
|
+
return { type: "secret" };
|
|
490
|
+
case "Domain":
|
|
491
|
+
return { type: "domain" };
|
|
492
|
+
case "Port":
|
|
493
|
+
return { type: "port" };
|
|
494
|
+
case "Certificate":
|
|
495
|
+
return { type: "certificate" };
|
|
496
|
+
case "CA":
|
|
497
|
+
return { type: "ca" };
|
|
498
|
+
case "Volatile":
|
|
499
|
+
case "Ephemeral":
|
|
500
|
+
return { type: "volume", kind: "volatile" };
|
|
501
|
+
case "NonReplicated":
|
|
502
|
+
return { type: "volume", kind: "nonReplicated" };
|
|
503
|
+
case "Persisted":
|
|
504
|
+
case "Persistent":
|
|
505
|
+
return { type: "volume", kind: "persistent" };
|
|
506
|
+
case "Registered":
|
|
507
|
+
return { type: "volume" };
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return { type: "secret" };
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
export const extractStructuredSchema = (
|
|
514
|
+
revisionData: any,
|
|
515
|
+
): {
|
|
516
|
+
parameters: {
|
|
517
|
+
name: string;
|
|
518
|
+
type: string;
|
|
519
|
+
required: boolean;
|
|
520
|
+
defaultValue?: any;
|
|
521
|
+
}[];
|
|
522
|
+
resources: { name: string; type: string; kind?: string; required: boolean }[];
|
|
523
|
+
} => {
|
|
524
|
+
const configSchema = revisionData?.configSchema;
|
|
525
|
+
const deploymentName = revisionData?.solution?.top;
|
|
526
|
+
const deployment = deploymentName
|
|
527
|
+
? revisionData?.solution?.deployments?.[deploymentName]
|
|
528
|
+
: Object.values(revisionData?.solution?.deployments ?? {})[0];
|
|
529
|
+
|
|
530
|
+
const parameterValues: Record<string, any> =
|
|
531
|
+
(deployment as any)?.config?.parameter ?? {};
|
|
532
|
+
const requiredParams: string[] =
|
|
533
|
+
configSchema?.properties?.config?.required ?? [];
|
|
534
|
+
const requiredResources: string[] =
|
|
535
|
+
configSchema?.properties?.resource?.required ?? [];
|
|
536
|
+
const schemaConfigProps: Record<string, any> =
|
|
537
|
+
configSchema?.properties?.config?.properties ?? {};
|
|
538
|
+
const schemaResourceProps: Record<string, any> =
|
|
539
|
+
configSchema?.properties?.resource?.properties ?? {};
|
|
540
|
+
|
|
541
|
+
const parameters = Object.entries(schemaConfigProps).map(
|
|
542
|
+
([name, propSchema]) => {
|
|
543
|
+
const entry: {
|
|
544
|
+
name: string;
|
|
545
|
+
type: string;
|
|
546
|
+
required: boolean;
|
|
547
|
+
defaultValue?: any;
|
|
548
|
+
} = {
|
|
549
|
+
name,
|
|
550
|
+
type: propSchema?.type ?? "string",
|
|
551
|
+
required: requiredParams.includes(name),
|
|
552
|
+
};
|
|
553
|
+
const currentValue = parameterValues[name];
|
|
554
|
+
if (currentValue !== undefined) entry.defaultValue = currentValue;
|
|
555
|
+
else if (propSchema?.default !== undefined)
|
|
556
|
+
entry.defaultValue = propSchema.default;
|
|
557
|
+
return entry;
|
|
558
|
+
},
|
|
559
|
+
);
|
|
560
|
+
|
|
561
|
+
const resources = Object.entries(schemaResourceProps).map(
|
|
562
|
+
([name, propSchema]) => {
|
|
563
|
+
const namedTypes = collectNamedTypes(propSchema);
|
|
564
|
+
const resolved = namedTypeToResourceKind(namedTypes);
|
|
565
|
+
const entry: {
|
|
566
|
+
name: string;
|
|
567
|
+
type: string;
|
|
568
|
+
kind?: string;
|
|
569
|
+
required: boolean;
|
|
570
|
+
} = {
|
|
571
|
+
name,
|
|
572
|
+
type: resolved.type,
|
|
573
|
+
required: requiredResources.includes(name),
|
|
574
|
+
};
|
|
575
|
+
if (resolved.kind) entry.kind = resolved.kind;
|
|
576
|
+
return entry;
|
|
577
|
+
},
|
|
578
|
+
);
|
|
579
|
+
|
|
580
|
+
return { parameters, resources };
|
|
581
|
+
};
|
|
582
|
+
|
|
465
583
|
export const processRevisionData = (
|
|
466
584
|
service: Service,
|
|
467
585
|
revisionData: any,
|
|
586
|
+
revisionsMap?: Map<string, Revision>,
|
|
587
|
+
serviceId?: string,
|
|
468
588
|
): Service => {
|
|
469
589
|
const { solution } = revisionData;
|
|
470
590
|
|
|
@@ -472,6 +592,56 @@ export const processRevisionData = (
|
|
|
472
592
|
const parameters = extractParametersFromConfig(config.parameter || {});
|
|
473
593
|
const resources = extractResources(config.resource || {});
|
|
474
594
|
|
|
595
|
+
if (revisionsMap && serviceId && revisionData.revision) {
|
|
596
|
+
const revisionId: string = revisionData.revision;
|
|
597
|
+
const revisionKey = `${serviceId}-${revisionId}`;
|
|
598
|
+
const schema = extractStructuredSchema(revisionData);
|
|
599
|
+
const existing = revisionsMap.get(revisionKey);
|
|
600
|
+
if (existing) {
|
|
601
|
+
revisionsMap.set(revisionKey, { ...existing, schema });
|
|
602
|
+
} else {
|
|
603
|
+
revisionsMap.set(revisionKey, {
|
|
604
|
+
id: revisionId,
|
|
605
|
+
schema,
|
|
606
|
+
usage: {
|
|
607
|
+
current: {
|
|
608
|
+
cpu: 0,
|
|
609
|
+
memory: 0,
|
|
610
|
+
storage: 0,
|
|
611
|
+
volatileStorage: 0,
|
|
612
|
+
nonReplicatedStorage: 0,
|
|
613
|
+
persistentStorage: 0,
|
|
614
|
+
},
|
|
615
|
+
limit: {
|
|
616
|
+
cpu: { max: revisionData.intensives?.vcpu / 1000 || 0, min: 0 },
|
|
617
|
+
memory: { max: revisionData.intensives?.ram / 1000 || 0, min: 0 },
|
|
618
|
+
storage: {
|
|
619
|
+
max: revisionData.intensives?.shared_disk / 1000 || 0,
|
|
620
|
+
min: 0,
|
|
621
|
+
},
|
|
622
|
+
volatileStorage: {
|
|
623
|
+
max: revisionData.intensives?.volatile_disk / 1000 || 0,
|
|
624
|
+
min: 0,
|
|
625
|
+
},
|
|
626
|
+
nonReplicatedStorage: {
|
|
627
|
+
max: revisionData.intensives?.nrpersistent_disk / 1000 || 0,
|
|
628
|
+
min: 0,
|
|
629
|
+
},
|
|
630
|
+
persistentStorage: {
|
|
631
|
+
max: revisionData.intensives?.persistent_disk / 1000 || 0,
|
|
632
|
+
min: 0,
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
cost: 0,
|
|
636
|
+
},
|
|
637
|
+
status: { code: "", message: "", timestamp: "", args: [] },
|
|
638
|
+
errorCode: "",
|
|
639
|
+
errorMsg: "",
|
|
640
|
+
createdAt: "",
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
475
645
|
const deploymentName = solution.top || service.name;
|
|
476
646
|
const deployment = solution.deployments[deploymentName];
|
|
477
647
|
|
|
@@ -783,114 +953,3 @@ const extractResourceName = (resourcePath: string): string => {
|
|
|
783
953
|
}
|
|
784
954
|
return resourcePath;
|
|
785
955
|
};
|
|
786
|
-
|
|
787
|
-
const collectNamedTypes = (schema: any): string[] => {
|
|
788
|
-
if (!schema || typeof schema !== "object") return [];
|
|
789
|
-
const names: string[] = [];
|
|
790
|
-
if (schema.$kdsl?.const?.NamedType?.Name)
|
|
791
|
-
names.push(schema.$kdsl.const.NamedType.Name as string);
|
|
792
|
-
if (Array.isArray(schema.oneOf)) {
|
|
793
|
-
for (const branch of schema.oneOf) names.push(...collectNamedTypes(branch));
|
|
794
|
-
}
|
|
795
|
-
return names;
|
|
796
|
-
};
|
|
797
|
-
|
|
798
|
-
const namedTypeToResourceKind = (
|
|
799
|
-
namedTypes: string[],
|
|
800
|
-
): { type: string; kind?: string } => {
|
|
801
|
-
for (const name of namedTypes) {
|
|
802
|
-
switch (name) {
|
|
803
|
-
case "Secret":
|
|
804
|
-
return { type: "secret" };
|
|
805
|
-
case "Domain":
|
|
806
|
-
return { type: "domain" };
|
|
807
|
-
case "Port":
|
|
808
|
-
return { type: "port" };
|
|
809
|
-
case "Certificate":
|
|
810
|
-
return { type: "certificate" };
|
|
811
|
-
case "CA":
|
|
812
|
-
return { type: "ca" };
|
|
813
|
-
case "Volatile":
|
|
814
|
-
case "Ephemeral":
|
|
815
|
-
return { type: "volume", kind: "volatile" };
|
|
816
|
-
case "NonReplicated":
|
|
817
|
-
return { type: "volume", kind: "nonReplicated" };
|
|
818
|
-
case "Persisted":
|
|
819
|
-
case "Persistent":
|
|
820
|
-
return { type: "volume", kind: "persistent" };
|
|
821
|
-
case "Registered":
|
|
822
|
-
return { type: "volume" };
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
return { type: "secret" };
|
|
826
|
-
};
|
|
827
|
-
|
|
828
|
-
export const extractStructuredSchema = (
|
|
829
|
-
revisionData: any,
|
|
830
|
-
): {
|
|
831
|
-
parameters: {
|
|
832
|
-
name: string;
|
|
833
|
-
type: string;
|
|
834
|
-
required: boolean;
|
|
835
|
-
defaultValue?: any;
|
|
836
|
-
}[];
|
|
837
|
-
resources: { name: string; type: string; kind?: string; required: boolean }[];
|
|
838
|
-
} => {
|
|
839
|
-
const configSchema = revisionData?.configSchema;
|
|
840
|
-
const deploymentName = revisionData?.solution?.top;
|
|
841
|
-
const deployment = deploymentName
|
|
842
|
-
? revisionData?.solution?.deployments?.[deploymentName]
|
|
843
|
-
: Object.values(revisionData?.solution?.deployments ?? {})[0];
|
|
844
|
-
|
|
845
|
-
const parameterValues: Record<string, any> =
|
|
846
|
-
(deployment as any)?.config?.parameter ?? {};
|
|
847
|
-
const requiredParams: string[] =
|
|
848
|
-
configSchema?.properties?.config?.required ?? [];
|
|
849
|
-
const requiredResources: string[] =
|
|
850
|
-
configSchema?.properties?.resource?.required ?? [];
|
|
851
|
-
const schemaConfigProps: Record<string, any> =
|
|
852
|
-
configSchema?.properties?.config?.properties ?? {};
|
|
853
|
-
const schemaResourceProps: Record<string, any> =
|
|
854
|
-
configSchema?.properties?.resource?.properties ?? {};
|
|
855
|
-
|
|
856
|
-
const parameters = Object.entries(schemaConfigProps).map(
|
|
857
|
-
([name, propSchema]) => {
|
|
858
|
-
const entry: {
|
|
859
|
-
name: string;
|
|
860
|
-
type: string;
|
|
861
|
-
required: boolean;
|
|
862
|
-
defaultValue?: any;
|
|
863
|
-
} = {
|
|
864
|
-
name,
|
|
865
|
-
type: propSchema?.type ?? "string",
|
|
866
|
-
required: requiredParams.includes(name),
|
|
867
|
-
};
|
|
868
|
-
const currentValue = parameterValues[name];
|
|
869
|
-
if (currentValue !== undefined) entry.defaultValue = currentValue;
|
|
870
|
-
else if (propSchema?.default !== undefined)
|
|
871
|
-
entry.defaultValue = propSchema.default;
|
|
872
|
-
return entry;
|
|
873
|
-
},
|
|
874
|
-
);
|
|
875
|
-
|
|
876
|
-
const resources = Object.entries(schemaResourceProps).map(
|
|
877
|
-
([name, propSchema]) => {
|
|
878
|
-
const namedTypes = collectNamedTypes(propSchema);
|
|
879
|
-
const resolved = namedTypeToResourceKind(namedTypes);
|
|
880
|
-
const entry: {
|
|
881
|
-
name: string;
|
|
882
|
-
type: string;
|
|
883
|
-
kind?: string;
|
|
884
|
-
required: boolean;
|
|
885
|
-
} = {
|
|
886
|
-
name,
|
|
887
|
-
type: resolved.type,
|
|
888
|
-
required: requiredResources.includes(name),
|
|
889
|
-
};
|
|
890
|
-
if (resolved.kind) entry.kind = resolved.kind;
|
|
891
|
-
return entry;
|
|
892
|
-
},
|
|
893
|
-
);
|
|
894
|
-
|
|
895
|
-
return { parameters, resources };
|
|
896
|
-
};
|
package/package.json
CHANGED
package/websocket-manager.ts
CHANGED
|
@@ -1218,6 +1218,8 @@ const handleOperationSuccess = (operation: PendingOperation, response: any) => {
|
|
|
1218
1218
|
const updatedService = processRevisionData(
|
|
1219
1219
|
svcSuccessResult.updatedService!,
|
|
1220
1220
|
svcSuccessResult.revisionData,
|
|
1221
|
+
revisionsMap,
|
|
1222
|
+
svcSuccessResult.serviceId,
|
|
1221
1223
|
);
|
|
1222
1224
|
|
|
1223
1225
|
if (svcSuccessResult.revisionData.revision_error) {
|