Skip to content

Commit 5306a46

Browse files
committed
Proxmox list snapshots
1 parent 25bbeac commit 5306a46

File tree

4 files changed

+85
-35
lines changed

4 files changed

+85
-35
lines changed

engine/schema/src/main/resources/META-INF/db/schema-42010to42100.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,16 @@ BEGIN
408408
; END IF
409409
;END;
410410

411+
CALL `cloud`.`INSERT_EXTENSION_CUSTOM_ACTION_IF_NOT_EXISTS`('Proxmox', 'ListSnapshots', 'List Instance snapshots', 'VirtualMachine', 15, 'Snapshots fetched for {{resourceName}} in {{extensionName}}', 'List Snapshots failed for {{resourceName}}', 60);
411412
CALL `cloud`.`INSERT_EXTENSION_CUSTOM_ACTION_IF_NOT_EXISTS`('Proxmox', 'CreateSnapshot', 'Create an Instance snapshot', 'VirtualMachine', 15, 'Snapshot created for {{resourceName}} in {{extensionName}}', 'Snapshot creation failed for {{resourceName}}', 60);
412413
CALL `cloud`.`INSERT_EXTENSION_CUSTOM_ACTION_IF_NOT_EXISTS`('Proxmox', 'RestoreSnapshot', 'Restore Instance to the specifeid snapshot', 'VirtualMachine', 15, 'Successfully restored snapshot for {{resourceName}} in {{extensionName}}', 'Restore snapshot failed for {{resourceName}}', 60);
413414
CALL `cloud`.`INSERT_EXTENSION_CUSTOM_ACTION_IF_NOT_EXISTS`('Proxmox', 'DeleteSnapshot', 'Delete the specified snapshot', 'VirtualMachine', 15, 'Successfully deleted snapshot for {{resourceName}} in {{extensionName}}', 'Delete snapshot failed for {{resourceName}}', 60);
414415

416+
CALL `cloud.INSERT_EXTENSION_CUSTOM_ACTION_DETAILS_IF_NOT_EXISTS`(
417+
'Proxmox',
418+
'ListSnapshots',
419+
'[]'
420+
);
415421
CALL `cloud`.`INSERT_EXTENSION_CUSTOM_ACTION_DETAILS_IF_NOT_EXISTS`(
416422
'Proxmox',
417423
'CreateSnapshot',

extensions/HyperV/hyperv.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def parse_json(self):
5252
"network_switch": external_host_details["network_switch"],
5353
"vhd_path": external_host_details["vhd_path"],
5454
"vm_path": external_host_details["vm_path"],
55-
"cert_validation": "validate" if external_host_details.get("validate_tls_certificate", "false").lower() == "true" else "ignore"
55+
"cert_validation": "validate" if external_host_details.get("validate_ssl", "true").lower() == "true" else "ignore"
5656
}
5757

5858
external_vm_details = json_data["externaldetails"].get("virtualmachine", [])

