@serve.zone/interfaces 12.0.0 → 13.0.1
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/changelog.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-07-19 - 13.0.1
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
- classify non-string preflight fence fields as invalid transport input (deployment)
|
|
8
|
+
|
|
9
|
+
## 2026-07-19 - 13.0.0
|
|
10
|
+
|
|
11
|
+
### Breaking Changes
|
|
12
|
+
|
|
13
|
+
- bind greenfield preflight to a sanitized candidate configuration (deployment)
|
|
14
|
+
- Derive namespace and storage resource names in Cloudly instead of accepting caller-selected cluster names.
|
|
15
|
+
- Require an explicit completeness marker and secret-reference identifiers without secret values.
|
|
16
|
+
- Reject malformed transport digests, release tags, and log-unsafe request identifiers deterministically.
|
|
17
|
+
|
|
3
18
|
## 2026-07-19 - 12.0.0
|
|
4
19
|
|
|
5
20
|
### Fixes
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/interfaces',
|
|
6
|
-
version: '
|
|
6
|
+
version: '13.0.1',
|
|
7
7
|
description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHVGQUF1RjtDQUNyRyxDQUFBIn0=
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TOciManifestMediaType, TSha256Digest } from './immutableimage.js';
|
|
2
2
|
import type { TServiceDeploymentCapability } from './user.js';
|
|
3
3
|
export type TDeploymentPreflightDecision = 'GO' | 'NO-GO';
|
|
4
|
-
export type TDeploymentPreflightBlockerCode = 'INVALID_REQUEST' | 'AUTHORIZATION_MISSING' | 'SOURCE_REVISION_INVALID' | 'SOURCE_WORKTREE_DIRTY' | 'VERSION_NOT_RESERVED' | 'VERSION_COLLISION' | 'NAMESPACE_NOT_RESERVED' | 'NAMESPACE_COLLISION' | 'NAMESPACE_NOT_PROVEN_BLANK' | 'CONFIGURATION_DIGEST_INVALID' | 'INTENT_DIGEST_INVALID' | 'CURRENT_REFERENCE_MUTABLE' | 'CURRENT_RUNTIME_DIGEST_MISSING' | 'OCI_INDEX_DIGEST_REQUIRED' | 'OCI_INDEX_NOT_FOUND' | 'OCI_INDEX_MEDIA_TYPE_REQUIRED' | 'OCI_PLATFORM_MISSING' | 'OCI_PLATFORM_MANIFEST_MISSING' | 'IMMUTABLE_RELEASE_TAG_REQUIRED' | 'IMMUTABLE_RELEASE_TAG_NOT_RESERVED' | 'RELEASE_EVIDENCE_MISSING' | 'RELEASE_EVIDENCE_INVALID' | 'RELEASE_NOT_AUTHORIZED' | 'GREENFIELD_EXECUTION_UNAVAILABLE' | 'ROUTE_PROMOTION_FENCE_UNAVAILABLE' | 'POST_DEPLOYMENT_VERIFICATION_UNAVAILABLE' | 'WOULD_REPLACE_EXISTING_STATE' | 'CORESTORE_INVENTORY_UNAVAILABLE' | 'RUNTIME_ATTESTATION_MISMATCH';
|
|
4
|
+
export type TDeploymentPreflightBlockerCode = 'INVALID_REQUEST' | 'AUTHORIZATION_MISSING' | 'SOURCE_REVISION_INVALID' | 'SOURCE_WORKTREE_DIRTY' | 'VERSION_NOT_RESERVED' | 'VERSION_COLLISION' | 'NAMESPACE_NOT_RESERVED' | 'NAMESPACE_COLLISION' | 'NAMESPACE_NOT_PROVEN_BLANK' | 'CONFIGURATION_DIGEST_INVALID' | 'INTENT_DIGEST_INVALID' | 'PROPOSED_CONFIGURATION_INCOMPLETE' | 'CURRENT_REFERENCE_MUTABLE' | 'CURRENT_RUNTIME_DIGEST_MISSING' | 'OCI_INDEX_DIGEST_REQUIRED' | 'OCI_INDEX_NOT_FOUND' | 'OCI_INDEX_MEDIA_TYPE_REQUIRED' | 'OCI_PLATFORM_MISSING' | 'OCI_PLATFORM_MANIFEST_MISSING' | 'IMMUTABLE_RELEASE_TAG_REQUIRED' | 'IMMUTABLE_RELEASE_TAG_NOT_RESERVED' | 'RELEASE_EVIDENCE_MISSING' | 'RELEASE_EVIDENCE_INVALID' | 'RELEASE_NOT_AUTHORIZED' | 'GREENFIELD_EXECUTION_UNAVAILABLE' | 'ROUTE_PROMOTION_FENCE_UNAVAILABLE' | 'POST_DEPLOYMENT_VERIFICATION_UNAVAILABLE' | 'WOULD_REPLACE_EXISTING_STATE' | 'CORESTORE_INVENTORY_UNAVAILABLE' | 'RUNTIME_ATTESTATION_MISMATCH';
|
|
5
5
|
export interface IDeploymentPreflightBlocker {
|
|
6
6
|
code: TDeploymentPreflightBlockerCode;
|
|
7
7
|
message: string;
|
|
@@ -41,6 +41,28 @@ export interface IDeploymentPreflightProposedCorestoreResource {
|
|
|
41
41
|
capability: 'database' | 'objectstorage';
|
|
42
42
|
resourceName: string;
|
|
43
43
|
}
|
|
44
|
+
export interface IDeploymentPreflightProposedVolumeMount {
|
|
45
|
+
mountPath: string;
|
|
46
|
+
storageClass: 'corestore' | 'ephemeral';
|
|
47
|
+
capability?: 'database' | 'objectstorage';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Secret-free candidate configuration declared by the source checkout.
|
|
51
|
+
* Cloudly derives namespace and resource names; callers may not probe arbitrary
|
|
52
|
+
* cluster names through this contract.
|
|
53
|
+
*/
|
|
54
|
+
export interface IDeploymentPreflightProposedConfiguration {
|
|
55
|
+
schemaVersion: 1;
|
|
56
|
+
declarationComplete: boolean;
|
|
57
|
+
projectName: string;
|
|
58
|
+
targetPlatforms: string[];
|
|
59
|
+
publicDomains: string[];
|
|
60
|
+
environmentVariableNames: string[];
|
|
61
|
+
secretReferenceIds: string[];
|
|
62
|
+
containerPorts: number[];
|
|
63
|
+
volumeMounts: IDeploymentPreflightProposedVolumeMount[];
|
|
64
|
+
requiredCapabilities: Array<'database' | 'objectstorage'>;
|
|
65
|
+
}
|
|
44
66
|
export interface IDeploymentReleaseEvidenceReference {
|
|
45
67
|
kind: 'provenance' | 'sbom' | 'signature' | 'vulnerability-policy' | 'release-authorization';
|
|
46
68
|
statementDigest: TSha256Digest;
|
|
@@ -64,8 +86,7 @@ export interface IDeploymentPreflightRequestData {
|
|
|
64
86
|
sourceDirty: boolean;
|
|
65
87
|
version: string;
|
|
66
88
|
intentDigest: string;
|
|
67
|
-
|
|
68
|
-
proposedCorestoreResources: IDeploymentPreflightProposedCorestoreResource[];
|
|
89
|
+
proposedConfiguration: IDeploymentPreflightProposedConfiguration;
|
|
69
90
|
ociIndexDigest?: string;
|
|
70
91
|
releaseTag?: string;
|
|
71
92
|
releaseEvidence?: IDeploymentReleaseEvidence;
|
|
@@ -118,6 +139,7 @@ export interface IDeploymentPreflightReport {
|
|
|
118
139
|
corestoreResources: IDeploymentPreflightCorestoreResource[];
|
|
119
140
|
proposed: {
|
|
120
141
|
namespace: string;
|
|
142
|
+
configuration: IDeploymentPreflightProposedConfiguration;
|
|
121
143
|
corestoreResources: IDeploymentPreflightProposedCorestoreResource[];
|
|
122
144
|
namespaceReserved: boolean;
|
|
123
145
|
inventoryComplete: boolean;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { normalizeSha256Digest } from './immutableimage.js';
|
|
2
2
|
const fullGitRevisionRegex = /^[a-f0-9]{40}$/;
|
|
3
|
-
const namespaceRegex = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
4
3
|
const semanticVersionRegex = /^(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)(?:-(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
5
4
|
const requiredEvidenceKinds = new Set([
|
|
6
5
|
'provenance',
|
|
@@ -15,7 +14,9 @@ export const validateDeploymentPreflightRequest = (requestArg) => {
|
|
|
15
14
|
if (!isRecord(requestArg)) {
|
|
16
15
|
return [{ code: 'INVALID_REQUEST', message: 'Deployment preflight request must be an object.' }];
|
|
17
16
|
}
|
|
18
|
-
if (typeof requestArg.requestId !== 'string'
|
|
17
|
+
if (typeof requestArg.requestId !== 'string'
|
|
18
|
+
|| requestArg.requestId.length > 200
|
|
19
|
+
|| !/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(requestArg.requestId)) {
|
|
19
20
|
blockers.push({ code: 'INVALID_REQUEST', message: 'A bounded request identifier is required.' });
|
|
20
21
|
}
|
|
21
22
|
if (typeof requestArg.serviceId !== 'string' || !requestArg.serviceId.trim() || requestArg.serviceId.length > 200) {
|
|
@@ -23,6 +24,9 @@ export const validateDeploymentPreflightRequest = (requestArg) => {
|
|
|
23
24
|
}
|
|
24
25
|
if (typeof requestArg.sourceRevision !== 'string' || !fullGitRevisionRegex.test(requestArg.sourceRevision)) {
|
|
25
26
|
blockers.push({ code: 'SOURCE_REVISION_INVALID', message: 'Source revision must be a full lower-case Git commit SHA.' });
|
|
27
|
+
if (typeof requestArg.sourceRevision !== 'string') {
|
|
28
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'Source revision is malformed.' });
|
|
29
|
+
}
|
|
26
30
|
}
|
|
27
31
|
if (typeof requestArg.sourceDirty !== 'boolean') {
|
|
28
32
|
blockers.push({ code: 'INVALID_REQUEST', message: 'Source worktree state must be reported.' });
|
|
@@ -34,33 +38,66 @@ export const validateDeploymentPreflightRequest = (requestArg) => {
|
|
|
34
38
|
|| requestArg.version.length > 100
|
|
35
39
|
|| !semanticVersionRegex.test(requestArg.version)) {
|
|
36
40
|
blockers.push({ code: 'VERSION_NOT_RESERVED', message: 'A canonical semantic release version is required.' });
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
if (typeof requestArg.version !== 'string') {
|
|
42
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'Release version is malformed.' });
|
|
43
|
+
}
|
|
40
44
|
}
|
|
41
45
|
if (typeof requestArg.intentDigest !== 'string' || !normalizeSha256Digest(requestArg.intentDigest)) {
|
|
42
46
|
blockers.push({ code: 'INTENT_DIGEST_INVALID', message: 'Deployment intent digest must be a canonical sha256 digest.' });
|
|
47
|
+
if (typeof requestArg.intentDigest !== 'string') {
|
|
48
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'Deployment intent digest is malformed.' });
|
|
49
|
+
}
|
|
43
50
|
}
|
|
44
|
-
const
|
|
45
|
-
? requestArg.
|
|
46
|
-
:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
.
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
const configuration = isRecord(requestArg.proposedConfiguration)
|
|
52
|
+
? requestArg.proposedConfiguration
|
|
53
|
+
: undefined;
|
|
54
|
+
const stringArrayValid = (valueArg, maxItemsArg, patternArg) => Array.isArray(valueArg)
|
|
55
|
+
&& valueArg.length <= maxItemsArg
|
|
56
|
+
&& valueArg.every((itemArg) => typeof itemArg === 'string'
|
|
57
|
+
&& itemArg.length > 0
|
|
58
|
+
&& itemArg.length <= 253
|
|
59
|
+
&& patternArg.test(itemArg))
|
|
60
|
+
&& new Set(valueArg).size === valueArg.length;
|
|
61
|
+
const capabilities = configuration?.requiredCapabilities;
|
|
62
|
+
const volumeMounts = configuration?.volumeMounts;
|
|
63
|
+
if (!configuration
|
|
64
|
+
|| configuration.schemaVersion !== 1
|
|
65
|
+
|| typeof configuration.declarationComplete !== 'boolean'
|
|
66
|
+
|| typeof configuration.projectName !== 'string'
|
|
67
|
+
|| !configuration.projectName.trim()
|
|
68
|
+
|| configuration.projectName.length > 200
|
|
69
|
+
|| !stringArrayValid(configuration.targetPlatforms, 8, /^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/)
|
|
70
|
+
|| !stringArrayValid(configuration.publicDomains, 32, /^[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$/)
|
|
71
|
+
|| !stringArrayValid(configuration.environmentVariableNames, 256, /^[A-Z_][A-Z0-9_]*$/)
|
|
72
|
+
|| !stringArrayValid(configuration.secretReferenceIds, 64, /^[A-Za-z0-9][A-Za-z0-9:._-]*$/)
|
|
73
|
+
|| !Array.isArray(configuration.containerPorts)
|
|
74
|
+
|| configuration.containerPorts.length > 64
|
|
75
|
+
|| configuration.containerPorts.some((portArg) => !Number.isSafeInteger(portArg) || portArg < 1 || portArg > 65535)
|
|
76
|
+
|| new Set(configuration.containerPorts).size !== configuration.containerPorts.length
|
|
77
|
+
|| !Array.isArray(volumeMounts)
|
|
78
|
+
|| volumeMounts.length > 32
|
|
79
|
+
|| volumeMounts.some((mountArg) => !isRecord(mountArg)
|
|
80
|
+
|| typeof mountArg.mountPath !== 'string'
|
|
81
|
+
|| !/^\/[A-Za-z0-9._/-]{0,254}$/.test(mountArg.mountPath)
|
|
82
|
+
|| (mountArg.storageClass !== 'corestore' && mountArg.storageClass !== 'ephemeral')
|
|
83
|
+
|| (mountArg.capability !== undefined
|
|
84
|
+
&& mountArg.capability !== 'database'
|
|
85
|
+
&& mountArg.capability !== 'objectstorage'))
|
|
86
|
+
|| !Array.isArray(capabilities)
|
|
87
|
+
|| capabilities.length > 2
|
|
88
|
+
|| capabilities.some((capabilityArg) => capabilityArg !== 'database' && capabilityArg !== 'objectstorage')
|
|
89
|
+
|| new Set(capabilities).size !== capabilities.length) {
|
|
90
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'The proposed deployment configuration is malformed.' });
|
|
60
91
|
}
|
|
61
92
|
if (requestArg.ociIndexDigest !== undefined
|
|
62
93
|
&& (typeof requestArg.ociIndexDigest !== 'string' || !normalizeSha256Digest(requestArg.ociIndexDigest))) {
|
|
63
94
|
blockers.push({ code: 'OCI_INDEX_DIGEST_REQUIRED', message: 'OCI index digest must be a canonical sha256 digest.' });
|
|
95
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'OCI index digest is malformed.' });
|
|
96
|
+
}
|
|
97
|
+
if (requestArg.releaseTag !== undefined
|
|
98
|
+
&& (typeof requestArg.releaseTag !== 'string'
|
|
99
|
+
|| !/^[A-Za-z0-9_][A-Za-z0-9._-]{0,127}$/.test(requestArg.releaseTag))) {
|
|
100
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'Release tag is malformed.' });
|
|
64
101
|
}
|
|
65
102
|
if (requestArg.greenfield !== true) {
|
|
66
103
|
blockers.push({ code: 'WOULD_REPLACE_EXISTING_STATE', message: 'Only greenfield deployment preflight is supported.' });
|
|
@@ -116,4 +153,4 @@ export const validateDeploymentReleaseEvidence = (argsArg) => {
|
|
|
116
153
|
}
|
|
117
154
|
return blockers;
|
|
118
155
|
};
|
|
119
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95bWVudHByZWZsaWdodC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2RhdGEvZGVwbG95bWVudHByZWZsaWdodC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQStNNUQsTUFBTSxvQkFBb0IsR0FBRyxnQkFBZ0IsQ0FBQztBQUM5QyxNQUFNLGNBQWMsR0FBRyx3Q0FBd0MsQ0FBQztBQUNoRSxNQUFNLG9CQUFvQixHQUFHLDRNQUE0TSxDQUFDO0FBQzFPLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxHQUFHLENBQThDO0lBQ2pGLFlBQVk7SUFDWixNQUFNO0lBQ04sV0FBVztJQUNYLHNCQUFzQjtJQUN0Qix1QkFBdUI7Q0FDeEIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxRQUFRLEdBQUcsQ0FBQyxRQUFpQixFQUF1QyxFQUFFLENBQzFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRWhGLE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLENBQ2hELFVBQW1CLEVBQ1ksRUFBRTtJQUNqQyxNQUFNLFFBQVEsR0FBa0MsRUFBRSxDQUFDO0lBQ25ELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUMxQixPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLGlEQUFpRCxFQUFFLENBQUMsQ0FBQztJQUNuRyxDQUFDO0lBQ0QsSUFBSSxPQUFPLFVBQVUsQ0FBQyxTQUFTLEtBQUssUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUNsSCxRQUFRLENBQUMsSUFB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
|
|
156
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95bWVudHByZWZsaWdodC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2RhdGEvZGVwbG95bWVudHByZWZsaWdodC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQXdPNUQsTUFBTSxvQkFBb0IsR0FBRyxnQkFBZ0IsQ0FBQztBQUM5QyxNQUFNLG9CQUFvQixHQUFHLDRNQUE0TSxDQUFDO0FBQzFPLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxHQUFHLENBQThDO0lBQ2pGLFlBQVk7SUFDWixNQUFNO0lBQ04sV0FBVztJQUNYLHNCQUFzQjtJQUN0Qix1QkFBdUI7Q0FDeEIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxRQUFRLEdBQUcsQ0FBQyxRQUFpQixFQUF1QyxFQUFFLENBQzFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRWhGLE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLENBQ2hELFVBQW1CLEVBQ1ksRUFBRTtJQUNqQyxNQUFNLFFBQVEsR0FBa0MsRUFBRSxDQUFDO0lBQ25ELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUMxQixPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLGlEQUFpRCxFQUFFLENBQUMsQ0FBQztJQUNuRyxDQUFDO0lBQ0QsSUFBSSxPQUFPLFVBQVUsQ0FBQyxTQUFTLEtBQUssUUFBUTtXQUN2QyxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxHQUFHO1dBQ2pDLENBQUMsK0JBQStCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ2pFLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVB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
|
package/package.json
CHANGED
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -19,6 +19,7 @@ export type TDeploymentPreflightBlockerCode =
|
|
|
19
19
|
| 'NAMESPACE_NOT_PROVEN_BLANK'
|
|
20
20
|
| 'CONFIGURATION_DIGEST_INVALID'
|
|
21
21
|
| 'INTENT_DIGEST_INVALID'
|
|
22
|
+
| 'PROPOSED_CONFIGURATION_INCOMPLETE'
|
|
22
23
|
| 'CURRENT_REFERENCE_MUTABLE'
|
|
23
24
|
| 'CURRENT_RUNTIME_DIGEST_MISSING'
|
|
24
25
|
| 'OCI_INDEX_DIGEST_REQUIRED'
|
|
@@ -84,6 +85,30 @@ export interface IDeploymentPreflightProposedCorestoreResource {
|
|
|
84
85
|
resourceName: string;
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
export interface IDeploymentPreflightProposedVolumeMount {
|
|
89
|
+
mountPath: string;
|
|
90
|
+
storageClass: 'corestore' | 'ephemeral';
|
|
91
|
+
capability?: 'database' | 'objectstorage';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Secret-free candidate configuration declared by the source checkout.
|
|
96
|
+
* Cloudly derives namespace and resource names; callers may not probe arbitrary
|
|
97
|
+
* cluster names through this contract.
|
|
98
|
+
*/
|
|
99
|
+
export interface IDeploymentPreflightProposedConfiguration {
|
|
100
|
+
schemaVersion: 1;
|
|
101
|
+
declarationComplete: boolean;
|
|
102
|
+
projectName: string;
|
|
103
|
+
targetPlatforms: string[];
|
|
104
|
+
publicDomains: string[];
|
|
105
|
+
environmentVariableNames: string[];
|
|
106
|
+
secretReferenceIds: string[];
|
|
107
|
+
containerPorts: number[];
|
|
108
|
+
volumeMounts: IDeploymentPreflightProposedVolumeMount[];
|
|
109
|
+
requiredCapabilities: Array<'database' | 'objectstorage'>;
|
|
110
|
+
}
|
|
111
|
+
|
|
87
112
|
export interface IDeploymentReleaseEvidenceReference {
|
|
88
113
|
kind: 'provenance' | 'sbom' | 'signature' | 'vulnerability-policy' | 'release-authorization';
|
|
89
114
|
statementDigest: TSha256Digest;
|
|
@@ -109,8 +134,7 @@ export interface IDeploymentPreflightRequestData {
|
|
|
109
134
|
sourceDirty: boolean;
|
|
110
135
|
version: string;
|
|
111
136
|
intentDigest: string;
|
|
112
|
-
|
|
113
|
-
proposedCorestoreResources: IDeploymentPreflightProposedCorestoreResource[];
|
|
137
|
+
proposedConfiguration: IDeploymentPreflightProposedConfiguration;
|
|
114
138
|
ociIndexDigest?: string;
|
|
115
139
|
releaseTag?: string;
|
|
116
140
|
releaseEvidence?: IDeploymentReleaseEvidence;
|
|
@@ -164,6 +188,7 @@ export interface IDeploymentPreflightReport {
|
|
|
164
188
|
corestoreResources: IDeploymentPreflightCorestoreResource[];
|
|
165
189
|
proposed: {
|
|
166
190
|
namespace: string;
|
|
191
|
+
configuration: IDeploymentPreflightProposedConfiguration;
|
|
167
192
|
corestoreResources: IDeploymentPreflightProposedCorestoreResource[];
|
|
168
193
|
namespaceReserved: boolean;
|
|
169
194
|
inventoryComplete: boolean;
|
|
@@ -210,7 +235,6 @@ export interface IGreenfieldDeploymentOperation {
|
|
|
210
235
|
}
|
|
211
236
|
|
|
212
237
|
const fullGitRevisionRegex = /^[a-f0-9]{40}$/;
|
|
213
|
-
const namespaceRegex = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
214
238
|
const semanticVersionRegex = /^(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)(?:-(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
215
239
|
const requiredEvidenceKinds = new Set<IDeploymentReleaseEvidenceReference['kind']>([
|
|
216
240
|
'provenance',
|
|
@@ -230,7 +254,9 @@ export const validateDeploymentPreflightRequest = (
|
|
|
230
254
|
if (!isRecord(requestArg)) {
|
|
231
255
|
return [{ code: 'INVALID_REQUEST', message: 'Deployment preflight request must be an object.' }];
|
|
232
256
|
}
|
|
233
|
-
if (typeof requestArg.requestId !== 'string'
|
|
257
|
+
if (typeof requestArg.requestId !== 'string'
|
|
258
|
+
|| requestArg.requestId.length > 200
|
|
259
|
+
|| !/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(requestArg.requestId)) {
|
|
234
260
|
blockers.push({ code: 'INVALID_REQUEST', message: 'A bounded request identifier is required.' });
|
|
235
261
|
}
|
|
236
262
|
if (typeof requestArg.serviceId !== 'string' || !requestArg.serviceId.trim() || requestArg.serviceId.length > 200) {
|
|
@@ -238,6 +264,9 @@ export const validateDeploymentPreflightRequest = (
|
|
|
238
264
|
}
|
|
239
265
|
if (typeof requestArg.sourceRevision !== 'string' || !fullGitRevisionRegex.test(requestArg.sourceRevision)) {
|
|
240
266
|
blockers.push({ code: 'SOURCE_REVISION_INVALID', message: 'Source revision must be a full lower-case Git commit SHA.' });
|
|
267
|
+
if (typeof requestArg.sourceRevision !== 'string') {
|
|
268
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'Source revision is malformed.' });
|
|
269
|
+
}
|
|
241
270
|
}
|
|
242
271
|
if (typeof requestArg.sourceDirty !== 'boolean') {
|
|
243
272
|
blockers.push({ code: 'INVALID_REQUEST', message: 'Source worktree state must be reported.' });
|
|
@@ -248,35 +277,72 @@ export const validateDeploymentPreflightRequest = (
|
|
|
248
277
|
|| requestArg.version.length > 100
|
|
249
278
|
|| !semanticVersionRegex.test(requestArg.version)) {
|
|
250
279
|
blockers.push({ code: 'VERSION_NOT_RESERVED', message: 'A canonical semantic release version is required.' });
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
280
|
+
if (typeof requestArg.version !== 'string') {
|
|
281
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'Release version is malformed.' });
|
|
282
|
+
}
|
|
254
283
|
}
|
|
255
284
|
if (typeof requestArg.intentDigest !== 'string' || !normalizeSha256Digest(requestArg.intentDigest)) {
|
|
256
285
|
blockers.push({ code: 'INTENT_DIGEST_INVALID', message: 'Deployment intent digest must be a canonical sha256 digest.' });
|
|
286
|
+
if (typeof requestArg.intentDigest !== 'string') {
|
|
287
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'Deployment intent digest is malformed.' });
|
|
288
|
+
}
|
|
257
289
|
}
|
|
258
|
-
const
|
|
259
|
-
? requestArg.
|
|
260
|
-
:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (
|
|
275
|
-
|
|
290
|
+
const configuration = isRecord(requestArg.proposedConfiguration)
|
|
291
|
+
? requestArg.proposedConfiguration
|
|
292
|
+
: undefined;
|
|
293
|
+
const stringArrayValid = (
|
|
294
|
+
valueArg: unknown,
|
|
295
|
+
maxItemsArg: number,
|
|
296
|
+
patternArg: RegExp,
|
|
297
|
+
): valueArg is string[] => Array.isArray(valueArg)
|
|
298
|
+
&& valueArg.length <= maxItemsArg
|
|
299
|
+
&& valueArg.every((itemArg) => typeof itemArg === 'string'
|
|
300
|
+
&& itemArg.length > 0
|
|
301
|
+
&& itemArg.length <= 253
|
|
302
|
+
&& patternArg.test(itemArg))
|
|
303
|
+
&& new Set(valueArg).size === valueArg.length;
|
|
304
|
+
const capabilities = configuration?.requiredCapabilities;
|
|
305
|
+
const volumeMounts = configuration?.volumeMounts;
|
|
306
|
+
if (
|
|
307
|
+
!configuration
|
|
308
|
+
|| configuration.schemaVersion !== 1
|
|
309
|
+
|| typeof configuration.declarationComplete !== 'boolean'
|
|
310
|
+
|| typeof configuration.projectName !== 'string'
|
|
311
|
+
|| !configuration.projectName.trim()
|
|
312
|
+
|| configuration.projectName.length > 200
|
|
313
|
+
|| !stringArrayValid(configuration.targetPlatforms, 8, /^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/)
|
|
314
|
+
|| !stringArrayValid(configuration.publicDomains, 32, /^[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$/)
|
|
315
|
+
|| !stringArrayValid(configuration.environmentVariableNames, 256, /^[A-Z_][A-Z0-9_]*$/)
|
|
316
|
+
|| !stringArrayValid(configuration.secretReferenceIds, 64, /^[A-Za-z0-9][A-Za-z0-9:._-]*$/)
|
|
317
|
+
|| !Array.isArray(configuration.containerPorts)
|
|
318
|
+
|| configuration.containerPorts.length > 64
|
|
319
|
+
|| configuration.containerPorts.some((portArg) => !Number.isSafeInteger(portArg) || portArg < 1 || portArg > 65535)
|
|
320
|
+
|| new Set(configuration.containerPorts).size !== configuration.containerPorts.length
|
|
321
|
+
|| !Array.isArray(volumeMounts)
|
|
322
|
+
|| volumeMounts.length > 32
|
|
323
|
+
|| volumeMounts.some((mountArg) => !isRecord(mountArg)
|
|
324
|
+
|| typeof mountArg.mountPath !== 'string'
|
|
325
|
+
|| !/^\/[A-Za-z0-9._/-]{0,254}$/.test(mountArg.mountPath)
|
|
326
|
+
|| (mountArg.storageClass !== 'corestore' && mountArg.storageClass !== 'ephemeral')
|
|
327
|
+
|| (mountArg.capability !== undefined
|
|
328
|
+
&& mountArg.capability !== 'database'
|
|
329
|
+
&& mountArg.capability !== 'objectstorage'))
|
|
330
|
+
|| !Array.isArray(capabilities)
|
|
331
|
+
|| capabilities.length > 2
|
|
332
|
+
|| capabilities.some((capabilityArg) => capabilityArg !== 'database' && capabilityArg !== 'objectstorage')
|
|
333
|
+
|| new Set(capabilities).size !== capabilities.length
|
|
334
|
+
) {
|
|
335
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'The proposed deployment configuration is malformed.' });
|
|
276
336
|
}
|
|
277
337
|
if (requestArg.ociIndexDigest !== undefined
|
|
278
338
|
&& (typeof requestArg.ociIndexDigest !== 'string' || !normalizeSha256Digest(requestArg.ociIndexDigest))) {
|
|
279
339
|
blockers.push({ code: 'OCI_INDEX_DIGEST_REQUIRED', message: 'OCI index digest must be a canonical sha256 digest.' });
|
|
340
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'OCI index digest is malformed.' });
|
|
341
|
+
}
|
|
342
|
+
if (requestArg.releaseTag !== undefined
|
|
343
|
+
&& (typeof requestArg.releaseTag !== 'string'
|
|
344
|
+
|| !/^[A-Za-z0-9_][A-Za-z0-9._-]{0,127}$/.test(requestArg.releaseTag))) {
|
|
345
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'Release tag is malformed.' });
|
|
280
346
|
}
|
|
281
347
|
if (requestArg.greenfield !== true) {
|
|
282
348
|
blockers.push({ code: 'WOULD_REPLACE_EXISTING_STATE', message: 'Only greenfield deployment preflight is supported.' });
|