@sap/cds-dk
Version:
Command line client and development toolkit for the SAP Cloud Application Programming Model
138 lines (128 loc) • 5.44 kB
JavaScript
const { join } = require('path')
const cds = require('../../../cds')
const { read, write } = cds.utils
const mvn = require('../../mvn')
const { readProject } = require('../../projectReader')
const { merge, sort } = require('../../merge')
const { copyRenderedJSON } = require('../../../util/fs')
const {
srv4, // Server
mtxSidecar4, // Additional Modules
saasRegistry, subscriptionManager, // BTP Services
srvApi4, providedMtxApiSidecar4, requiredMtxSidecarApi4, // APIs
} = require('../../registries/mta')
module.exports = class MultitenancyTemplate extends require('../../plugin') {
static help() {
return 'schema-based multitenancy support'
}
static hasInProduction(env) {
const { options } = cds.cli.options
// REVISIT: Check if this can be simplified
return options?.add?.has('mtx') || options?.add?.has('multitenancy') || !!env.requires?.multitenancy || false
}
async run() {
const project = readProject()
const { isNodejs, isJava, configFile } = project
await merge(__dirname, 'files/package.json.hbs').into(configFile, { with: project })
if (isJava) {
const packageJson = await read('package.json')
packageJson.workspaces = ['mtx/sidecar']
await write('package.json', packageJson, { spaces: 2 })
await mvn.add('mtx')
}
if (isNodejs) await sort('package.json', 'dependencies')
await copyRenderedJSON(join(__dirname, 'files', 'package.sidecar.json.hbs'), join('mtx', 'sidecar/package.json'), project)
}
async combine() {
const project = readProject()
const {
isNodejs, isJava, hasMta, hasHelm, hasHelmUnifiedRuntime,
hasXsuaa, hasIas, hasHana, hasContainerize, hasApprouter,
srvPath, appName
} = project
if (hasMta) {
const srv = srv4(srvPath)
const mtxSidecar = mtxSidecar4(isJava ? 'mtx/sidecar' : 'gen/mtx/sidecar')
const modules = [srv, mtxSidecar]
const services = []
if (hasIas) services.push(subscriptionManager)
if (!hasIas || hasXsuaa) services.push(saasRegistry)
const apis = [srvApi4(srv), providedMtxApiSidecar4(mtxSidecar)]
if (isJava) apis.push(requiredMtxSidecarApi4(srv))
const additions = [...modules, ...services, ...apis]
const relationships = []
if (hasXsuaa) {
relationships.push({
insert: [saasRegistry, 'name'],
into: [isJava ? srv : mtxSidecar, 'requires', 'name']
})
}
if (hasIas) {
relationships.push({
insert: [subscriptionManager, 'name'],
into: [isJava ? srv : mtxSidecar, 'requires', 'name']
})
}
if (isJava) {
relationships.push({
insert: [srv, 'name'],
into: [mtxSidecar, 'build-parameters.requires', 'name']
})
}
const templateMtaPath = join(__dirname, 'files/mta.yaml.hbs')
await merge(templateMtaPath).into('mta.yaml', { with: project, additions, relationships })
}
if (hasHelm || hasHelmUnifiedRuntime) {
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
const domain = hasApprouter ? 'svc.cluster.local:8080' : '{{ .Values.global.domain }}'
const applicationWorkload = hasApprouter ? 'approuter' : 'srv'
const serviceCommunicatingWithSaasReg = hasApprouter ? 'approuter' : isNodejs ? 'sidecar' : 'srv'
const prefix = `https://{{ .Release.Name }}-${serviceCommunicatingWithSaasReg}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`
const getDependencies = `${prefix}${isNodejs ? '/-/cds/saas-provisioning' : '/mt/v1.0/subscriptions'}/dependencies`
const onSubscription = `${prefix}${isNodejs ? '/-/cds/saas-provisioning/tenant/{tenantId}' : '/mt/v1.0/subscriptions/tenants/{tenantId}'}`
await merge({
'saas-registry': {
parameters: {
xsappname: `${appName}-{{ .Release.Namespace }}`,
appName: `${appName}-{{ .Release.Namespace }}`,
appUrls: {
getDependencies, onSubscription
}
}
},
...(isNodejs) && { sidecar: { env: {
SUBSCRIPTION_URL: `https://\${tenant_subdomain}-{{ .Release.Name }}-${applicationWorkload}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`
}}},
...(isJava) && { srv: { env: {
CDS_MULTITENANCY_APPUI_URL: `https://{{ .Release.Name }}-${applicationWorkload}-{{ .Release.Namespace }}.{{ .Values.global.domain }}`,
CDS_MULTITENANCY_SIDECAR_URL: `http${hasApprouter ? '' : 's'}://{{ .Release.Name }}-sidecar${hasApprouter ? '.' : '-'}{{ .Release.Namespace }}.${domain}`
}}}
}).into('chart/values.yaml',{ forceOverwrite: true })
}
if (hasContainerize) {
const deletions = []
if (hasHana) {
deletions.push({
item: {
in: 'modules',
where: { name: `${appName}-hana-deployer` }
}
})
}
const additions = [{
in: 'modules',
where: { name: `${appName}-sidecar` }
}]
await merge(__dirname, '/files/containerize.yaml.hbs').into('containerize.yaml', { with: project, additions, deletions })
}
if (hasXsuaa) {
await merge(__dirname, 'files/xs-security.json.hbs').into('xs-security.json', {
project,
additions: [{
in: 'scopes',
where: { name: '$XSAPPNAME.mtcallback' },
}]
})
}
}
}