@@ -11,7 +11,18 @@ const yaml = require('@sap/cds-foss').yaml
1111const Mustache = require ( 'mustache' )
1212const { spawn } = require ( 'child_process' )
1313
14- const { ask, mergeObj, isCAPOperatorChart, isConfigurableTemplateChart, transformValuesAndFillCapOpCroYaml, isServiceOnlyChart } = require ( '../lib/util' )
14+ const {
15+ ask,
16+ mergeObj,
17+ isCAPOperatorChart,
18+ isConfigurableTemplateChart,
19+ transformValuesAndFillCapOpCroYaml,
20+ isServiceOnlyChart,
21+ getServiceInstanceKeyName,
22+ getConfigurableCapOpCroYaml,
23+ getDomainCroYaml,
24+ getHelperTpl
25+ } = require ( '../lib/util' )
1526
1627const SUPPORTED = { 'generate-runtime-values' : [ '--with-input-yaml' ] , 'convert-to-configurable-template-chart' : [ '--with-runtime-yaml' ] }
1728
@@ -25,7 +36,7 @@ async function capOperatorPlugin(cmd, option, yamlPath) {
2536 if ( option === '--with-input-yaml' && ! yamlPath )
2637 return _usage ( `Input yaml path is missing.` )
2738
28- if ( option === '--with-input-yaml' && ! yamlPath && cds . utils . exists ( cds . utils . path . join ( cds . root , yamlPath ) ) )
39+ if ( option === '--with-input-yaml' && ! yamlPath && cds . utils . exists ( cds . utils . path . join ( cds . root , yamlPath ) ) )
2940 return _usage ( `Input yaml path ${ yamlPath } does not exist.` )
3041
3142 await generateRuntimeValues ( option , yamlPath )
@@ -35,7 +46,7 @@ async function capOperatorPlugin(cmd, option, yamlPath) {
3546 if ( option === '--with-runtime-yaml' && ! yamlPath )
3647 return _usage ( `Input runtime yaml path is missing.` )
3748
38- if ( option === '--with-runtime-yaml' && ! yamlPath && cds . utils . exists ( cds . utils . path . join ( cds . root , yamlPath ) ) )
49+ if ( option === '--with-runtime-yaml' && ! yamlPath && cds . utils . exists ( cds . utils . path . join ( cds . root , yamlPath ) ) )
3950 return _usage ( `Input runtime yaml path ${ yamlPath } does not exist.` )
4051
4152 await convertToconfigurableTemplateChart ( option , yamlPath )
@@ -81,13 +92,13 @@ EXAMPLES
8192}
8293
8394async function transformRuntimeValues ( runtimeYamlPath ) {
84- console . log ( 'Transforming runtime values file ' + cds . utils . path . join ( cds . root , runtimeYamlPath ) + ' to the configurable template chart format.' )
95+ console . log ( 'Transforming runtime values file ' + cds . utils . path . join ( cds . root , runtimeYamlPath ) + ' to the configurable template chart format.' )
8596 let runtimeYaml = yaml . parse ( await cds . utils . read ( cds . utils . path . join ( cds . root , runtimeYamlPath ) ) )
8697 if ( runtimeYaml ?. workloads ?. server ?. deploymentDefinition ?. env ) {
8798 const index = runtimeYaml . workloads . server . deploymentDefinition . env . findIndex ( e => e . name === 'CDS_CONFIG' )
8899 if ( index > - 1 ) {
89100 const cdsConfigValueJson = JSON . parse ( runtimeYaml . workloads . server . deploymentDefinition . env [ index ] . value )
90- if ( cdsConfigValueJson ?. requires ?. [ 'cds.xt.DeploymentService' ] ?. hdi ?. create ?. database_id ) {
101+ if ( cdsConfigValueJson ?. requires ?. [ 'cds.xt.DeploymentService' ] ?. hdi ?. create ?. database_id ) {
91102 runtimeYaml [ 'hanaInstanceId' ] = cdsConfigValueJson . requires [ 'cds.xt.DeploymentService' ] . hdi . create . database_id
92103 delete runtimeYaml [ 'workloads' ]
93104 await cds . utils . write ( yaml . stringify ( runtimeYaml ) ) . to ( cds . utils . path . join ( cds . root , runtimeYamlPath ) )
@@ -102,36 +113,55 @@ async function isRuntimeValueAlreadyTransformed(runtimeYamlPath) {
102113}
103114
104115async function convertToconfigurableTemplateChart ( option , runtimeYamlPath ) {
105- if ( ! ( ( cds . utils . exists ( 'chart' ) && isCAPOperatorChart ( cds . utils . path . join ( cds . root , 'chart' ) ) ) ) )
116+ if ( ! ( ( cds . utils . exists ( 'chart' ) && isCAPOperatorChart ( cds . utils . path . join ( cds . root , 'chart' ) ) ) ) )
106117 throw new Error ( "No CAP Operator chart found in the project. Please run 'cds add cap-operator --force' to add the CAP Operator chart folder." )
107118
108- if ( isConfigurableTemplateChart ( cds . utils . path . join ( cds . root , 'chart' ) ) ) {
119+ if ( isConfigurableTemplateChart ( cds . utils . path . join ( cds . root , 'chart' ) ) ) {
109120 console . log ( "Exisiting chart is already a configurable template chart. No need for conversion." )
110121 if ( option === '--with-runtime-yaml' && runtimeYamlPath && ! ( await isRuntimeValueAlreadyTransformed ( runtimeYamlPath ) ) )
111122 await transformRuntimeValues ( runtimeYamlPath )
112123 else
113- console . log ( 'Runtime values file ' + cds . utils . path . join ( cds . root , runtimeYamlPath ) + ' already in the configurable template chart format.' )
124+ console . log ( 'Runtime values file ' + cds . utils . path . join ( cds . root , runtimeYamlPath ) + ' already in the configurable template chart format.' )
114125 return
115126 }
116127
117- console . log ( 'Converting chart ' + cds . utils . path . join ( cds . root , 'chart' ) + ' to configurable template chart.' )
128+ console . log ( 'Converting chart ' + cds . utils . path . join ( cds . root , 'chart' ) + ' to configurable template chart.' )
118129
119130 // Copy templates
120- await cds . utils . copy ( cds . utils . path . join ( __dirname , '../files/configurableTemplatesChart/templates/_helpers.tpl' ) ) . to ( cds . utils . path . join ( cds . root , 'chart/templates/_helpers.tpl' ) )
121- await cds . utils . copy ( cds . utils . path . join ( __dirname , '../files/commonTemplates/' ) ) . to ( cds . utils . path . join ( cds . root , 'chart/templates/' ) )
131+ await cds . utils . copy ( cds . utils . path . join ( __dirname , '../files/commonTemplates/' ) ) . to ( cds . utils . path . join ( cds . root , 'chart/templates/' ) )
122132
123- isServiceOnlyChart ( cds . utils . path . join ( cds . root , 'chart' ) ) ? await cds . utils . copy ( cds . utils . path . join ( __dirname , '../files/configurableTemplatesChart/templates/cap-operator-cros-svc.yaml' ) ) . to ( cds . utils . path . join ( cds . root , 'chart/templates/cap-operator-cros.yaml' ) ) :
124- await cds . utils . copy ( cds . utils . path . join ( __dirname , '../files/configurableTemplatesChart/templates/cap-operator-cros.yaml' ) ) . to ( cds . utils . path . join ( cds . root , 'chart/templates/cap-operator-cros.yaml' ) )
133+ const valuesYaml = yaml . parse ( await cds . utils . read ( cds . utils . path . join ( cds . root , 'chart/values.yaml' ) ) )
134+ const hasIas = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'identity' ) != null
135+ const hasXsuaa = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'xsuaa' ) != null
136+
137+ // Create _helpers.tpl
138+ await cds . utils . write ( getHelperTpl ( {
139+ hasXsuaa : hasXsuaa
140+ } , false ) ) . to ( cds . utils . path . join ( cds . root , 'chart/templates/_helpers.tpl' ) )
141+
142+ // Create domain.yaml
143+ await cds . utils . write ( getDomainCroYaml ( {
144+ hasIas : hasIas
145+ } ) ) . to ( cds . utils . path . join ( cds . root , 'chart/templates/domain.yaml' ) )
146+
147+ // Create cap-operator-cros.yaml
148+ // Only filling those fields in the project input struct that are required to create CAPApplication CR
149+ // Workloads will be filled during transformValuesAndFillCapOpCroYaml function call
150+ await cds . utils . write ( getConfigurableCapOpCroYaml ( {
151+ hasXsuaa : hasXsuaa ,
152+ hasIas : hasIas ,
153+ isService : isServiceOnlyChart ( cds . utils . path . join ( cds . root , 'chart' ) )
154+ } ) ) . to ( cds . utils . path . join ( cds . root , 'chart/templates/cap-operator-cros.yaml' ) )
125155
126156 // Copy values.schema.json
127- await cds . utils . copy ( cds . utils . path . join ( __dirname , '../files/configurableTemplatesChart/values.schema.json' ) ) . to ( cds . utils . path . join ( cds . root , 'chart' , 'values.schema.json' ) )
157+ await cds . utils . copy ( cds . utils . path . join ( __dirname , '../files/configurableTemplatesChart/values.schema.json' ) ) . to ( cds . utils . path . join ( cds . root , 'chart' , 'values.schema.json' ) )
128158
129159 // Add annotation to chart.yaml
130160 const chartYaml = yaml . parse ( await cds . utils . read ( cds . utils . path . join ( cds . root , 'chart/Chart.yaml' ) ) )
131161 chartYaml [ 'annotations' ] [ 'app.kubernetes.io/part-of' ] = 'cap-operator-configurable-templates'
132162 await cds . utils . write ( yaml . stringify ( chartYaml ) ) . to ( cds . utils . path . join ( cds . root , 'chart/Chart.yaml' ) )
133163
134- // Transform
164+ // Transform CAPApplicationVersion CR from values.yaml
135165 await transformValuesAndFillCapOpCroYaml ( )
136166
137167 if ( option === '--with-runtime-yaml' && runtimeYamlPath ) {
@@ -140,14 +170,14 @@ async function convertToconfigurableTemplateChart(option, runtimeYamlPath) {
140170}
141171
142172async function generateRuntimeValues ( option , inputYamlPath ) {
143- if ( ! ( ( cds . utils . exists ( 'chart' ) && isCAPOperatorChart ( cds . utils . path . join ( cds . root , 'chart' ) ) ) ) ) {
173+ if ( ! ( ( cds . utils . exists ( 'chart' ) && isCAPOperatorChart ( cds . utils . path . join ( cds . root , 'chart' ) ) ) ) ) {
144174 throw new Error ( "No CAP Operator chart found in the project. Please run 'cds add cap-operator --force' to add the CAP Operator chart folder." )
145175 }
146176
147177 let answerStruct = { }
148178 const { appName, appDescription } = getAppDetails ( )
149- const isConfigurableTempChart = isConfigurableTemplateChart ( cds . utils . path . join ( cds . root , 'chart' ) )
150- const isServiceOnly = isServiceOnlyChart ( cds . utils . path . join ( cds . root , 'chart' ) )
179+ const isConfigurableTempChart = isConfigurableTemplateChart ( cds . utils . path . join ( cds . root , 'chart' ) )
180+ const isServiceOnly = isServiceOnlyChart ( cds . utils . path . join ( cds . root , 'chart' ) )
151181
152182 if ( option === '--with-input-yaml' && inputYamlPath ) {
153183
@@ -190,8 +220,16 @@ async function generateRuntimeValues(option, inputYamlPath) {
190220 const valuesYaml = yaml . parse ( await cds . utils . read ( cds . utils . path . join ( cds . root , 'chart/values.yaml' ) ) )
191221
192222 //get saas-registry and xsuaa service keys
193- answerStruct [ 'saasRegistryKeyName' ] = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'saas-registry' ) || 'saas-registry'
194- answerStruct [ 'xsuaaKeyName' ] = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'xsuaa' ) || 'xsuaa'
223+ const xsuaaServiceInstanceKey = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'xsuaa' )
224+ if ( xsuaaServiceInstanceKey == null ) {
225+ answerStruct [ 'hasXsuaa' ] = false
226+ answerStruct [ 'subscriptionManagerKeyName' ] = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'subscription-manager' ) || 'subscription-manager'
227+ answerStruct [ 'identityKeyName' ] = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'identity' ) || 'identity'
228+ } else {
229+ answerStruct [ 'hasXsuaa' ] = true
230+ answerStruct [ 'saasRegistryKeyName' ] = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'saas-registry' ) || 'saas-registry'
231+ answerStruct [ 'xsuaaKeyName' ] = getServiceInstanceKeyName ( valuesYaml [ 'serviceInstances' ] , 'xsuaa' ) || 'xsuaa'
232+ }
195233
196234 answerStruct [ 'isApp' ] = ! isServiceOnly
197235 answerStruct [ 'isService' ] = isServiceOnly
@@ -220,7 +258,7 @@ function updateWorkloadEnv(runtimeValuesYaml, valuesYaml, answerStruct) {
220258
221259 const cdsConfigHana = Mustache . render ( '{"requires":{"cds.xt.DeploymentService":{"hdi":{"create":{"database_id":"{{hanaInstanceId}}"}}}}}' , answerStruct )
222260
223- if ( ( workloadDetails ?. deploymentDefinition ?. type === 'CAP' || workloadDetails ?. deploymentDefinition ?. type === 'service ' ) && answerStruct [ 'hanaInstanceId' ] ) {
261+ if ( ( workloadDetails ?. deploymentDefinition ?. type === 'CAP' || workloadDetails ?. deploymentDefinition ?. type === 'Service ' ) && answerStruct [ 'hanaInstanceId' ] ) {
224262 updateCdsConfigEnv ( runtimeValuesYaml , workloadKey , 'deploymentDefinition' , cdsConfigHana )
225263 }
226264
@@ -242,14 +280,6 @@ function updateWorkloadEnv(runtimeValuesYaml, valuesYaml, answerStruct) {
242280 }
243281}
244282
245- function getServiceInstanceKeyName ( serviceInstances , offeringName ) {
246- for ( const key in serviceInstances ) {
247- if ( serviceInstances [ key ] . serviceOfferingName === offeringName )
248- return key
249- }
250- return null
251- }
252-
253283function updateCdsConfigEnv ( runtimeValuesYaml , workloadKey , workloadDefintion , cdsConfigHana ) {
254284 const index = runtimeValuesYaml [ 'workloads' ] [ workloadKey ] [ workloadDefintion ] [ 'env' ] . findIndex ( e => e . name === 'CDS_CONFIG' )
255285 if ( index > - 1 ) {
@@ -285,7 +315,7 @@ async function getShootDomain() {
285315
286316 kubectl . on ( 'close' , ( ) => { resolve ( ) } )
287317 } )
288- } catch ( error ) { }
318+ } catch ( error ) { }
289319
290320 return domain
291321}
0 commit comments