@ankhorage/infra 5.1.1 → 5.1.2
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
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/infra",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.1.
|
|
4
|
+
"version": "5.1.2",
|
|
5
5
|
"description": "Project-aware infrastructure generation library and executable Ankh provider for Ankhorage.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/infra#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -17,8 +17,12 @@ import { upInfraEnvironmentAsync } from './features/environment-lifecycle/applic
|
|
|
17
17
|
import type { InfraOrchestrationDependencies } from './types/infraOrchestration.js';
|
|
18
18
|
|
|
19
19
|
const projectId = 'infra145-minikube-supabase';
|
|
20
|
+
const acceptanceNamespace = `${projectId}-local`;
|
|
20
21
|
const baseUrl = 'http://127.0.0.1:54321';
|
|
21
22
|
const bucket = 'phase8-acceptance';
|
|
23
|
+
const staleOwnedConfigMap = 'phase8-stale-owned';
|
|
24
|
+
const unrelatedConfigMap = 'phase8-unrelated';
|
|
25
|
+
const staleOwnedResourceId = 'stale:phase8-owned';
|
|
22
26
|
const jwtSecret = 'phase8-jwt-secret-that-is-at-least-thirty-two-characters';
|
|
23
27
|
const credentials = {
|
|
24
28
|
postgresPassword: 'phase8-postgres-password',
|
|
@@ -94,6 +98,32 @@ test.skipIf(process.env.ANKH_INFRA_MINIKUBE_SUPABASE_E2E !== '1')(
|
|
|
94
98
|
);
|
|
95
99
|
expect(convergedPlan.actions.every(({ operation }) => operation === 'noop')).toBe(true);
|
|
96
100
|
|
|
101
|
+
await createStaleOwnershipFixturesAsync();
|
|
102
|
+
const stalePlan = requireSuccess(
|
|
103
|
+
await planInfraEnvironmentAsync({ projectId, manifest, previous: ledger }, dependencies),
|
|
104
|
+
);
|
|
105
|
+
expect(
|
|
106
|
+
stalePlan.actions.some(
|
|
107
|
+
({ operation, owner }) =>
|
|
108
|
+
operation === 'delete' && owner.resourceId === staleOwnedResourceId,
|
|
109
|
+
),
|
|
110
|
+
).toBe(true);
|
|
111
|
+
|
|
112
|
+
const { ledger: prunedLedger } = requireSuccess(
|
|
113
|
+
await upInfraEnvironmentAsync({ projectId, manifest, previous: ledger }, dependencies),
|
|
114
|
+
);
|
|
115
|
+
ledger = prunedLedger;
|
|
116
|
+
expect(await configMapExistsAsync(staleOwnedConfigMap)).toBe(false);
|
|
117
|
+
expect(await configMapExistsAsync(unrelatedConfigMap)).toBe(true);
|
|
118
|
+
await runKubectlAsync([
|
|
119
|
+
'delete',
|
|
120
|
+
'configmap',
|
|
121
|
+
unrelatedConfigMap,
|
|
122
|
+
'--namespace',
|
|
123
|
+
acceptanceNamespace,
|
|
124
|
+
'--ignore-not-found=true',
|
|
125
|
+
]);
|
|
126
|
+
|
|
97
127
|
const { ledger: downLedger } = requireSuccess(
|
|
98
128
|
await downInfraEnvironmentAsync({ projectId, manifest, previous: ledger }, dependencies),
|
|
99
129
|
);
|
|
@@ -128,6 +158,75 @@ test.skipIf(process.env.ANKH_INFRA_MINIKUBE_SUPABASE_E2E !== '1')(
|
|
|
128
158
|
900_000,
|
|
129
159
|
);
|
|
130
160
|
|
|
161
|
+
async function createStaleOwnershipFixturesAsync(): Promise<void> {
|
|
162
|
+
await runKubectlAsync([
|
|
163
|
+
'create',
|
|
164
|
+
'configmap',
|
|
165
|
+
staleOwnedConfigMap,
|
|
166
|
+
'--namespace',
|
|
167
|
+
acceptanceNamespace,
|
|
168
|
+
'--from-literal=marker=stale',
|
|
169
|
+
]);
|
|
170
|
+
await runKubectlAsync([
|
|
171
|
+
'label',
|
|
172
|
+
'configmap',
|
|
173
|
+
staleOwnedConfigMap,
|
|
174
|
+
'--namespace',
|
|
175
|
+
acceptanceNamespace,
|
|
176
|
+
'app.kubernetes.io/managed-by=ankhorage-infra',
|
|
177
|
+
`infra.ankhorage.dev/project=${projectId}`,
|
|
178
|
+
'infra.ankhorage.dev/environment=local',
|
|
179
|
+
]);
|
|
180
|
+
await runKubectlAsync([
|
|
181
|
+
'annotate',
|
|
182
|
+
'configmap',
|
|
183
|
+
staleOwnedConfigMap,
|
|
184
|
+
'--namespace',
|
|
185
|
+
acceptanceNamespace,
|
|
186
|
+
`infra.ankhorage.dev/project-id=${projectId}`,
|
|
187
|
+
'infra.ankhorage.dev/environment=local',
|
|
188
|
+
'infra.ankhorage.dev/adapter=minikube',
|
|
189
|
+
`infra.ankhorage.dev/resource-id=${staleOwnedResourceId}`,
|
|
190
|
+
'infra.ankhorage.dev/persistent=false',
|
|
191
|
+
'infra.ankhorage.dev/retention=retain',
|
|
192
|
+
'infra.ankhorage.dev/depends-on=[]',
|
|
193
|
+
]);
|
|
194
|
+
await runKubectlAsync([
|
|
195
|
+
'create',
|
|
196
|
+
'configmap',
|
|
197
|
+
unrelatedConfigMap,
|
|
198
|
+
'--namespace',
|
|
199
|
+
acceptanceNamespace,
|
|
200
|
+
'--from-literal=marker=unrelated',
|
|
201
|
+
]);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async function configMapExistsAsync(name: string): Promise<boolean> {
|
|
205
|
+
const output = await runKubectlAsync([
|
|
206
|
+
'get',
|
|
207
|
+
'configmap',
|
|
208
|
+
name,
|
|
209
|
+
'--namespace',
|
|
210
|
+
acceptanceNamespace,
|
|
211
|
+
'--ignore-not-found=true',
|
|
212
|
+
'--output=name',
|
|
213
|
+
]);
|
|
214
|
+
return output === `configmap/${name}`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function runKubectlAsync(args: readonly string[]): Promise<string> {
|
|
218
|
+
const process = Bun.spawn(['kubectl', ...args], { stdout: 'pipe', stderr: 'pipe' });
|
|
219
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
220
|
+
process.exited,
|
|
221
|
+
new Response(process.stdout).text(),
|
|
222
|
+
new Response(process.stderr).text(),
|
|
223
|
+
]);
|
|
224
|
+
if (exitCode !== 0) {
|
|
225
|
+
throw new Error(`kubectl ${args.join(' ')} failed: ${stderr.trim()}`);
|
|
226
|
+
}
|
|
227
|
+
return stdout.trim();
|
|
228
|
+
}
|
|
229
|
+
|
|
131
230
|
function createDependencies(): InfraOrchestrationDependencies {
|
|
132
231
|
return {
|
|
133
232
|
adapterResolver: createNodeInfraAdapterPackageResolver(),
|