@sap/cds-dk
Version:
Command line client and development toolkit for the SAP Cloud Application Programming Model
170 lines (152 loc) • 6.65 kB
JavaScript
const { join } = require('path')
const cds = require('../../../cds')
const { exists, rimraf, copy, readFileSync, yaml } = cds.utils
const { readProject } = require('../../projectReader')
const { merge } = require('../../merge')
const { ask4 } = require('../../../util/question')
const { execSync } = require('child_process')
const { mvn } = require('../../add')
module.exports = class HelmTemplate extends require('../../plugin') {
static help() {
return 'Kyma deployment using Helm charts'
}
options() {
return {
'y': {
type: 'boolean',
help: 'If provided, the default values will be used for all prompts.'
}
}
}
async canRun() {
const hasInProduction = HelmTemplate.hasInProduction()
if (cds.cli.options.force) {
await rimraf(join('chart'))
return true
} else if (exists(join(cds.root, 'chart')) && !hasInProduction) {
throw `Chart already exists. Use --force to overwrite.`
}
return true
}
// Won't need this any more with plugin approach: package not there -> plugin not pulled
static hasInProduction() {
if (exists('chart/Chart.yaml')) {
const chartFile = readFileSync(join(cds.root, 'chart', 'Chart.yaml'), 'utf8')
const chartYaml = yaml.parseDocument(chartFile).toJS()
return chartYaml.annotations?.["app.kubernetes.io/managed-by"] === 'cds-dk/helm'
}
return false
}
async run() {
const project = readProject()
project.domain = 'abc.com'
project.registry = 'registry-name'
project.imagePullSecret = 'docker-registry'
project.tag = 'latest'
if (cds.cli.command == 'add' && !HelmTemplate.hasInProduction()) {
let registry = 'registry-name', tag = 'latest', domain = 'abc.com'
// read domain using kubectl
try {
const domainCmd = execSync(`kubectl config view --minify --output jsonpath="{.clusters[*].cluster.server}"`, { stdio: "pipe" }).toString()
const domainStartIndex = domainCmd.indexOf('api.')
if (domainStartIndex !== -1) {
domain = domainCmd.substring(domainStartIndex + 4)
}
} catch (error) {
// ignore
}
// read project.registry
if (exists('containerize.yaml')) {
const containerizeYamlFile = readFileSync(join(cds.root, 'containerize.yaml'), 'utf8')
const containerizYaml = yaml.parseDocument(containerizeYamlFile).toJS()
registry = containerizYaml.repository
tag = containerizYaml.tag
}
let imagePullSecretInput = 'docker-registry'
if (!cds.cli.options['y']) {
const [domainAns, imagePullSecretAns, registryAns] = await ask4(`domain: (${domain}) `, 'imagePullSecret: (docker-registry) ', `registry: (${registry}) `)
domain = domainAns || domain
imagePullSecretInput = imagePullSecretAns || imagePullSecretInput
registry = registryAns || registry
}
project.domain = domain
project.imagePullSecret = imagePullSecretInput
project.registry = registry
project.tag = tag
}
await copy(join(__dirname, 'files', 'values.schema.json')).to('chart/values.schema.json')
await merge(__dirname, 'files/Chart.yaml.hbs').into('chart/Chart.yaml', { with: project })
await merge(__dirname, 'files/values.yaml.hbs').into('chart/values.yaml', { with: project })
await this._mergeDependency('web-application', 'srv')
if (project.isJava) await mvn.add('k8s')
}
async combine() {
const { hasDestination, hasEnterpriseMessaging, hasEnterpriseMessagingShared, hasHana, hasMultitenancy, hasXsuaa, hasHtml5Repo, hasApprouter, hasKafka, hasAttachments, hasPortal, hasMalwareScanner, hasDynatrace, hasCloudLogging } = readProject()
if (hasApprouter) {
await this._mergeDependency('web-application', 'approuter')
}
if (hasHtml5Repo) {
await this._mergeDependency('service-instance', 'html5-apps-repo-host')
await this._mergeDependency('content-deployment', 'html5-apps-deployer')
if (hasApprouter) {
await this._mergeDependency('service-instance', 'html5-apps-repo-runtime')
}
}
if (hasMultitenancy) {
await this._mergeDependency('web-application', 'sidecar')
await this._mergeDependency('service-instance', 'saas-registry')
}
if (hasDestination) {
await this._mergeDependency('service-instance', 'destination')
}
if (hasAttachments) {
await this._mergeDependency('service-instance', 'attachments')
}
if (hasEnterpriseMessaging || hasEnterpriseMessagingShared) {
await this._mergeDependency('service-instance', 'event-mesh')
}
if (hasXsuaa) {
await this._mergeDependency('service-instance', 'xsuaa')
}
if (hasHana) {
if (hasMultitenancy) {
await this._mergeDependency('service-instance', 'service-manager')
} else {
await this._mergeDependency('service-instance', 'hana')
await this._mergeDependency('content-deployment', 'hana-deployer')
}
}
if (hasKafka) {
await this._mergeDependency('service-instance', 'kafka')
}
if (hasPortal) {
await this._mergeDependency('service-instance', 'portal')
await this._mergeDependency('content-deployment', 'portal-deployer')
}
if (hasMalwareScanner) {
await this._mergeDependency('service-instance', 'malware-scanner')
}
if (hasCloudLogging) {
await this._mergeDependency('service-instance', 'cloud-logging')
}
if (hasDynatrace) {
await this._mergeDependency('service-instance', 'dynatrace')
}
}
async _mergeDependency(name, alias) {
const project = readProject()
await merge({
dependencies: [{
name,
alias,
version: '>0.0.0'
}]
}).into('chart/Chart.yaml', {
project,
additions: [{
in: 'dependencies',
where: { alias }
}]
})
}
}