Skip to content

Commit

Permalink
fix: env merge & deploy start validation
Browse files Browse the repository at this point in the history
  • Loading branch information
robot9706 committed Dec 16, 2024
1 parent fc97901 commit f59f9a6
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 564 deletions.
24 changes: 23 additions & 1 deletion web/crux-ui/src/models/container-merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Marker,
Port,
UniqueKey,
UniqueKeyValue,
UniqueSecretKey,
UniqueSecretKeyValue,
Volume,
Expand Down Expand Up @@ -81,6 +82,20 @@ export const mergeSecrets = (strong: UniqueSecretKeyValue[], weak: UniqueSecretK
return [...missing, ...strong]
}

// TODO(@robot9706): Validate
const mergeUniqueKeyValues = <T extends UniqueKeyValue>(strong: T[], weak: T[]): T[] => {
if (!strong) {
return weak ?? null
}

if (!weak) {
return strong
}

const missing = weak.filter(w => !strong.find(it => it.key === w.key))
return [...strong, ...missing]
}

export const mergeConfigs = (strong: ContainerConfigData, weak: ContainerConfigData): ContainerConfigData => ({
// common
name: strong.name ?? weak.name,
Expand Down Expand Up @@ -122,8 +137,15 @@ export const mergeConfigs = (strong: ContainerConfigData, weak: ContainerConfigD
expectedState: strong.expectedState ?? weak.expectedState,
})

// TODO(@robot9706): Validate
export const squashConfigs = (configs: ContainerConfigData[]): ContainerConfigData =>
configs.reduce((result, conf) => mergeConfigs(conf, result), {} as ContainerConfigData)
configs.reduce((result, conf) => {
const merged = mergeConfigs(conf, result)
return {
...merged,
environment: mergeUniqueKeyValues(conf.environment, result.environment),
}
}, {} as ContainerConfigData)

// this assumes that the concrete config takes care of any conflict between the other configs
export const mergeConfigsWithConcreteConfig = (
Expand Down
49 changes: 20 additions & 29 deletions web/crux/src/app/deploy/interceptors/deploy.start.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getConflictsForConcreteConfig } from 'src/domain/container-conflict'
import { mergeConfigsWithConcreteConfig } from 'src/domain/container-merge'
import { checkDeploymentDeployability } from 'src/domain/deployment'
import { parseDyrectorioEnvRules } from 'src/domain/image'
import { missingSecretsOf } from 'src/domain/start-deployment'
import { deploymentConfigOf, instanceConfigOf, missingSecretsOf } from 'src/domain/start-deployment'
import { createStartDeploymentSchema, nullifyUndefinedProperties, yupValidate } from 'src/domain/validation'
import { CruxPreconditionFailedException } from 'src/exception/crux-exception'
import PrismaService from 'src/services/prisma.service'
Expand Down Expand Up @@ -110,25 +110,7 @@ export default class DeployStartValidationInterceptor implements NestInterceptor
})
yupValidate(createStartDeploymentSchema(instanceValidations), target)

const missingSecrets = deployment.instances
.map(it => {
const imageConfig = it.image.config as any as ContainerConfigData
const instanceConfig = it.config as any as ConcreteContainerConfigData
const mergedConfig = mergeConfigsWithConcreteConfig([imageConfig], instanceConfig)

return missingSecretsOf(it.configId, mergedConfig)
})
.filter(it => !!it)

if (missingSecrets.length > 0) {
throw new CruxPreconditionFailedException({
message: 'Required secrets must have values!',
property: 'instanceSecrets',
value: missingSecrets,
})
}

// config bundles
// check config bundle conflicts
if (deployment.configBundles.length > 0) {
const configs = deployment.configBundles.map(it => it.configBundle.config as any as ContainerConfigDataWithId)
const concreteConfig = deployment.config as any as ConcreteContainerConfigData
Expand All @@ -140,16 +122,25 @@ export default class DeployStartValidationInterceptor implements NestInterceptor
value: Object.keys(conflicts).join(', '),
})
}
}

const mergedConfig = mergeConfigsWithConcreteConfig(configs, concreteConfig)
const missingInstanceSecrets = missingSecretsOf(deployment.configId, mergedConfig)
if (missingInstanceSecrets) {
throw new CruxPreconditionFailedException({
message: 'Required secrets must have values!',
property: 'deploymentSecrets',
value: missingInstanceSecrets,
})
}
// validate instance configs
const deploymentConfig = deploymentConfigOf(deployment)

const missingSecrets = deployment.instances
.map(it => {
const instanceConfig = instanceConfigOf(deployment, deploymentConfig, it)

return missingSecretsOf(it.configId, instanceConfig)
})
.filter(it => !!it)

if (missingSecrets.length > 0) {
throw new CruxPreconditionFailedException({
message: 'Required secrets must have values!',
property: 'instanceSecrets',
value: missingSecrets,
})
}

// node
Expand Down
Loading

0 comments on commit f59f9a6

Please sign in to comment.