@fabrika/provider-zerops 0.0.15 → 0.0.16
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/package.json +5 -5
- package/src/index.ts +2 -0
- package/src/namespace.ts +46 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabrika/provider-zerops",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"gen:schema": "bun scripts/generate-zerops-types.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@fabrika/auth": "^0.0.
|
|
36
|
-
"@fabrika/auth-core": "^0.0.
|
|
37
|
-
"@fabrika/provider-contract": "^0.0.
|
|
38
|
-
"@fabrika/proxy-contract": "^0.0.
|
|
35
|
+
"@fabrika/auth": "^0.0.16",
|
|
36
|
+
"@fabrika/auth-core": "^0.0.16",
|
|
37
|
+
"@fabrika/provider-contract": "^0.0.16",
|
|
38
|
+
"@fabrika/proxy-contract": "^0.0.16"
|
|
39
39
|
}
|
|
40
40
|
}
|
package/src/index.ts
CHANGED
|
@@ -69,6 +69,7 @@ export {
|
|
|
69
69
|
compileZeropsNamespaceTopology,
|
|
70
70
|
createZeropsNamespaceCapabilities,
|
|
71
71
|
createZeropsNamespaceOperator,
|
|
72
|
+
ensureNamespaceProxyIam,
|
|
72
73
|
ZEROPS_NAMESPACE_IAM_ISSUER_VARIABLE,
|
|
73
74
|
ZEROPS_NAMESPACE_IAM_KEY_VARIABLE,
|
|
74
75
|
ZEROPS_NAMESPACE_POSTGRES_HOSTNAME,
|
|
@@ -78,6 +79,7 @@ export {
|
|
|
78
79
|
zeropsNamespaceTargetCodec,
|
|
79
80
|
} from './namespace'
|
|
80
81
|
export type {
|
|
82
|
+
NamespaceProxyIamInput,
|
|
81
83
|
ZeropsNamespaceOperatorOptions,
|
|
82
84
|
ZeropsNamespaceOptions,
|
|
83
85
|
ZeropsNamespacePlanOptions,
|
package/src/namespace.ts
CHANGED
|
@@ -737,6 +737,47 @@ const resolveServices = async (
|
|
|
737
737
|
return postgres === null ? { proxy } : { proxy, postgres }
|
|
738
738
|
}
|
|
739
739
|
|
|
740
|
+
export interface NamespaceProxyIamInput {
|
|
741
|
+
readonly api: Pick<ZeropsApi, 'listServiceEnv' | 'putServiceEnv'>
|
|
742
|
+
readonly proxyServiceId: string
|
|
743
|
+
/** The public IAM origin the proxy compares a token's `iss` against. */
|
|
744
|
+
readonly iamUrl: string
|
|
745
|
+
readonly iamKey: string
|
|
746
|
+
readonly signal: AbortSignal
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Converge the two variables the namespace proxy's own CODE reads, and call this from everywhere that
|
|
751
|
+
* code is replaced — not only where the namespace is created.
|
|
752
|
+
*
|
|
753
|
+
* `syncZeropsProxy` rebuilds the proxy from git on every app deploy, so a proxy can take new code
|
|
754
|
+
* whose configuration nobody rewrote. That is not hypothetical: the `FABRIKA_IAM_URL` →
|
|
755
|
+
* `FABRIKA_IAM_ISSUER` rename ([ADR-0035](../../../docs/decisions/0035-the-platform-owns-the-application-iam-issuer.md))
|
|
756
|
+
* left a live namespace proxy crash-looping on `FABRIKA_IAM_ISSUER is required`, because provisioning
|
|
757
|
+
* had written the old name months earlier and the deploy path only ever wrote the manifest. Writing
|
|
758
|
+
* these BEFORE the pipeline is triggered is what makes a rename a flag day rather than an outage
|
|
759
|
+
* ([ADR-0024](../../../docs/decisions/0024-retire-the-legacy-environment-name-fallback.md)).
|
|
760
|
+
*/
|
|
761
|
+
export const ensureNamespaceProxyIam = async (input: NamespaceProxyIamInput): Promise<void> => {
|
|
762
|
+
const variables = await input.api.listServiceEnv({ serviceId: input.proxyServiceId, signal: input.signal })
|
|
763
|
+
const issuer = variables.find((variable) => variable.key === ZEROPS_NAMESPACE_IAM_ISSUER_VARIABLE)
|
|
764
|
+
if (issuer?.content !== input.iamUrl) {
|
|
765
|
+
await input.api.putServiceEnv({
|
|
766
|
+
serviceId: input.proxyServiceId,
|
|
767
|
+
key: ZEROPS_NAMESPACE_IAM_ISSUER_VARIABLE,
|
|
768
|
+
value: input.iamUrl,
|
|
769
|
+
signal: input.signal,
|
|
770
|
+
})
|
|
771
|
+
}
|
|
772
|
+
// Secret read-back is not trustworthy, so overwrite it idempotently without inspecting its value.
|
|
773
|
+
await input.api.putServiceEnv({
|
|
774
|
+
serviceId: input.proxyServiceId,
|
|
775
|
+
key: ZEROPS_NAMESPACE_IAM_KEY_VARIABLE,
|
|
776
|
+
value: input.iamKey,
|
|
777
|
+
signal: input.signal,
|
|
778
|
+
})
|
|
779
|
+
}
|
|
780
|
+
|
|
740
781
|
const ensureProxyConfiguration = async (
|
|
741
782
|
target: NormalizedZeropsNamespaceTarget,
|
|
742
783
|
options: ZeropsNamespaceOptions,
|
|
@@ -759,20 +800,11 @@ const ensureProxyConfiguration = async (
|
|
|
759
800
|
})
|
|
760
801
|
deployRequired = true
|
|
761
802
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
value: options.iamUrl,
|
|
768
|
-
signal,
|
|
769
|
-
})
|
|
770
|
-
}
|
|
771
|
-
// Secret read-back is not trustworthy, so overwrite it idempotently without inspecting its value.
|
|
772
|
-
await options.api.putServiceEnv({
|
|
773
|
-
serviceId: proxyServiceId,
|
|
774
|
-
key: ZEROPS_NAMESPACE_IAM_KEY_VARIABLE,
|
|
775
|
-
value: options.iamKey,
|
|
803
|
+
await ensureNamespaceProxyIam({
|
|
804
|
+
api: options.api,
|
|
805
|
+
proxyServiceId,
|
|
806
|
+
iamUrl: options.iamUrl,
|
|
807
|
+
iamKey: options.iamKey,
|
|
776
808
|
signal,
|
|
777
809
|
})
|
|
778
810
|
return deployRequired
|