1
+ """
2
+ This module creates IONOS clusters using the CLI
3
+ """
1
4
from modules .command import run_command
2
5
from time import sleep
3
6
4
-
5
7
def query_command_for_table (command , description ):
6
8
"""
7
9
Runs the given command and returns the results as a list of dicts
@@ -26,8 +28,16 @@ def query_command_for_table(command, description):
26
28
result .append ({ name : line [start :end ].strip () if end != - 1 else line [start :].strip () for (name , start , end ) in columns })
27
29
return (0 , result )
28
30
29
-
30
31
def create_datacenter (name , location , logger ):
32
+ """
33
+ Creates a datacenter
34
+
35
+ name name of the DC
36
+ location location, e.g. 'de/txl'
37
+ logger logger (String-consuming function)
38
+
39
+ Returns the IONOS-internal datacenter ID
40
+ """
31
41
command = f"ionosctl datacenter create --name { name } --location { location } "
32
42
exit_code , output = query_command_for_table (command , 'create datacenter' )
33
43
if exit_code != 0 :
@@ -36,8 +46,13 @@ def create_datacenter(name, location, logger):
36
46
return None
37
47
return output [0 ]['DatacenterId' ]
38
48
39
-
40
49
def get_datacenter (id , logger ):
50
+ """
51
+ Reads a datacenter by its IONOS-internal ID
52
+
53
+ id ID of the DC
54
+ logger logger (String-consuming function)
55
+ """
41
56
command = f"ionosctl datacenter list"
42
57
exit_code , output = query_command_for_table (command , 'list datacenters' )
43
58
if exit_code != 0 :
@@ -46,8 +61,13 @@ def get_datacenter(id, logger):
46
61
return None
47
62
return next (iter ([dc for dc in output if dc ['DatacenterId' ]== id ]), None )
48
63
49
-
50
64
def delete_datacenter (id , logger ):
65
+ """
66
+ Deletes a datacenter
67
+
68
+ id ID of the DC
69
+ logger logger (String-consuming function)
70
+ """
51
71
command = f"ionosctl datacenter delete --datacenter-id { id } --force"
52
72
exit_code , output = run_command (command , 'delete datacenter' )
53
73
if exit_code != 0 :
@@ -56,8 +76,15 @@ def delete_datacenter(id, logger):
56
76
return False
57
77
return True
58
78
59
-
60
79
def wait_for_datacenter_state (id , target_state , logger ):
80
+ """
81
+ Waits until a datacenter is in the desired state (blocking method)
82
+ Polls the CLI every 5 seconds.
83
+
84
+ id ID of the DC
85
+ target_state desired state
86
+ logger logger (String-consuming function)
87
+ """
61
88
datacenter = get_datacenter (id , logger )
62
89
state = datacenter ['State' ] if datacenter else None
63
90
logger (f"Datacenter { id } is in state { state } " )
@@ -67,8 +94,16 @@ def wait_for_datacenter_state(id, target_state, logger):
67
94
state = datacenter ['State' ] if datacenter else None
68
95
logger (f"Datacenter { id } is in state { state } " )
69
96
70
-
71
97
def ionosctl_create_cluster (name , k8s_version , logger ):
98
+ """
99
+ Creates a K8s cluster
100
+
101
+ name name of the cluster
102
+ k8s_version K8s version, e.g. '1.29.5'
103
+ logger logger (String-consuming function)
104
+
105
+ Returns the IONOS-internal cluster ID
106
+ """
72
107
command = f"ionosctl k8s cluster create --name { name } --k8s-version { k8s_version } "
73
108
exit_code , output = query_command_for_table (command , 'create cluster' )
74
109
if exit_code != 0 :
@@ -77,8 +112,13 @@ def ionosctl_create_cluster(name, k8s_version, logger):
77
112
return None
78
113
return output [0 ]['ClusterId' ]
79
114
80
-
81
115
def get_cluster (id , logger ):
116
+ """
117
+ Reads a K8s cluster by its IONOS-internal ID
118
+
119
+ id ID of the K8s cluster
120
+ logger logger (String-consuming function)
121
+ """
82
122
command = f"ionosctl k8s cluster list"
83
123
exit_code , output = query_command_for_table (command , 'list clusters' )
84
124
if exit_code != 0 :
@@ -87,8 +127,13 @@ def get_cluster(id, logger):
87
127
return None
88
128
return next (iter ([c for c in output if c ['ClusterId' ]== id ]), None )
89
129
90
-
91
130
def delete_cluster (id , logger ):
131
+ """
132
+ Deletes a K8s cluster
133
+
134
+ id ID of the K8s cluster
135
+ logger logger (String-consuming function)
136
+ """
92
137
command = f"ionosctl k8s cluster delete --cluster-id { id } --force"
93
138
exit_code , output = run_command (command , 'delete cluster' )
94
139
if exit_code != 0 :
@@ -97,8 +142,15 @@ def delete_cluster(id, logger):
97
142
return False
98
143
return True
99
144
100
-
101
145
def wait_for_cluster_state (id , target_state , logger ):
146
+ """
147
+ Waits until a K8s cluster is in the desired state (blocking method)
148
+ Polls the CLI every 5 seconds.
149
+
150
+ id ID of the cluster
151
+ target_state desired state
152
+ logger logger (String-consuming function)
153
+ """
102
154
cluster = get_cluster (id , logger )
103
155
state = cluster ['State' ] if cluster else None
104
156
logger (f"Cluster { id } is in state { state } " )
@@ -108,8 +160,22 @@ def wait_for_cluster_state(id, target_state, logger):
108
160
state = cluster ['State' ] if cluster else None
109
161
logger (f"Cluster { id } is in state { state } " )
110
162
111
-
112
163
def create_nodepool (name , cluster_id , datacenter_id , cores , node_count , ram , disk_type , disk_size , logger ):
164
+ """
165
+ Creates a K8s nodepool
166
+
167
+ name name of the cluster
168
+ cluster_id ID of cluster where this nodepool should be created at
169
+ datacenter_id ID of the datacenter to put nodepool into
170
+ cores number of cores per node
171
+ node_count number of nodes
172
+ ram RAM of each Node in MB
173
+ disk_type 'HDD' or 'SSD'
174
+ disk_size disk size in GB
175
+ logger logger (String-consuming function)
176
+
177
+ Returns the IONOS-internal nodepool ID
178
+ """
113
179
command = f"ionosctl k8s nodepool create --datacenter-id { datacenter_id } --cluster-id { cluster_id } --name { name } --cores { cores } --node-count { node_count } --ram { ram } --storage-type { disk_type } --storage-size { disk_size } "
114
180
exit_code , output = query_command_for_table (command , 'create nodepool' )
115
181
if exit_code != 0 :
@@ -118,8 +184,14 @@ def create_nodepool(name, cluster_id, datacenter_id, cores, node_count, ram, dis
118
184
return None
119
185
return output [0 ]['NodePoolId' ]
120
186
121
-
122
187
def get_nodepool (id , cluster_id , logger ):
188
+ """
189
+ Reads a K8s nodepool by its IONOS-internal ID
190
+
191
+ id ID of the nodepool
192
+ cluster_id ID of the K8s cluster
193
+ logger logger (String-consuming function)
194
+ """
123
195
command = f"ionosctl k8s nodepool list --cluster-id { cluster_id } "
124
196
exit_code , output = query_command_for_table (command , 'list nodepools' )
125
197
if exit_code != 0 :
@@ -128,8 +200,14 @@ def get_nodepool(id, cluster_id, logger):
128
200
return None
129
201
return next (iter ([n for n in output if n ['NodePoolId' ]== id ]), None )
130
202
131
-
132
203
def delete_nodepool (id , cluster_id , logger ):
204
+ """
205
+ Deletes a K8s nodepool
206
+
207
+ id ID of the nodepool
208
+ cluster_id ID of the K8s cluster
209
+ logger logger (String-consuming function)
210
+ """
133
211
command = f"ionosctl k8s nodepool delete --cluster-id { cluster_id } --nodepool-id { id } --force"
134
212
exit_code , output = run_command (command , 'delete nodepool' )
135
213
if exit_code != 0 :
@@ -138,8 +216,16 @@ def delete_nodepool(id, cluster_id, logger):
138
216
return False
139
217
return True
140
218
141
-
142
219
def wait_for_nodepool_state (id , cluster_id , target_state , logger ):
220
+ """
221
+ Waits until a K8s nodepool is in the desired state (blocking method)
222
+ Polls the CLI every 5 seconds.
223
+
224
+ id ID of the nodepool
225
+ cluster_id ID of the K8s cluster
226
+ target_state desired state
227
+ logger logger (String-consuming function)
228
+ """
143
229
nodepool = get_nodepool (id , cluster_id , logger )
144
230
state = nodepool ['State' ] if nodepool else None
145
231
logger (f"Nodepool { id } is in state { state } " )
@@ -149,22 +235,39 @@ def wait_for_nodepool_state(id, cluster_id, target_state, logger):
149
235
state = nodepool ['State' ] if nodepool else None
150
236
logger (f"Nodepool { id } is in state { state } " )
151
237
152
-
153
238
def update_kubeconfig (cluster_id , logger ):
239
+ """
240
+ Updates the kubeconfig (in default folder /root/.kube/config/) for the given cluster
241
+ """
154
242
exit_code , output = run_command (f"ionosctl k8s kubeconfig get --cluster-id { cluster_id } > /root/.kube/config" , 'update kubeconfig' )
155
243
if exit_code != 0 :
156
244
for line in output :
157
245
logger (line )
158
246
return False
159
247
return True
160
248
161
-
162
249
def write_cluster_info_file (cluster_info_file ):
250
+ """
251
+ Writes a file containing basic cluster information
252
+ """
163
253
run_command (f"kubectl get nodes > { cluster_info_file } " , 'kubectl get nodes' )
164
254
165
-
166
255
def create_cluster (id , spec , platform_version , cluster_info_file , logger ):
256
+ """
257
+ Creates an IONOS cluster with the given spec. (Blocking operation)
258
+
259
+ id UUID of the cluster
260
+ spec dict containing specification of cluster (vendor-specific)
261
+ platform_version version of the (K8s) platform
262
+ cluster_info_file file to write cluster-specific information into
263
+ logger logger (String-consuming function)
264
+
265
+ Returns vendor-specific cluster object.
266
+
267
+ If not cluster could be created, the reason is logged and None is returned.
268
+ """
167
269
270
+ # name is first 10 digits of ID
168
271
cluster_name = id [0 :10 ]
169
272
170
273
logger (f"Creating cluster { cluster_name } on IONOS..." )
@@ -210,9 +313,13 @@ def create_cluster(id, spec, platform_version, cluster_info_file, logger):
210
313
'nodepool_id' : nodepool_id
211
314
}
212
315
213
-
214
316
def terminate_cluster (id , logger ):
317
+ """
318
+ Terminates the given cluster. (Blocking operation)
215
319
320
+ id vendor-specific cluster object which was previously returned by create_cluster()
321
+ logger logger (String-consuming function)
322
+ """
216
323
if not delete_nodepool (id ['nodepool_id' ], id ['cluster_id' ], logger ):
217
324
logger ('Error deleting nodepool' )
218
325
return False
0 commit comments