15
15
*
16
16
*/
17
17
import { Task } from '../../core/task.js' ;
18
- import { Templates } from '../../core/templates.js' ;
19
18
import { Flags as flags } from '../flags.js' ;
20
19
import type { ListrTaskWrapper } from 'listr2' ;
20
+ import type { ConfigBuilder } from '../../types/aliases.js' ;
21
21
import { type BaseCommand } from '../base.js' ;
22
+ import { splitFlagInput } from '../../core/helpers.js' ;
22
23
23
24
export class ContextCommandTasks {
24
25
private readonly parent : BaseCommand ;
@@ -29,62 +30,150 @@ export class ContextCommandTasks {
29
30
30
31
updateLocalConfig ( argv ) {
31
32
return new Task ( 'Update local configuration' , async ( ctx : any , task : ListrTaskWrapper < any , any , any > ) => {
32
- this . parent . logger . info ( 'Updating local configuration...' ) ;
33
+ this . parent . logger . info ( 'Compare local and remote configuration...' ) ;
34
+ const configManager = this . parent . getConfigManager ( ) ;
35
+ const isQuiet = configManager . getFlag ( flags . quiet ) ;
33
36
34
- const isQuiet = ! ! argv [ flags . quiet . name ] ;
37
+ await this . parent . getRemoteConfigManager ( ) . modify ( async remoteConfig => {
38
+ // Update current deployment with cluster list from remoteConfig
39
+ const localConfig = this . parent . getLocalConfig ( ) ;
40
+ const localDeployments = localConfig . deployments ;
41
+ const remoteClusterList = [ ] ;
42
+ for ( const cluster of Object . keys ( remoteConfig . clusters ) ) {
43
+ if ( localConfig . currentDeploymentName === remoteConfig . clusters [ cluster ] ) {
44
+ remoteClusterList . push ( cluster ) ;
45
+ }
46
+ }
47
+ ctx . config . clusters = remoteClusterList ;
48
+ localDeployments [ localConfig . currentDeploymentName ] . clusters = ctx . config . clusters ;
49
+ localConfig . setDeployments ( localDeployments ) ;
35
50
36
- let currentDeploymentName = argv [ flags . namespace . name ] ;
37
- let clusters = Templates . parseClusterAliases ( argv [ flags . clusterName . name ] ) ;
38
- let contextName = argv [ flags . context . name ] ;
51
+ const contexts = splitFlagInput ( configManager . getFlag ( flags . context ) ) ;
39
52
40
- const kubeContexts = await this . parent . getK8 ( ) . getContexts ( ) ;
53
+ for ( let i = 0 ; i < ctx . config . clusters . length ; i ++ ) {
54
+ const cluster = ctx . config . clusters [ i ] ;
55
+ const context = contexts [ i ] ;
41
56
42
- if ( isQuiet ) {
43
- const currentCluster = await this . parent . getK8 ( ) . getKubeConfig ( ) . getCurrentCluster ( ) ;
44
- if ( ! clusters . length ) clusters = [ currentCluster . name ] ;
45
- if ( ! contextName ) contextName = await this . parent . getK8 ( ) . getKubeConfig ( ) . getCurrentContext ( ) ;
57
+ // If a context is provided use it to update the mapping
58
+ if ( context ) {
59
+ localConfig . clusterContextMapping [ cluster ] = context ;
60
+ } else if ( ! localConfig . clusterContextMapping [ cluster ] ) {
61
+ // In quiet mode use the currently selected context to update the mapping
62
+ if ( isQuiet ) {
63
+ localConfig . clusterContextMapping [ cluster ] = this . parent . getK8 ( ) . getKubeConfig ( ) . getCurrentContext ( ) ;
64
+ }
46
65
47
- if ( ! currentDeploymentName ) {
48
- const selectedContext = kubeContexts . find ( e => e . name === contextName ) ;
49
- currentDeploymentName = selectedContext && selectedContext . namespace ? selectedContext . namespace : 'default' ;
50
- }
51
- } else {
52
- if ( ! clusters . length ) {
53
- const prompt = flags . clusterName . prompt ;
54
- const unparsedClusterAliases = await prompt ( task , clusters ) ;
55
- clusters = Templates . parseClusterAliases ( unparsedClusterAliases ) ;
56
- }
57
- if ( ! contextName ) {
58
- const prompt = flags . context . prompt ;
59
- contextName = await prompt (
60
- task ,
61
- kubeContexts . map ( c => c . name ) ,
62
- ) ;
63
- }
64
- if ( ! currentDeploymentName ) {
65
- const prompt = flags . namespace . prompt ;
66
- currentDeploymentName = await prompt ( task , currentDeploymentName ) ;
66
+ // Prompt the user to select a context if mapping value is missing
67
+ else {
68
+ localConfig . clusterContextMapping [ cluster ] = await this . promptForContext ( task , cluster ) ;
69
+ }
70
+ }
67
71
}
72
+ this . parent . logger . info ( 'Update local configuration...' ) ;
73
+ await localConfig . write ( ) ;
74
+ } ) ;
75
+ } ) ;
76
+ }
77
+
78
+ private async getSelectedContext ( task , selectedCluster , localConfig , isQuiet ) {
79
+ let selectedContext ;
80
+ if ( isQuiet ) {
81
+ selectedContext = this . parent . getK8 ( ) . getKubeConfig ( ) . getCurrentContext ( ) ;
82
+ } else {
83
+ selectedContext = await this . promptForContext ( task , selectedCluster ) ;
84
+ localConfig . clusterContextMapping [ selectedCluster ] = selectedContext ;
85
+ }
86
+ return selectedContext ;
87
+ }
88
+
89
+ private async promptForContext ( task , cluster ) {
90
+ const kubeContexts = this . parent . getK8 ( ) . getContexts ( ) ;
91
+ return flags . context . prompt (
92
+ task ,
93
+ kubeContexts . map ( c => c . name ) ,
94
+ cluster ,
95
+ ) ;
96
+ }
97
+
98
+ private async selectContextForFirstCluster ( task , clusters , localConfig , isQuiet ) {
99
+ const selectedCluster = clusters [ 0 ] ;
100
+
101
+ if ( localConfig . clusterContextMapping [ selectedCluster ] ) {
102
+ return localConfig . clusterContextMapping [ selectedCluster ] ;
103
+ }
104
+
105
+ // If cluster does not exist in LocalConfig mapping prompt the user to select a context or use the current one
106
+ else {
107
+ return this . getSelectedContext ( task , selectedCluster , localConfig , isQuiet ) ;
108
+ }
109
+ }
110
+
111
+ selectContext ( argv ) {
112
+ return new Task ( 'Read local configuration settings' , async ( ctx : any , task : ListrTaskWrapper < any , any , any > ) => {
113
+ this . parent . logger . info ( 'Read local configuration settings...' ) ;
114
+ const configManager = this . parent . getConfigManager ( ) ;
115
+ const isQuiet = configManager . getFlag ( flags . quiet ) ;
116
+ const deploymentName : string = configManager . getFlag ( flags . namespace ) ;
117
+ let clusters = splitFlagInput ( configManager . getFlag ( flags . clusterName ) ) ;
118
+ const contexts = splitFlagInput ( configManager . getFlag ( flags . context ) ) ;
119
+ const localConfig = this . parent . getLocalConfig ( ) ;
120
+ let selectedContext ;
121
+
122
+ // If one or more contexts are provided use the first one
123
+ if ( contexts . length ) {
124
+ selectedContext = contexts [ 0 ] ;
68
125
}
69
126
70
- // Select current deployment
71
- this . parent . getLocalConfig ( ) . setCurrentDeployment ( currentDeploymentName ) ;
127
+ // If one or more clusters are provided use the first one to determine the context
128
+ // from the mapping in the LocalConfig
129
+ else if ( clusters . length ) {
130
+ selectedContext = await this . selectContextForFirstCluster ( task , clusters , localConfig , isQuiet ) ;
131
+ }
132
+
133
+ // If a deployment name is provided get the clusters associated with the deployment from the LocalConfig
134
+ // and select the context from the mapping, corresponding to the first deployment cluster
135
+ else if ( deploymentName ) {
136
+ const deployment = localConfig . deployments [ deploymentName ] ;
137
+
138
+ if ( deployment && deployment . clusters . length ) {
139
+ selectedContext = await this . selectContextForFirstCluster ( task , deployment . clusters , localConfig , isQuiet ) ;
140
+ }
72
141
73
- // Set clusters for active deployment
74
- const deployments = this . parent . getLocalConfig ( ) . deployments ;
75
- deployments [ currentDeploymentName ] . clusters = clusters ;
76
- this . parent . getLocalConfig ( ) . setDeployments ( deployments ) ;
142
+ // The provided deployment does not exist in the LocalConfig
143
+ else {
144
+ // Add the deployment to the LocalConfig with the currently selected cluster and context in KubeConfig
145
+ if ( isQuiet ) {
146
+ selectedContext = this . parent . getK8 ( ) . getKubeConfig ( ) . getCurrentContext ( ) ;
147
+ const selectedCluster = this . parent . getK8 ( ) . getKubeConfig ( ) . getCurrentCluster ( ) . name ;
148
+ localConfig . deployments [ deploymentName ] = {
149
+ clusters : [ selectedCluster ] ,
150
+ } ;
77
151
78
- this . parent . getK8 ( ) . getKubeConfig ( ) . setCurrentContext ( contextName ) ;
152
+ if ( ! localConfig . clusterContextMapping [ selectedCluster ] ) {
153
+ localConfig . clusterContextMapping [ selectedCluster ] = selectedContext ;
154
+ }
155
+ }
79
156
80
- this . parent . logger . info (
81
- `Save LocalConfig file: [currentDeploymentName: ${ currentDeploymentName } , contextName: ${ contextName } , clusters: ${ clusters . join ( ' ' ) } ]` ,
82
- ) ;
83
- await this . parent . getLocalConfig ( ) . write ( ) ;
157
+ // Prompt user for clusters and contexts
158
+ else {
159
+ clusters = splitFlagInput ( await flags . clusterName . prompt ( task , clusters ) ) ;
160
+
161
+ for ( const cluster of clusters ) {
162
+ if ( ! localConfig . clusterContextMapping [ cluster ] ) {
163
+ localConfig . clusterContextMapping [ cluster ] = await this . promptForContext ( task , cluster ) ;
164
+ }
165
+ }
166
+
167
+ selectedContext = localConfig . clusterContextMapping [ clusters [ 0 ] ] ;
168
+ }
169
+ }
170
+ }
171
+
172
+ this . parent . getK8 ( ) . getKubeConfig ( ) . setCurrentContext ( selectedContext ) ;
84
173
} ) ;
85
174
}
86
175
87
- initialize ( argv : any ) {
176
+ initialize ( argv : any , configInit : ConfigBuilder ) {
88
177
const { requiredFlags, optionalFlags} = argv ;
89
178
90
179
argv . flags = [ ...requiredFlags , ...optionalFlags ] ;
@@ -93,6 +182,8 @@ export class ContextCommandTasks {
93
182
if ( argv [ flags . devMode . name ] ) {
94
183
this . parent . logger . setDevMode ( true ) ;
95
184
}
185
+
186
+ ctx . config = await configInit ( argv , ctx , task ) ;
96
187
} ) ;
97
188
}
98
189
}
0 commit comments