extensions/Proxmox/proxmox.sh

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ parse_json() {
3434
"host_secret": (.externaldetails.host.secret // ""),
3535
"node": (.externaldetails.host.node // ""),
3636
"network_bridge": (.externaldetails.host.network_bridge // ""),
37+
"validate_ssl": (.externaldetails.host.validate_ssl // "true"),
3738
"vm_name": (.externaldetails.virtualmachine.vm_name // ""),
3839
"template_id": (.externaldetails.virtualmachine.template_id // ""),
3940
"template_type": (.externaldetails.virtualmachine.template_type // ""),
@@ -96,11 +97,23 @@ call_proxmox_api() {
9697
local path=$2
9798
local data=$3
9899

99-
#echo "curl -sk --fail -X $method -H \"Authorization: PVEAPIToken=${user}!${token}=${secret}\" ${data:+-d \"$data\"} https://${url}:8006/api2/json${path}" >&2
100-
response=$(curl -sk --fail -X "$method" \
101-
-H "Authorization: PVEAPIToken=${user}!${token}=${secret}" \
102-
${data:+-d "$data"} \
103-
"https://${url}:8006/api2/json${path}")
100+
curl_opts=(
101+
-s
102+
--fail
103+
-X "$method"
104+
-H "Authorization: PVEAPIToken=${user}!${token}=${secret}"
105+
)
106+
107+
if [[ "$validate_ssl" == "false" ]]; then
108+
curl_opts+=(-k)
109+
fi
110+
111+
if [[ -n "$data" ]]; then
112+
curl_opts+=(-d "$data")
113+
fi
114+
115+
#echo curl "${curl_opts[@]}" "https://${url}:8006/api2/json${path}" >&2
116+
response=$(curl "${curl_opts[@]}" "https://${url}:8006/api2/json${path}")
104117
echo "$response"
105118
}
106119

@@ -166,25 +179,21 @@ execute_and_wait() {
166179
}
167180

168181
prepare() {
169-
parse_json "$1" || exit 1
170-
171182
response=$(call_proxmox_api GET "/cluster/nextid")
172183
vmid=$(echo "$response" | jq -r '.data // ""')
173184

174185
echo "{\"details\":{\"proxmox_vmid\": \"$vmid\"}}"
175186
}
176187

177188
create() {
178-
parse_json "$1" || exit 1
179-
180189
if [[ -z "$vm_name" ]]; then
181190
vm_name="$vm_internal_name"
182191
fi
183192
validate_name "VM" "$vm_name"
184-
check_required_fields vmid network_bridge
193+
check_required_fields vmid network_bridge vmcpus vmmemory
185194

186195
if [[ "${template_type^^}" == "ISO" ]]; then
187-
check_required_fields iso_path vmcpus vmmemory
196+
check_required_fields iso_path
188197
local data="vmid=$vmid"
189198
data+="&name=$vm_name"
190199
data+="&ide2=$(urlencode "$iso_path,media=cdrom")"
@@ -196,12 +205,20 @@ create() {
196205
data+="&numa=0"
197206
data+="&cpu=x86-64-v2-AES"
198207
data+="&memory=$((vmmemory / 1024 / 1024))"
208+
199209
execute_and_wait POST "/nodes/${node}/qemu/" "$data"
210+
cleanup_vm=1
211+
200212
else
201213
check_required_fields template_id
202214
local data="newid=$vmid"
203215
data+="&name=$vm_name"
204216
execute_and_wait POST "/nodes/${node}/qemu/${template_id}/clone" "$data"
217+
cleanup_vm=1
218+
219+
data="cores=$vmcpus"
220+
data+="&memory=$((vmmemory / 1024 / 1024))"
221+
execute_and_wait POST "/nodes/${node}/qemu/${vmid}/config" "$data"
205222
fi
206223

207224
IFS=',' read -ra vlan_array <<< "$vlans"
@@ -213,36 +230,31 @@ create() {
213230

214231
execute_and_wait POST "/nodes/${node}/qemu/${vmid}/status/start"
215232

233+
cleanup_vm=0
216234
echo '{"status": "success", "message": "Instance created"}'
217235
}
218236

219237
start() {
220-
parse_json "$1" || exit 1
221238
execute_and_wait POST "/nodes/${node}/qemu/${vmid}/status/start"
222239
echo '{"status": "success", "message": "Instance started"}'
223240
}
224241

225242
delete() {
226-
parse_json "$1" || exit 1
227243
execute_and_wait DELETE "/nodes/${node}/qemu/${vmid}"
228244
echo '{"status": "success", "message": "Instance deleted"}'
229245
}
230246

231247
stop() {
232-
parse_json "$1" || exit 1
233248
execute_and_wait POST "/nodes/${node}/qemu/${vmid}/status/stop"
234249
echo '{"status": "success", "message": "Instance stopped"}'
235250
}
236251

237252
reboot() {
238-
parse_json "$1" || exit 1
239253
execute_and_wait POST "/nodes/${node}/qemu/${vmid}/status/reboot"
240254
echo '{"status": "success", "message": "Instance rebooted"}'
241255
}
242256

243257
status() {
244-
parse_json "$1" || exit 1
245-
246258
local status_response vm_status powerstate
247259
status_response=$(call_proxmox_api GET "/nodes/${node}/qemu/${vmid}/status/current")
248260
vm_status=$(echo "$status_response" | jq -r '.data.status')
@@ -255,13 +267,34 @@ status() {
255267
echo "{\"status\": \"success\", \"power_state\": \"$powerstate\"}"
256268
}
257269

258-
create_snapshot() {
259-
parse_json "$1" || exit 1
270+
list_snapshots() {
271+
snapshot_response=$(call_proxmox_api GET "/nodes/${node}/qemu/${vmid}/snapshot")
272+
echo "$snapshot_response" | jq '
273+
def to_date:
274+
if . == "-" then "-"
275+
elif . == null then "-"
276+
else (. | tonumber | strftime("%Y-%m-%d %H:%M:%S"))
277+
end;
278+
279+
{
280+
status: "success",
281+
print_message: "true",
282+
message: [.data[] | {
283+
name: .name,
284+
snaptime: ((.snaptime // "-") | to_date),
285+
description: .description,
286+
parent: (.parent // "-"),
287+
vmstate: (.vmstate // "-")
288+
}]
289+
}
290+
'
291+
}
260292

293+
create_snapshot() {
261294
check_required_fields snap_name
262295
validate_name "Snapshot" "$snap_name"
263296

264-
local data, vmstate
297+
local data vmstate
265298
data="snapname=$snap_name"
266299
if [[ -n "$snap_description" ]]; then
267300
data+="&description=$snap_description"
@@ -278,8 +311,6 @@ create_snapshot() {
278311
}
279312

280313
restore_snapshot() {
281-
parse_json "$1" || exit 1
282-
283314
check_required_fields snap_name
284315
validate_name "Snapshot" "$snap_name"
285316

@@ -291,8 +322,6 @@ restore_snapshot() {
291322
}
292323

293324
delete_snapshot() {
294-
parse_json "$1" || exit 1
295-
296325
check_required_fields snap_name
297326
validate_name "Snapshot" "$snap_name"
298327

@@ -312,36 +341,50 @@ fi
312341
# Read file content as parameters (assumes space-separated arguments)
313342
parameters=$(<"$parameters_file")
314343

344+
parse_json "$parameters" || exit 1
345+
346+
cleanup_vm=0
347+
cleanup() {
348+
if (( cleanup_vm == 1 )); then
349+
execute_and_wait DELETE "/nodes/${node}/qemu/${vmid}"
350+
fi
351+
}
352+
353+
trap cleanup EXIT
354+
315355
case $action in
316356
prepare)
317-
prepare "$parameters"
357+
prepare
318358
;;
319359
create)
320-
create "$parameters"
360+
create
321361
;;
322362
delete)
323-
delete "$parameters"
363+
delete
324364
;;
325365
start)
326-
start "$parameters"
366+
start
327367
;;
328368
stop)
329-
stop "$parameters"
369+
stop
330370
;;
331371
reboot)
332-
reboot "$parameters"
372+
reboot
333373
;;
334374
status)
335-
status "$parameters"
375+
status
376+
;;
377+
ListSnapshots)
378+
list_snapshots
336379
;;
337380
CreateSnapshot)
338-
create_snapshot "$parameters"
381+
create_snapshot
339382
;;
340383
RestoreSnapshot)
341-
restore_snapshot "$parameters"
384+
restore_snapshot
342385
;;
343386
DeleteSnapshot)
344-
delete_snapshot "$parameters"
387+
delete_snapshot
345388
;;
346389
*)
347390
echo '{"error":"Invalid action"}'

ui/src/views/extension/RunCustomAction.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ export default {
271271
h('table', {
272272
style: {
273273
marginTop: '1em',
274+
width: '100%',
274275
maxWidth: '100%',
275276
borderCollapse: 'collapse',
276277
backgroundColor: '#f6f6f6'

0 commit comments

Comments
 (0)