From 68d24d41c49256ac6483b76858319bc43f76f3d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D1=91=D1=82=D1=80=20=D0=9A=D1=80=D1=83=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= Date: Thu, 11 Aug 2022 08:09:54 +0000 Subject: [PATCH] Dev --- .golangci.yml | 21 ++ README.md | 129 +++------ account.go | 9 + account/account.go | 15 + account/add_user.go | 68 +++++ account/audits.go | 54 ++++ account/create.go | 65 +++++ account/delete.go | 52 ++++ account/delete_user.go | 58 ++++ account/disable_enable.go | 80 ++++++ account/get.go | 55 ++++ account/get_consumed_account_units.go | 55 ++++ account/get_consumed_cloud_units_by_type.go | 64 +++++ account/get_consumption.go | 83 ++++++ account/get_reserved_account_units.go | 55 ++++ account/list.go | 42 +++ account/list_computes.go | 55 ++++ account/list_deleted.go | 42 +++ account/list_disks.go | 55 ++++ account/list_flipgroups.go | 55 ++++ account/list_rg.go | 55 ++++ account/list_templates.go | 56 ++++ account/list_vins.go | 55 ++++ account/models.go | 229 ++++++++++++++++ account/restore.go | 53 ++++ account/update.go | 60 ++++ account/update_user.go | 68 +++++ bservice/bservice.go | 13 + bservice/create.go | 43 +++ bservice/delete.go | 37 +++ bservice/disable.go | 36 +++ bservice/enable.go | 36 +++ bservice/get.go | 41 +++ bservice/group_add.go | 75 +++++ bservice/group_compute_remove.go | 46 ++++ bservice/group_get.go | 46 ++++ bservice/group_parent_add.go | 46 ++++ bservice/group_parent_remove.go | 46 ++++ bservice/group_remove.go | 42 +++ bservice/group_resize.go | 52 ++++ bservice/group_start.go | 41 +++ bservice/group_stop.go | 42 +++ bservice/group_update.go | 47 ++++ bservice/group_update_extnet.go | 42 +++ bservice/group_update_vins.go | 42 +++ bservice/list.go | 46 ++++ bservice/models.go | 123 +++++++++ bservice/restore.go | 36 +++ bservice/snapshot_create.go | 41 +++ bservice/snapshot_delete.go | 41 +++ bservice/snapshot_list.go | 41 +++ bservice/snapshot_rollback.go | 41 +++ bservice/start.go | 36 +++ bservice/stop.go | 36 +++ client.go | 50 ++++ compute.go | 9 + compute/affinity_group_check_start.go | 49 ++++ compute/affinity_label_remove.go | 51 ++++ compute/affinity_label_set.go | 55 ++++ compute/affinity_relations.go | 54 ++++ compute/affinity_rule_add.go | 91 +++++++ compute/affinity_rule_remove.go | 91 +++++++ compute/affinity_rules_clear.go | 51 ++++ compute/anti_affinity_rule_add.go | 91 +++++++ compute/anti_affinity_rule_remove.go | 91 +++++++ compute/anti_affinity_rules_clear.go | 51 ++++ compute/attach_gpu.go | 56 ++++ compute/attach_pci_device.go | 56 ++++ compute/audits.go | 41 +++ compute/cd_eject.go | 50 ++++ compute/cd_insert.go | 54 ++++ compute/clone.go | 56 ++++ compute/compute.go | 15 + compute/create_template.go | 88 ++++++ compute/delete.go | 52 ++++ compute/detach_gpu.go | 52 ++++ compute/detach_pci_device.go | 56 ++++ compute/disable.go | 51 ++++ compute/disk_add.go | 66 +++++ compute/disk_attach.go | 56 ++++ compute/disk_del.go | 57 ++++ compute/disk_detach.go | 56 ++++ compute/disk_qos.go | 61 +++++ compute/disk_resize.go | 61 +++++ compute/enable.go | 51 ++++ compute/get.go | 52 ++++ compute/get_audits.go | 52 ++++ compute/get_console_url.go | 48 ++++ compute/get_log.go | 74 +++++ compute/list.go | 42 +++ compute/list_deleted.go | 41 +++ compute/list_pci_device.go | 53 ++++ compute/list_vgpu.go | 53 ++++ compute/models.go | 288 ++++++++++++++++++++ compute/move_to_rg.go | 57 ++++ compute/net_attach.go | 67 +++++ compute/net_detach.go | 52 ++++ compute/pause.go | 50 ++++ compute/pfw_add.go | 69 +++++ compute/pfw_del.go | 56 ++++ compute/pfw_list.go | 53 ++++ compute/pin_to_stack.go | 50 ++++ compute/power_cycle.go | 50 ++++ compute/reboot.go | 50 ++++ compute/redeploy.go | 55 ++++ compute/reset.go | 50 ++++ compute/resize.go | 53 ++++ compute/restore.go | 45 +++ compute/resume.go | 50 ++++ compute/snapshot_create.go | 52 ++++ compute/snapshot_delete.go | 55 ++++ compute/snapshot_list.go | 53 ++++ compute/snapshot_rollback.go | 55 ++++ compute/snapshot_usage.go | 54 ++++ compute/start.go | 51 ++++ compute/stop.go | 51 ++++ compute/tag_add.go | 59 ++++ compute/tag_remove.go | 54 ++++ compute/unpin_from_stack.go | 50 ++++ compute/update.go | 52 ++++ compute/user_grant.go | 65 +++++ compute/user_list.go | 49 ++++ compute/user_revoke.go | 55 ++++ compute/user_update.go | 65 +++++ computeci.go | 9 + computeci/computeci.go | 15 + computeci/get.go | 41 +++ computeci/list.go | 30 ++ computeci/models.go | 14 + config.go | 10 + disks.go | 9 + disks/create.go | 77 ++++++ disks/delete.go | 53 ++++ disks/delete_disks.go | 55 ++++ disks/disks.go | 15 + disks/get.go | 55 ++++ disks/limitio.go | 67 +++++ disks/list.go | 72 +++++ disks/list_types.go | 41 +++ disks/list_unattached.go | 41 +++ disks/models.go | 116 ++++++++ disks/rename.go | 58 ++++ disks/resize.go | 89 ++++++ disks/restore.go | 58 ++++ disks/search.go | 43 +++ disks/snapshot_delete.go | 58 ++++ disks/snapshot_rollback.go | 59 ++++ extnet.go | 9 + extnet/extnet.go | 15 + extnet/get.go | 53 ++++ extnet/get_default.go | 35 +++ extnet/list.go | 42 +++ extnet/list_computes.go | 49 ++++ extnet/models.go | 80 ++++++ flipgroup.go | 9 + flipgroup/compute_add.go | 45 +++ flipgroup/compute_remove.go | 45 +++ flipgroup/create.go | 63 +++++ flipgroup/delete.go | 41 +++ flipgroup/edit.go | 43 +++ flipgroup/flipgroup.go | 15 + flipgroup/get.go | 42 +++ flipgroup/list.go | 29 ++ flipgroup/models.go | 40 +++ go.mod | 5 + go.sum | 5 + http-client.go | 25 ++ image.go | 9 + image/create.go | 102 +++++++ image/create_virtual.go | 58 ++++ image/delete.go | 54 ++++ image/get.go | 54 ++++ image/image.go | 15 + image/link.go | 57 ++++ image/list.go | 42 +++ image/models.go | 68 +++++ image/rename.go | 58 ++++ interfaces/caller.go | 7 + internal/validators/helper.go | 10 + k8ci.go | 9 + k8ci/get.go | 41 +++ k8ci/k8ci.go | 15 + k8ci/list.go | 30 ++ k8ci/list_deleted.go | 29 ++ k8ci/models.go | 15 + k8s.go | 9 + k8s/create.go | 75 +++++ k8s/delete.go | 51 ++++ k8s/delete_master_from_group.go | 59 ++++ k8s/delete_worker_from_group.go | 59 ++++ k8s/disable_enable.go | 78 ++++++ k8s/find_group_by_label.go | 59 ++++ k8s/get.go | 53 ++++ k8s/get_config.go | 45 +++ k8s/get_node_annotations.go | 49 ++++ k8s/get_node_taints.go | 49 ++++ k8s/k8s.go | 15 + k8s/list.go | 42 +++ k8s/list_deleted.go | 41 +++ k8s/models.go | 119 ++++++++ k8s/restore.go | 50 ++++ k8s/start.go | 50 ++++ k8s/stop.go | 50 ++++ k8s/update.go | 52 ++++ k8s/worker_add.go | 60 ++++ k8s/worker_reset.go | 60 ++++ k8s/worker_restart.go | 60 ++++ k8s/workers_group_add.go | 74 +++++ k8s/workers_group_delete.go | 55 ++++ k8s/workers_group_get_by_name.go | 58 ++++ kvmppc.go | 7 + kvmppc/create.go | 79 ++++++ kvmppc/create_blank.go | 80 ++++++ kvmppc/kvmppc.go | 15 + kvmx86.go | 9 + kvmx86/create.go | 79 ++++++ kvmx86/create_blank.go | 80 ++++++ kvmx86/kvmx86.go | 15 + lb.go | 7 + lb/backend_create.go | 66 +++++ lb/backend_delete.go | 57 ++++ lb/backend_server_add.go | 81 ++++++ lb/backend_server_delete.go | 62 +++++ lb/backend_server_update.go | 81 ++++++ lb/backend_update.go | 66 +++++ lb/config_reset.go | 52 ++++ lb/create.go | 64 +++++ lb/delete.go | 53 ++++ lb/disable_enable.go | 82 ++++++ lb/frontend_bind.go | 59 ++++ lb/frontend_bind_delete.go | 57 ++++ lb/frontend_bind_update.go | 59 ++++ lb/frontend_create.go | 62 +++++ lb/frontend_delete.go | 57 ++++ lb/get.go | 54 ++++ lb/lb.go | 15 + lb/list.go | 42 +++ lb/list_deleted.go | 41 +++ lb/models.go | 89 ++++++ lb/restart.go | 52 ++++ lb/restore.go | 52 ++++ lb/update.go | 56 ++++ locations/get_url.go | 28 ++ locations/list.go | 41 +++ locations/locations.go | 15 + locations/models.go | 14 + locatons.go | 7 + opts/decort_opts.go | 6 + opts/opts.go | 26 ++ rg.go | 7 + rg/access_grant.go | 48 ++++ rg/access_revoke.go | 42 +++ rg/affinity_group_computes.go | 46 ++++ rg/affinity_groups_get.go | 46 ++++ rg/affinity_groups_list.go | 41 +++ rg/audits.go | 41 +++ rg/create.go | 59 ++++ rg/delete.go | 39 +++ rg/disable.go | 37 +++ rg/enable.go | 37 +++ rg/get.go | 42 +++ rg/list.go | 30 ++ rg/list_computes.go | 42 +++ rg/list_deleted.go | 29 ++ rg/list_lb.go | 41 +++ rg/list_pfw.go | 41 +++ rg/list_vins.go | 42 +++ rg/models.go | 234 ++++++++++++++++ rg/restore.go | 37 +++ rg/rg.go | 15 + rg/set_def_net.go | 44 +++ rg/update.go | 45 +++ rg/usage.go | 42 +++ sizes.go | 9 + sizes/list.go | 31 +++ sizes/models.go | 12 + sizes/sizes.go | 15 + tasks.go | 9 + tasks/get.go | 54 ++++ tasks/list.go | 41 +++ tasks/models.go | 51 ++++ tasks/tasks.go | 15 + transport.go | 65 +++++ typed/typed.go | 6 + vins.go | 9 + vins/audits.go | 54 ++++ vins/create_in_account.go | 61 +++++ vins/create_in_rg.go | 62 +++++ vins/delete.go | 54 ++++ vins/disable_enable.go | 84 ++++++ vins/extnet_connect.go | 54 ++++ vins/extnet_disconnect.go | 52 ++++ vins/extnet_list.go | 49 ++++ vins/get.go | 55 ++++ vins/ip_list.go | 54 ++++ vins/ip_release.go | 55 ++++ vins/ip_reserve.go | 55 ++++ vins/list.go | 42 +++ vins/list_deleted.go | 41 +++ vins/models.go | 271 ++++++++++++++++++ vins/nat_rule_add.go | 70 +++++ vins/nat_rule_del.go | 58 ++++ vins/nat_rule_list.go | 47 ++++ vins/restore.go | 53 ++++ vins/search.go | 43 +++ vins/vins.go | 15 + vins/vnfdev_redeploy.go | 53 ++++ vins/vnfdev_restart.go | 53 ++++ 308 files changed, 15476 insertions(+), 91 deletions(-) create mode 100644 .golangci.yml create mode 100644 account.go create mode 100644 account/account.go create mode 100644 account/add_user.go create mode 100644 account/audits.go create mode 100644 account/create.go create mode 100644 account/delete.go create mode 100644 account/delete_user.go create mode 100644 account/disable_enable.go create mode 100644 account/get.go create mode 100644 account/get_consumed_account_units.go create mode 100644 account/get_consumed_cloud_units_by_type.go create mode 100644 account/get_consumption.go create mode 100644 account/get_reserved_account_units.go create mode 100644 account/list.go create mode 100644 account/list_computes.go create mode 100644 account/list_deleted.go create mode 100644 account/list_disks.go create mode 100644 account/list_flipgroups.go create mode 100644 account/list_rg.go create mode 100644 account/list_templates.go create mode 100644 account/list_vins.go create mode 100644 account/models.go create mode 100644 account/restore.go create mode 100644 account/update.go create mode 100644 account/update_user.go create mode 100644 bservice/bservice.go create mode 100644 bservice/create.go create mode 100644 bservice/delete.go create mode 100644 bservice/disable.go create mode 100644 bservice/enable.go create mode 100644 bservice/get.go create mode 100644 bservice/group_add.go create mode 100644 bservice/group_compute_remove.go create mode 100644 bservice/group_get.go create mode 100644 bservice/group_parent_add.go create mode 100644 bservice/group_parent_remove.go create mode 100644 bservice/group_remove.go create mode 100644 bservice/group_resize.go create mode 100644 bservice/group_start.go create mode 100644 bservice/group_stop.go create mode 100644 bservice/group_update.go create mode 100644 bservice/group_update_extnet.go create mode 100644 bservice/group_update_vins.go create mode 100644 bservice/list.go create mode 100644 bservice/models.go create mode 100644 bservice/restore.go create mode 100644 bservice/snapshot_create.go create mode 100644 bservice/snapshot_delete.go create mode 100644 bservice/snapshot_list.go create mode 100644 bservice/snapshot_rollback.go create mode 100644 bservice/start.go create mode 100644 bservice/stop.go create mode 100644 client.go create mode 100644 compute.go create mode 100644 compute/affinity_group_check_start.go create mode 100644 compute/affinity_label_remove.go create mode 100644 compute/affinity_label_set.go create mode 100644 compute/affinity_relations.go create mode 100644 compute/affinity_rule_add.go create mode 100644 compute/affinity_rule_remove.go create mode 100644 compute/affinity_rules_clear.go create mode 100644 compute/anti_affinity_rule_add.go create mode 100644 compute/anti_affinity_rule_remove.go create mode 100644 compute/anti_affinity_rules_clear.go create mode 100644 compute/attach_gpu.go create mode 100644 compute/attach_pci_device.go create mode 100644 compute/audits.go create mode 100644 compute/cd_eject.go create mode 100644 compute/cd_insert.go create mode 100644 compute/clone.go create mode 100644 compute/compute.go create mode 100644 compute/create_template.go create mode 100644 compute/delete.go create mode 100644 compute/detach_gpu.go create mode 100644 compute/detach_pci_device.go create mode 100644 compute/disable.go create mode 100644 compute/disk_add.go create mode 100644 compute/disk_attach.go create mode 100644 compute/disk_del.go create mode 100644 compute/disk_detach.go create mode 100644 compute/disk_qos.go create mode 100644 compute/disk_resize.go create mode 100644 compute/enable.go create mode 100644 compute/get.go create mode 100644 compute/get_audits.go create mode 100644 compute/get_console_url.go create mode 100644 compute/get_log.go create mode 100644 compute/list.go create mode 100644 compute/list_deleted.go create mode 100644 compute/list_pci_device.go create mode 100644 compute/list_vgpu.go create mode 100644 compute/models.go create mode 100644 compute/move_to_rg.go create mode 100644 compute/net_attach.go create mode 100644 compute/net_detach.go create mode 100644 compute/pause.go create mode 100644 compute/pfw_add.go create mode 100644 compute/pfw_del.go create mode 100644 compute/pfw_list.go create mode 100644 compute/pin_to_stack.go create mode 100644 compute/power_cycle.go create mode 100644 compute/reboot.go create mode 100644 compute/redeploy.go create mode 100644 compute/reset.go create mode 100644 compute/resize.go create mode 100644 compute/restore.go create mode 100644 compute/resume.go create mode 100644 compute/snapshot_create.go create mode 100644 compute/snapshot_delete.go create mode 100644 compute/snapshot_list.go create mode 100644 compute/snapshot_rollback.go create mode 100644 compute/snapshot_usage.go create mode 100644 compute/start.go create mode 100644 compute/stop.go create mode 100644 compute/tag_add.go create mode 100644 compute/tag_remove.go create mode 100644 compute/unpin_from_stack.go create mode 100644 compute/update.go create mode 100644 compute/user_grant.go create mode 100644 compute/user_list.go create mode 100644 compute/user_revoke.go create mode 100644 compute/user_update.go create mode 100644 computeci.go create mode 100644 computeci/computeci.go create mode 100644 computeci/get.go create mode 100644 computeci/list.go create mode 100644 computeci/models.go create mode 100644 config.go create mode 100644 disks.go create mode 100644 disks/create.go create mode 100644 disks/delete.go create mode 100644 disks/delete_disks.go create mode 100644 disks/disks.go create mode 100644 disks/get.go create mode 100644 disks/limitio.go create mode 100644 disks/list.go create mode 100644 disks/list_types.go create mode 100644 disks/list_unattached.go create mode 100644 disks/models.go create mode 100644 disks/rename.go create mode 100644 disks/resize.go create mode 100644 disks/restore.go create mode 100644 disks/search.go create mode 100644 disks/snapshot_delete.go create mode 100644 disks/snapshot_rollback.go create mode 100644 extnet.go create mode 100644 extnet/extnet.go create mode 100644 extnet/get.go create mode 100644 extnet/get_default.go create mode 100644 extnet/list.go create mode 100644 extnet/list_computes.go create mode 100644 extnet/models.go create mode 100644 flipgroup.go create mode 100644 flipgroup/compute_add.go create mode 100644 flipgroup/compute_remove.go create mode 100644 flipgroup/create.go create mode 100644 flipgroup/delete.go create mode 100644 flipgroup/edit.go create mode 100644 flipgroup/flipgroup.go create mode 100644 flipgroup/get.go create mode 100644 flipgroup/list.go create mode 100644 flipgroup/models.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 http-client.go create mode 100644 image.go create mode 100644 image/create.go create mode 100644 image/create_virtual.go create mode 100644 image/delete.go create mode 100644 image/get.go create mode 100644 image/image.go create mode 100644 image/link.go create mode 100644 image/list.go create mode 100644 image/models.go create mode 100644 image/rename.go create mode 100644 interfaces/caller.go create mode 100644 internal/validators/helper.go create mode 100644 k8ci.go create mode 100644 k8ci/get.go create mode 100644 k8ci/k8ci.go create mode 100644 k8ci/list.go create mode 100644 k8ci/list_deleted.go create mode 100644 k8ci/models.go create mode 100644 k8s.go create mode 100644 k8s/create.go create mode 100644 k8s/delete.go create mode 100644 k8s/delete_master_from_group.go create mode 100644 k8s/delete_worker_from_group.go create mode 100644 k8s/disable_enable.go create mode 100644 k8s/find_group_by_label.go create mode 100644 k8s/get.go create mode 100644 k8s/get_config.go create mode 100644 k8s/get_node_annotations.go create mode 100644 k8s/get_node_taints.go create mode 100644 k8s/k8s.go create mode 100644 k8s/list.go create mode 100644 k8s/list_deleted.go create mode 100644 k8s/models.go create mode 100644 k8s/restore.go create mode 100644 k8s/start.go create mode 100644 k8s/stop.go create mode 100644 k8s/update.go create mode 100644 k8s/worker_add.go create mode 100644 k8s/worker_reset.go create mode 100644 k8s/worker_restart.go create mode 100644 k8s/workers_group_add.go create mode 100644 k8s/workers_group_delete.go create mode 100644 k8s/workers_group_get_by_name.go create mode 100644 kvmppc.go create mode 100644 kvmppc/create.go create mode 100644 kvmppc/create_blank.go create mode 100644 kvmppc/kvmppc.go create mode 100644 kvmx86.go create mode 100644 kvmx86/create.go create mode 100644 kvmx86/create_blank.go create mode 100644 kvmx86/kvmx86.go create mode 100644 lb.go create mode 100644 lb/backend_create.go create mode 100644 lb/backend_delete.go create mode 100644 lb/backend_server_add.go create mode 100644 lb/backend_server_delete.go create mode 100644 lb/backend_server_update.go create mode 100644 lb/backend_update.go create mode 100644 lb/config_reset.go create mode 100644 lb/create.go create mode 100644 lb/delete.go create mode 100644 lb/disable_enable.go create mode 100644 lb/frontend_bind.go create mode 100644 lb/frontend_bind_delete.go create mode 100644 lb/frontend_bind_update.go create mode 100644 lb/frontend_create.go create mode 100644 lb/frontend_delete.go create mode 100644 lb/get.go create mode 100644 lb/lb.go create mode 100644 lb/list.go create mode 100644 lb/list_deleted.go create mode 100644 lb/models.go create mode 100644 lb/restart.go create mode 100644 lb/restore.go create mode 100644 lb/update.go create mode 100644 locations/get_url.go create mode 100644 locations/list.go create mode 100644 locations/locations.go create mode 100644 locations/models.go create mode 100644 locatons.go create mode 100644 opts/decort_opts.go create mode 100644 opts/opts.go create mode 100644 rg.go create mode 100644 rg/access_grant.go create mode 100644 rg/access_revoke.go create mode 100644 rg/affinity_group_computes.go create mode 100644 rg/affinity_groups_get.go create mode 100644 rg/affinity_groups_list.go create mode 100644 rg/audits.go create mode 100644 rg/create.go create mode 100644 rg/delete.go create mode 100644 rg/disable.go create mode 100644 rg/enable.go create mode 100644 rg/get.go create mode 100644 rg/list.go create mode 100644 rg/list_computes.go create mode 100644 rg/list_deleted.go create mode 100644 rg/list_lb.go create mode 100644 rg/list_pfw.go create mode 100644 rg/list_vins.go create mode 100644 rg/models.go create mode 100644 rg/restore.go create mode 100644 rg/rg.go create mode 100644 rg/set_def_net.go create mode 100644 rg/update.go create mode 100644 rg/usage.go create mode 100644 sizes.go create mode 100644 sizes/list.go create mode 100644 sizes/models.go create mode 100644 sizes/sizes.go create mode 100644 tasks.go create mode 100644 tasks/get.go create mode 100644 tasks/list.go create mode 100644 tasks/models.go create mode 100644 tasks/tasks.go create mode 100644 transport.go create mode 100644 typed/typed.go create mode 100644 vins.go create mode 100644 vins/audits.go create mode 100644 vins/create_in_account.go create mode 100644 vins/create_in_rg.go create mode 100644 vins/delete.go create mode 100644 vins/disable_enable.go create mode 100644 vins/extnet_connect.go create mode 100644 vins/extnet_disconnect.go create mode 100644 vins/extnet_list.go create mode 100644 vins/get.go create mode 100644 vins/ip_list.go create mode 100644 vins/ip_release.go create mode 100644 vins/ip_reserve.go create mode 100644 vins/list.go create mode 100644 vins/list_deleted.go create mode 100644 vins/models.go create mode 100644 vins/nat_rule_add.go create mode 100644 vins/nat_rule_del.go create mode 100644 vins/nat_rule_list.go create mode 100644 vins/restore.go create mode 100644 vins/search.go create mode 100644 vins/vins.go create mode 100644 vins/vnfdev_redeploy.go create mode 100644 vins/vnfdev_restart.go diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..e0b92a5 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,21 @@ +linters: + enable: + - bodyclose + - decorder + - dogsled + - errorlint + - exportloopref + - gocognit + - goconst + - gocyclo + - gosec + - ifshort + - makezero + - nestif + - nilerr + - prealloc + - unconvert + - unparam + +issues: + max-same-issues: 0 diff --git a/README.md b/README.md index 14d5115..4861989 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,39 @@ -# Decort Sdk - -SDK для разработки приложений на платформе decort - -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - +# Decort SDK + +```go +package main + +import ( + "context" + "fmt" + "log" + + decort "github.com/rudecs/decort-sdk" + "github.com/rudecs/decort-sdk/kvmx86" +) + +func main() { + cfg := decort.Config{ + AppID: "", + AppSecret: "", + SSOURL: "https://sso.digitalenergy.online", + DecortURL: "https://mr4.digitalenergy.online", + Retries: 5, + } + client := decort.New(cfg) + req := kvmx86.CreateRequest{ + RGID: 123, + Name: "compute", + CPU: 4, + RAM: 4096, + ImageID: 321, + } + + res, err := client.KVMX86().Create(context.Background(), req) + if err != nil { + log.Fatal(err) + } + + fmt.Println(res) +} ``` -cd existing_repo -git remote add origin https://gitlab.decs.local/rudecs/decort-sdk.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.decs.local/rudecs/decort-sdk/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/account.go b/account.go new file mode 100644 index 0000000..c6bce94 --- /dev/null +++ b/account.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/account" +) + +func (dc *decortClient) Account() *account.Account { + return account.New(dc) +} diff --git a/account/account.go b/account/account.go new file mode 100644 index 0000000..93d53f4 --- /dev/null +++ b/account/account.go @@ -0,0 +1,15 @@ +package account + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Account struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Account { + return &Account{ + client, + } +} diff --git a/account/add_user.go b/account/add_user.go new file mode 100644 index 0000000..d5256be --- /dev/null +++ b/account/add_user.go @@ -0,0 +1,68 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AddUserRequest struct { + AccountId uint64 `url:"accountId"` + UserId string `url:"userId"` + AccessType string `url:"accesstype"` +} + +func (arq AddUserRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + if arq.UserId == "" { + return errors.New("validation-error: field UserId can not be empty") + } + + if arq.AccessType == "" { + return errors.New("validation-error: field AccessType can not be empty") + } + + isValid := validators.StringInSlice(arq.AccessType, []string{"R", "RCX", "ARCXDU"}) + if !isValid { + return errors.New("validation-error: field AccessType can be only R, RCX or ARCXDU") + } + + return nil +} + +func (a Account) AddUser(ctx context.Context, req AddUserRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/account/addUser" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/account/audits.go b/account/audits.go new file mode 100644 index 0000000..1757666 --- /dev/null +++ b/account/audits.go @@ -0,0 +1,54 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AuditsRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq AuditsRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) Audits(ctx context.Context, req AuditsRequest, options ...opts.DecortOpts) (AccountAuditsList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/audits" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + auditsRaw, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + audits := AccountAuditsList{} + + err = json.Unmarshal([]byte(auditsRaw), &audits) + if err != nil { + return nil, err + } + + return audits, nil +} diff --git a/account/create.go b/account/create.go new file mode 100644 index 0000000..412dd8f --- /dev/null +++ b/account/create.go @@ -0,0 +1,65 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + Name string `url:"name"` + Username string `url:"username"` + EmailAddress string `url:"emailaddress,omitempty"` + MaxMemoryCapacity uint `url:"maxMemoryCapacity,omitempty"` + MaxVDiskCapacity uint `url:"maxVDiskCapacity,omitempty"` + MaxCPUCapacity uint `url:"maxCPUCapacity,omitempty"` + MaxNetworkPeerTransfer uint `url:"maxNetworkPeerTransfer,omitempty"` + MaxNumPublicIP uint `url:"maxNumPublicIP,omitempty"` + SendAccessEmails bool `url:"sendAccessEmails,omitempty"` + GpuUnits uint `url:"gpu_units,omitempty"` +} + +func (arq CreateRequest) Validate() error { + if arq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + if arq.Username == "" { + return errors.New("validation-error: field Username can not be empty") + } + + return nil +} + +func (a Account) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/account/create" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + + return result, nil +} diff --git a/account/delete.go b/account/delete.go new file mode 100644 index 0000000..38d3531 --- /dev/null +++ b/account/delete.go @@ -0,0 +1,52 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + AccountId uint64 `url:"accountId"` + Permanently bool `url:"permanently,omitempty"` +} + +func (arq DeleteRequest) Validate() error { + + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId must be set") + } + return nil +} + +func (a Account) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/account/delete" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/account/delete_user.go b/account/delete_user.go new file mode 100644 index 0000000..54abdb9 --- /dev/null +++ b/account/delete_user.go @@ -0,0 +1,58 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteUserRequest struct { + AccountId uint64 `url:"accountId"` + UserId string `url:"userId"` + RecursiveDelete bool `url:"recursivedelete,omitempty"` +} + +func (arq DeleteUserRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + if arq.UserId == "" { + return errors.New("validation-error: field UserId can not be empty") + } + + return nil +} + +func (a Account) DeleteUser(ctx context.Context, req DeleteUserRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/account/deleteUser" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/account/disable_enable.go b/account/disable_enable.go new file mode 100644 index 0000000..58b0ea0 --- /dev/null +++ b/account/disable_enable.go @@ -0,0 +1,80 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DisabelEnableRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq DisabelEnableRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) Disable(ctx context.Context, req DisabelEnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/account/disable" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} + +func (a Account) Enable(ctx context.Context, req DisabelEnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/account/enable" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/account/get.go b/account/get.go new file mode 100644 index 0000000..6512d4f --- /dev/null +++ b/account/get.go @@ -0,0 +1,55 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq GetRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*AccountWithResources, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/get" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + account := &AccountWithResources{} + + err = json.Unmarshal(res, &account) + if err != nil { + return nil, err + } + + return account, nil + +} diff --git a/account/get_consumed_account_units.go b/account/get_consumed_account_units.go new file mode 100644 index 0000000..14a3e79 --- /dev/null +++ b/account/get_consumed_account_units.go @@ -0,0 +1,55 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetConsumedAccountUnitsRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq GetConsumedAccountUnitsRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) GetConsumedAccountUnits(ctx context.Context, req GetConsumedAccountUnitsRequest, options ...opts.DecortOpts) (*ResourceLimits, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/getConsumedAccountUnits" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + rl := &ResourceLimits{} + + err = json.Unmarshal(res, &rl) + if err != nil { + return nil, err + } + + return rl, nil + +} diff --git a/account/get_consumed_cloud_units_by_type.go b/account/get_consumed_cloud_units_by_type.go new file mode 100644 index 0000000..e6a432c --- /dev/null +++ b/account/get_consumed_cloud_units_by_type.go @@ -0,0 +1,64 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetConsumedCloudUnitsByTypeRequest struct { + AccountId uint64 `url:"accountId"` + CUType string `url:"cutype"` +} + +func (arq GetConsumedCloudUnitsByTypeRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + if arq.CUType == "" { + return errors.New("validation-error: field CUType can not be empty") + } + + isValid := validators.StringInSlice(arq.CUType, []string{"CU_M", "CU_C", "CU_D", "CU_S", "CU_A", "CU_NO", "CU_I", "CU_NP"}) + if !isValid { + return errors.New("validation-error: field AccessType can be only CU_M, CU_C, CU_D, CU_S, CU_A, CU_NO, CU_I or CU_NP") + } + + return nil +} + +func (a Account) GetConsumedCloudUnitsByType(ctx context.Context, req GetConsumedCloudUnitsByTypeRequest, options ...opts.DecortOpts) (float64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/account/getConsumedCloudUnitsByType" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseFloat(string(res), 64) + if err != nil { + return 0, err + } + + return result, nil + +} diff --git a/account/get_consumption.go b/account/get_consumption.go new file mode 100644 index 0000000..c97cb86 --- /dev/null +++ b/account/get_consumption.go @@ -0,0 +1,83 @@ +package account + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetConsumtionRequest struct { + AccountId uint64 `url:"accountId"` + Start uint64 `url:"start"` + End uint64 `url:"end"` +} + +func (arq GetConsumtionRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + if arq.Start == 0 { + return errors.New("validation-error: field Start can not be empty or equal to 0") + } + + if arq.End == 0 { + return errors.New("validation-error: field End can not be empty or equal to 0") + } + + return nil +} + +func (a Account) GetConsumtion(ctx context.Context, req GetConsumtionRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/account/getConsumtion" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil + +} + +func (a Account) GetConsumtionGet(ctx context.Context, req GetConsumtionRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/account/getConsumtion" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.GET, url, req) + if err != nil { + return "", err + } + + return string(res), nil + +} diff --git a/account/get_reserved_account_units.go b/account/get_reserved_account_units.go new file mode 100644 index 0000000..37caf7a --- /dev/null +++ b/account/get_reserved_account_units.go @@ -0,0 +1,55 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetReservedAccountUnitsRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq GetReservedAccountUnitsRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) GetReservedAccountUnits(ctx context.Context, req GetReservedAccountUnitsRequest, options ...opts.DecortOpts) (*ResourceLimits, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/getReservedAccountUnits" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + rl := &ResourceLimits{} + + err = json.Unmarshal(res, &rl) + if err != nil { + return nil, err + } + + return rl, nil + +} diff --git a/account/list.go b/account/list.go new file mode 100644 index 0000000..e083c69 --- /dev/null +++ b/account/list.go @@ -0,0 +1,42 @@ +package account + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (a Account) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (AccountCloudApiList, error) { + url := "/account/list" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + accountList := AccountCloudApiList{} + + err = json.Unmarshal(res, &accountList) + if err != nil { + return nil, err + } + + return accountList, nil + +} diff --git a/account/list_computes.go b/account/list_computes.go new file mode 100644 index 0000000..fa29a88 --- /dev/null +++ b/account/list_computes.go @@ -0,0 +1,55 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListComputesRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq ListComputesRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) ListComputes(ctx context.Context, req ListComputesRequest, options ...opts.DecortOpts) (AccountComputesList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/listComputes" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + accountComputesList := AccountComputesList{} + + err = json.Unmarshal(res, &accountComputesList) + if err != nil { + return nil, err + } + + return accountComputesList, nil + +} diff --git a/account/list_deleted.go b/account/list_deleted.go new file mode 100644 index 0000000..972c164 --- /dev/null +++ b/account/list_deleted.go @@ -0,0 +1,42 @@ +package account + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListDeletedRequest struct { + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (a Account) ListDeleted(ctx context.Context, req ListDeletedRequest, options ...opts.DecortOpts) (AccountCloudApiList, error) { + url := "/account/listDeleted" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + accountList := AccountCloudApiList{} + + err = json.Unmarshal(res, &accountList) + if err != nil { + return nil, err + } + + return accountList, nil + +} diff --git a/account/list_disks.go b/account/list_disks.go new file mode 100644 index 0000000..c239163 --- /dev/null +++ b/account/list_disks.go @@ -0,0 +1,55 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListDisksRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq ListDisksRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) ListDisks(ctx context.Context, req ListDisksRequest, options ...opts.DecortOpts) (AccountDisksList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/listDisks" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + accountDisksList := AccountDisksList{} + + err = json.Unmarshal(res, &accountDisksList) + if err != nil { + return nil, err + } + + return accountDisksList, nil + +} diff --git a/account/list_flipgroups.go b/account/list_flipgroups.go new file mode 100644 index 0000000..04c864e --- /dev/null +++ b/account/list_flipgroups.go @@ -0,0 +1,55 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListFlipGroupsRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq ListFlipGroupsRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) ListFlipGroups(ctx context.Context, req ListFlipGroupsRequest, options ...opts.DecortOpts) (AccountFlipGroupsList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/listFlipGroups" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + accountFlipGroupsList := AccountFlipGroupsList{} + + err = json.Unmarshal(res, &accountFlipGroupsList) + if err != nil { + return nil, err + } + + return accountFlipGroupsList, nil + +} diff --git a/account/list_rg.go b/account/list_rg.go new file mode 100644 index 0000000..cc32dbc --- /dev/null +++ b/account/list_rg.go @@ -0,0 +1,55 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRGRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq ListRGRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) ListRG(ctx context.Context, req ListRGRequest, options ...opts.DecortOpts) (AccountRGList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/listRG" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + accountRGList := AccountRGList{} + + err = json.Unmarshal(res, &accountRGList) + if err != nil { + return nil, err + } + + return accountRGList, nil + +} diff --git a/account/list_templates.go b/account/list_templates.go new file mode 100644 index 0000000..96420e7 --- /dev/null +++ b/account/list_templates.go @@ -0,0 +1,56 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListTemplatesRequest struct { + AccountId uint64 `url:"accountId"` + IncludeDeleted bool `url:"includedeleted"` +} + +func (arq ListTemplatesRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) ListTemplates(ctx context.Context, req ListTemplatesRequest, options ...opts.DecortOpts) (AccountTemplatesList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/listTemplates" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + accountTemplatesList := AccountTemplatesList{} + + err = json.Unmarshal(res, &accountTemplatesList) + if err != nil { + return nil, err + } + + return accountTemplatesList, nil + +} diff --git a/account/list_vins.go b/account/list_vins.go new file mode 100644 index 0000000..e224274 --- /dev/null +++ b/account/list_vins.go @@ -0,0 +1,55 @@ +package account + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListVinsRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq ListVinsRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) ListVins(ctx context.Context, req ListVinsRequest, options ...opts.DecortOpts) (AccountVinsList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/account/listVins" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + accountVinsList := AccountVinsList{} + + err = json.Unmarshal(res, &accountVinsList) + if err != nil { + return nil, err + } + + return accountVinsList, nil + +} diff --git a/account/models.go b/account/models.go new file mode 100644 index 0000000..42b1757 --- /dev/null +++ b/account/models.go @@ -0,0 +1,229 @@ +package account + +type AccountAclRecord struct { + IsExplicit bool `json:"explicit"` + GUID string `json:"guid"` + Rights string `json:"right"` + Status string `json:"status"` + Type string `json:"type"` + UgroupID string `json:"userGroupId"` + CanBeDeleted bool `json:"canBeDeleted"` +} + +type ResourceLimits struct { + CUC float64 `json:"CU_C"` + CUD float64 `json:"CU_D"` + CUI float64 `json:"CU_I"` + CUM float64 `json:"CU_M"` + CUNP float64 `json:"CU_NP"` + GpuUnits float64 `json:"gpu_units"` +} + +type AccountRecord struct { + DCLocation string `json:"DCLocation"` + CKey string `jspn:"_ckey"` + Meta []interface{} `json:"_meta"` + Acl []AccountAclRecord `json:"acl"` + Company string `json:"company"` + CompanyUrl string `json:"companyurl"` + CreatedBy string `jspn:"createdBy"` + CreatedTime int `json:"createdTime"` + DeactiovationTime float64 `json:"deactivationTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime int `json:"deletedTime"` + DisplayName string `json:"displayname"` + GUID int `json:"guid"` + ID int `json:"id"` + Name string `json:"name"` + ResourceLimits ResourceLimits `json:"resourceLimits"` + SendAccessEmails bool `json:"sendAccessEmails"` + ServiceAccount bool `json:"serviceAccount"` + Status string `json:"status"` + UpdatedTime int `json:"updatedTime"` + Version int `json:"version"` + Vins []int `json:"vins"` +} + +type AccountList []AccountRecord + +type AccountCloudApi struct { + Acl []AccountAclRecord `json:"acl"` + CreatedTime int `json:"createdTime"` + DeletedTime int `json:"deletedTime"` + ID int `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + UpdatedTime int `json:"updatedTime"` +} + +type AccountCloudApiList []AccountCloudApi + +type Resource struct { + CPU int `json:"cpu"` + Disksize int `json:"disksize"` + Extips int `json:"extips"` + Exttraffic int `json:"exttraffic"` + GPU int `json:"gpu"` + RAM int `json:"ram"` +} + +type Resources struct { + Current Resource `json:"Current"` + Reserved Resource `json:"Reserved"` +} + +type Computes struct { + Started int `json:"started"` + Stopped int `json:"stopped"` +} + +type Machines struct { + Running int `json:"running"` + Halted int `json:"halted"` +} + +type AccountWithResources struct { + Account + Resources Resources `json:"Resources"` + Computes Computes `json:"computes"` + Machines Machines `json:"machines"` + Vinses int `json:"vinses"` +} + +type AccountCompute struct { + AccountId int `json:"accountId"` + AccountName string `json:"accountName"` + CPUs int `json:"cpus"` + CreatedBy string `json:"createdBy"` + CreatedTime int `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime int `json:"deletedTime"` + ComputeId int `json:"id"` + ComputeName string `json:"name"` + RAM int `json:"ram"` + Registered bool `json:"registered"` + RGId int `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + TotalDisksSize int `json:"totalDisksSize"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime int `json:"updatedTime"` + UserManaged bool `json:"userManaged"` + VinsConnected int `json:"vinsConnected"` +} + +type AccountComputesList []AccountCompute + +type AccountDisk struct { + ID int `json:"id"` + Name string `json:"name"` + Pool string `json:"pool"` + SepId int `json:"sepId"` + SizeMax int `json:"sizeMax"` + Type string `json:"type"` +} + +type AccountDisksList []AccountDisk + +type AccountVin struct { + AccountId int `json:"accountId"` + AccountName string `json:"accountName"` + Computes int `json:"computes"` + CreatedBy string `json:"createdBy"` + CreatedTime int `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime int `json:"deletedTime"` + ExternalIP string `json:"externalIP"` + ID int `json:"id"` + Name string `json:"name"` + Network string `json:"network"` + PriVnfDevId int `json:"priVnfDevId"` + RGId int `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime int `json:"updatedTime"` +} + +type AccountVinsList []AccountVin + +type AccountAudit struct { + Call string `json:"call"` + ResponseTime float64 `json:"responsetime"` + StatusCode int `json:"statuscode"` + Timestamp float64 `json:"timestamp"` + User string `json:"user"` +} + +type AccountAuditsList []AccountAudit + +type AccountRGComputes struct { + Started int `json:"Started"` + Stopped int `json:"Stopped"` +} + +type AccountRGResources struct { + Consumed Resource `json:"Consumed"` + Limits Resource `json:"Limits"` + Reserved Resource `json:"Reserved"` +} + +type AccountRG struct { + Computes AccountRGComputes `json:"Computes"` + Resources AccountRGResources `json:"Resources"` + CreatedBy string `json:"createdBy"` + CreatedTime int `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime int `json:"deletedTime"` + RGID int `json:"id"` + Milestones int `json:"milestones"` + RGName string `json:"name"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime int `json:"updatedTime"` + Vinses int `json:"vinses"` +} + +type AccountRGList []AccountRG + +type AccountTemplate struct { + UNCPath string `json:"UNCPath"` + AccountId int `json:"accountId"` + Description string `json:"desc"` + ID int `json:"id"` + Name string `json:"name"` + Public bool `json:"public"` + Size int `json:"size"` + Status string `json:"status"` + Type string `json:"type"` + Username string `json:"username"` +} + +type AccountTemplatesList []AccountTemplate + +type AccountFlipGroup struct { + AccountId int `json:"accountId"` + ClientType string `json:"clientType"` + ConnType string `json:"connType"` + CreatedBy string `json:"createdBy"` + CreatedTime int `json:"createdTime"` + DefaultGW string `json:"defaultGW"` + DeletedBy string `json:"deletedBy"` + DeletedTime int `json:"deletedTime"` + Description string `json:"desc"` + GID int `json:"gid"` + GUID int `json:"guid"` + ID int `json:"id"` + IP string `json:"ip"` + Milestones int `json:"milestones"` + Name string `json:"name"` + NetID int `json:"netId"` + NetType string `json:"netType"` + NetMask int `json:"netmask"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime int `json:"updatedTime"` +} + +type AccountFlipGroupsList []AccountFlipGroup diff --git a/account/restore.go b/account/restore.go new file mode 100644 index 0000000..8352faa --- /dev/null +++ b/account/restore.go @@ -0,0 +1,53 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestoreRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (arq RestoreRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) Restore(ctx context.Context, req RestoreRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/account/restore" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/account/update.go b/account/update.go new file mode 100644 index 0000000..e9a82f7 --- /dev/null +++ b/account/update.go @@ -0,0 +1,60 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UpdateRequest struct { + AccountId uint64 `url:"accountId"` + Name string `url:"name,omitempty"` + MaxMemoryCapacity uint `url:"maxMemoryCapacity,omitempty"` + MaxVDiskCapacity uint `url:"maxVDiskCapacity,omitempty"` + MaxCPUCapacity uint `url:"maxCPUCapacity,omitempty"` + MaxNetworkPeerTransfer uint `url:"maxNetworkPeerTransfer,omitempty"` + MaxNumPublicIP uint `url:"maxNumPublicIP,omitempty"` + SendAccessEmails bool `url:"sendAccessEmails,omitempty"` + GpuUnits uint `url:"gpu_units,omitempty"` +} + +func (arq UpdateRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (a Account) Update(ctx context.Context, req UpdateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/account/update" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/account/update_user.go b/account/update_user.go new file mode 100644 index 0000000..f96aeab --- /dev/null +++ b/account/update_user.go @@ -0,0 +1,68 @@ +package account + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UpdateUserRequest struct { + AccountId uint64 `url:"accountId"` + UserId string `url:"userId"` + AccessType string `url:"accesstype"` +} + +func (arq UpdateUserRequest) Validate() error { + if arq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + if arq.UserId == "" { + return errors.New("validation-error: field UserId can not be empty") + } + + if arq.AccessType == "" { + return errors.New("validation-error: field AccessType can not be empty") + } + + isValid := validators.StringInSlice(arq.AccessType, []string{"R", "RCX", "ARCXDU"}) + if !isValid { + return errors.New("validation-error: field AccessType can be only R, RCX or ARCXDU") + } + + return nil +} + +func (a Account) UpdateUser(ctx context.Context, req UpdateUserRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/account/updateUser" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := a.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/bservice/bservice.go b/bservice/bservice.go new file mode 100644 index 0000000..0b92cc2 --- /dev/null +++ b/bservice/bservice.go @@ -0,0 +1,13 @@ +package bservice + +import "github.com/rudecs/decort-sdk/interfaces" + +type BService struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *BService { + return &BService{ + client, + } +} diff --git a/bservice/create.go b/bservice/create.go new file mode 100644 index 0000000..ee398c1 --- /dev/null +++ b/bservice/create.go @@ -0,0 +1,43 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + Name string `url:"name"` + RGID uint64 `url:"rgId"` + SSHUser string `url:"sshUser,omitempty"` + SSHKey string `url:"sshKey,omitempty"` +} + +func (bsrq CreateRequest) Validate() error { + if bsrq.Name == "" { + return errors.New("field Name can not be empty") + } + + if bsrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (uint64, error) { + if err := req.Validate(); err != nil { + return 0, err + } + + url := "/cloudapi/bservice/create" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + return strconv.ParseUint(string(res), 10, 64) +} diff --git a/bservice/delete.go b/bservice/delete.go new file mode 100644 index 0000000..d54845f --- /dev/null +++ b/bservice/delete.go @@ -0,0 +1,37 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + ServiceID uint64 `url:"serviceId"` + Permanently bool `url:"permanently,omitempty"` +} + +func (bsrq DeleteRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/delete" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/disable.go b/bservice/disable.go new file mode 100644 index 0000000..76b7adc --- /dev/null +++ b/bservice/disable.go @@ -0,0 +1,36 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DisableRequest struct { + ServiceID uint64 `url:"serviceId"` +} + +func (bsrq DisableRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) Disable(ctx context.Context, req DisableRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/delete" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/enable.go b/bservice/enable.go new file mode 100644 index 0000000..8cc0fa9 --- /dev/null +++ b/bservice/enable.go @@ -0,0 +1,36 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type EnableRequest struct { + ServiceID uint64 `url:"serviceId"` +} + +func (bsrq EnableRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) Enable(ctx context.Context, req EnableRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/enable" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/get.go b/bservice/get.go new file mode 100644 index 0000000..48c012b --- /dev/null +++ b/bservice/get.go @@ -0,0 +1,41 @@ +package bservice + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + ServiceID uint64 `url:"serviceId"` +} + +func (bsrq GetRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*BasicService, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/bservice/get" + bsRaw, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + bs := &BasicService{} + if err := json.Unmarshal(bsRaw, bs); err != nil { + return nil, err + } + + return bs, nil +} diff --git a/bservice/group_add.go b/bservice/group_add.go new file mode 100644 index 0000000..2ed02f2 --- /dev/null +++ b/bservice/group_add.go @@ -0,0 +1,75 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupAddRequest struct { + ServiceID uint64 `url:"serviceId"` + Name string `url:"name"` + Count uint64 `url:"count"` + CPU uint64 `url:"cpu"` + RAM uint64 `url:"ram"` + Disk uint64 `url:"disk"` + ImageID uint64 `url:"imageId"` + Driver string `url:"driver"` + Role string `url:"role,omitempty"` + VINSes []uint64 `url:"vinses,omitempty"` + Extnets []uint64 `url:"extnets,omitempty"` + TimeoutStart uint64 `url:"timeoutStart"` +} + +func (bsrq GroupAddRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.Name == "" { + return errors.New("field Name can not be empty") + } + + if bsrq.Count == 0 { + return errors.New("field Count can not be empty or equal to 0") + } + + if bsrq.CPU == 0 { + return errors.New("field CPU can not be empty or equal to 0") + } + + if bsrq.RAM == 0 { + return errors.New("field RAM can not be empty or equal to 0") + } + + if bsrq.Disk == 0 { + return errors.New("field Disk can not be empty or equal to 0") + } + + if bsrq.ImageID == 0 { + return errors.New("field ImageID can not be empty or equal to 0") + } + + if bsrq.Driver == "" { + return errors.New("field Driver can not be empty") + } + + return nil +} + +func (b BService) GroupAdd(ctx context.Context, req GroupAddRequest, options ...opts.DecortOpts) (uint64, error) { + if err := req.Validate(); err != nil { + return 0, err + } + + url := "/cloudapi/bservice/groupAdd" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + return strconv.ParseUint(string(res), 10, 64) +} diff --git a/bservice/group_compute_remove.go b/bservice/group_compute_remove.go new file mode 100644 index 0000000..0635587 --- /dev/null +++ b/bservice/group_compute_remove.go @@ -0,0 +1,46 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupComputeRemoveRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` + ComputeID uint64 `url:"computeId"` +} + +func (bsrq GroupComputeRemoveRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + if bsrq.ComputeID == 0 { + return errors.New("field ComputeID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupComputeRemove(ctx context.Context, req GroupComputeRemoveRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupComputeRemove" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/group_get.go b/bservice/group_get.go new file mode 100644 index 0000000..8230e7c --- /dev/null +++ b/bservice/group_get.go @@ -0,0 +1,46 @@ +package bservice + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupGetRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` +} + +func (bsrq GroupGetRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupGet(ctx context.Context, req GroupGetRequest, options ...opts.DecortOpts) (*Group, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/bservice/groupGet" + groupRaw, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + group := &Group{} + if err := json.Unmarshal(groupRaw, group); err != nil { + return nil, err + } + + return group, nil +} diff --git a/bservice/group_parent_add.go b/bservice/group_parent_add.go new file mode 100644 index 0000000..02ce409 --- /dev/null +++ b/bservice/group_parent_add.go @@ -0,0 +1,46 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupParentAddRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` + ParentID uint64 `url:"parentId"` +} + +func (bsrq GroupParentAddRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + if bsrq.ParentID == 0 { + return errors.New("field ParentID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupParentAdd(ctx context.Context, req GroupParentAddRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupParentAdd" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/group_parent_remove.go b/bservice/group_parent_remove.go new file mode 100644 index 0000000..a57e63e --- /dev/null +++ b/bservice/group_parent_remove.go @@ -0,0 +1,46 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupParentRemoveRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` + ParentID uint64 `url:"parentId"` +} + +func (bsrq GroupParentRemoveRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + if bsrq.ParentID == 0 { + return errors.New("field ParentID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupParentRemove(ctx context.Context, req GroupParentRemoveRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupParentRemove" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/group_remove.go b/bservice/group_remove.go new file mode 100644 index 0000000..c200ce3 --- /dev/null +++ b/bservice/group_remove.go @@ -0,0 +1,42 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupRemoveRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` +} + +func (bsrq GroupRemoveRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupRemove(ctx context.Context, req GroupRemoveRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupRemove" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/group_resize.go b/bservice/group_resize.go new file mode 100644 index 0000000..1588e85 --- /dev/null +++ b/bservice/group_resize.go @@ -0,0 +1,52 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupResizeRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` + Count int64 `url:"count"` + Mode string `url:"mode"` +} + +func (bsrq GroupResizeRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + if bsrq.Mode == "RELATIVE" && bsrq.Count == 0 { + return errors.New("field Count can not be equal to 0 if Mode if 'RELATIVE'") + } + + if !validators.StringInSlice(bsrq.Mode, []string{"RELATIVE", "ABSOLUTE"}) { + return errors.New("field Mode can only be one of 'RELATIVE' or 'ABSOLUTE'") + } + + return nil +} + +func (b BService) GroupResize(ctx context.Context, req GroupResizeRequest, options ...opts.DecortOpts) (uint64, error) { + if err := req.Validate(); err != nil { + return 0, err + } + + url := "/cloudapi/bservice/groupResize" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + return strconv.ParseUint(string(res), 10, 64) +} diff --git a/bservice/group_start.go b/bservice/group_start.go new file mode 100644 index 0000000..3d52c6a --- /dev/null +++ b/bservice/group_start.go @@ -0,0 +1,41 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupStartRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` +} + +func (bsrq GroupStartRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupStart(ctx context.Context, req GroupStartRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupStart" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/group_stop.go b/bservice/group_stop.go new file mode 100644 index 0000000..82e268a --- /dev/null +++ b/bservice/group_stop.go @@ -0,0 +1,42 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupStopRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` + Force bool `url:"force,omitempty"` +} + +func (bsrq GroupStopRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupStop(ctx context.Context, req GroupStopRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupStop" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/group_update.go b/bservice/group_update.go new file mode 100644 index 0000000..1771ed5 --- /dev/null +++ b/bservice/group_update.go @@ -0,0 +1,47 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupUpdateRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` + Name string `url:"name,omitempty"` + Role string `url:"role,omitempty"` + CPU uint64 `url:"cpu,omitempty"` + RAM uint64 `url:"ram,omitempty"` + Disk uint64 `url:"disk,omitempty"` + Force bool `url:"force,omitempty"` +} + +func (bsrq GroupUpdateRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupUpdate(ctx context.Context, req GroupUpdateRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupUpdate" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/group_update_extnet.go b/bservice/group_update_extnet.go new file mode 100644 index 0000000..8353e14 --- /dev/null +++ b/bservice/group_update_extnet.go @@ -0,0 +1,42 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupUpdateExtnetRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` + Extnets []uint64 `url:"extnets,omitempty"` +} + +func (bsrq GroupUpdateExtnetRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupUpdateExtnet(ctx context.Context, req GroupUpdateExtnetRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupUpdateExtnet" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/group_update_vins.go b/bservice/group_update_vins.go new file mode 100644 index 0000000..a0ed7b5 --- /dev/null +++ b/bservice/group_update_vins.go @@ -0,0 +1,42 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GroupUpdateVINSRequest struct { + ServiceID uint64 `url:"serviceId"` + CompGroupID uint64 `url:"compgroupId"` + VINSes []uint64 `url:"vinses,omitempty"` +} + +func (bsrq GroupUpdateVINSRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.CompGroupID == 0 { + return errors.New("field CompGroupID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) GroupUpdateVINS(ctx context.Context, req GroupUpdateVINSRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/groupUpdateVins" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/list.go b/bservice/list.go new file mode 100644 index 0000000..fa12389 --- /dev/null +++ b/bservice/list.go @@ -0,0 +1,46 @@ +package bservice + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + AccountID uint64 `url:"accountId,omitempty"` + RGID uint64 `url:"rgId,omitempty"` + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (b BService) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (BasicServiceList, error) { + url := "/cloudapi/bservice/list" + bsListRaw, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + bsList := BasicServiceList{} + if err := json.Unmarshal(bsListRaw, &bsList); err != nil { + return nil, err + } + + return bsList, nil +} + +func (b BService) ListDeleted(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (BasicServiceList, error) { + url := "/cloudapi/bservice/listDeleted" + bsListRaw, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + bsList := BasicServiceList{} + if err := json.Unmarshal(bsListRaw, &bsList); err != nil { + return nil, err + } + + return bsList, nil +} diff --git a/bservice/models.go b/bservice/models.go new file mode 100644 index 0000000..3d866f1 --- /dev/null +++ b/bservice/models.go @@ -0,0 +1,123 @@ +package bservice + +type BasicService struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + BaseDomain string `json:"baseDomain"` + Computes []Compute `json:"computes"` + CPUTotal uint64 `json:"cpuTotal"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + DiskTotal uint64 `json:"diskTotal"` + GID uint64 `json:"gid"` + Groups []uint64 `json:"groups"` + GroupsName []string `json:"groupsName"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + ParentSrvID uint64 `json:"parentSrvId"` + ParentSrvType string `json:"parentSrvType"` + RAMTotal uint64 `json:"ramTotal"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + Snapshots []Snapshot `json:"snapshots"` + SSHKey string `json:"sshKey"` + SSHUser string `json:"sshUser"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + UserManaged bool `json:"userManaged"` +} + +type Compute struct { + CompGroupID uint64 `json:"compgroupId"` + CompGroupName string `json:"compgroupName"` + CompGroupRole string `json:"compgroupRole"` + ID uint64 `json:"id"` + Name string `json:"name"` +} + +type Snapshot struct { + GUID string `json:"guid"` + Label string `json:"label"` + Timestamp uint64 `json:"timestamp"` + Valid bool `json:"valid"` +} + +type Group struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + Computes []GroupCompute `json:"computes"` + Consistency bool `json:"consistency"` + CPU uint64 `json:"cpu"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Disk uint64 `json:"disk"` + Driver string `json:"driver"` + Extnets []uint64 `json:"extnets"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + ImageID uint64 `json:"imageId"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + Parents []uint64 `json:"parents"` + RAM uint64 `json:"ram"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + Role string `json:"role"` + SepID uint64 `json:"sepId"` + SeqNo uint64 `json:"seqNo"` + ServiceID uint64 `json:"serviceId"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + TimeoutStart uint64 `json:"timeoutStart"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + VINSes []uint64 `json:"vinses"` +} + +type GroupCompute struct { + ID uint64 `json:"id"` + IPAddresses []string `json:"ipAddresses"` + Name string `json:"name"` + OSUsers []OSUser `json:"osUsers"` +} + +type OSUser struct { + Login string `json:"login"` + Password string `json:"password"` +} + +type BasicServiceShort struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + BaseDomain string `json:"baseDomain"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + GID uint64 `json:"gid"` + Groups []uint64 `json:"groups"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + Name string `json:"name"` + ParentSrvID uint64 `json:"parentSrvId"` + ParentSrvType string `json:"parentSrvType"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + SSHUser string `json:"sshUser"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + UserManaged bool `json:"userManaged"` +} + +type BasicServiceList []BasicServiceShort diff --git a/bservice/restore.go b/bservice/restore.go new file mode 100644 index 0000000..add6205 --- /dev/null +++ b/bservice/restore.go @@ -0,0 +1,36 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestoreRequest struct { + ServiceID uint64 `url:"serviceId"` +} + +func (bsrq RestoreRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) Restore(ctx context.Context, req RestoreRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/restore" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/snapshot_create.go b/bservice/snapshot_create.go new file mode 100644 index 0000000..b0bac96 --- /dev/null +++ b/bservice/snapshot_create.go @@ -0,0 +1,41 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotCreateRequest struct { + ServiceID uint64 `url:"serviceId"` + Label string `url:"label"` +} + +func (bsrq SnapshotCreateRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.Label == "" { + return errors.New("field Label can not be empty") + } + + return nil +} + +func (b BService) SnapshotCreate(ctx context.Context, req SnapshotCreateRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/snapshotCreate" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/snapshot_delete.go b/bservice/snapshot_delete.go new file mode 100644 index 0000000..aa5b551 --- /dev/null +++ b/bservice/snapshot_delete.go @@ -0,0 +1,41 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotDeleteRequest struct { + ServiceID uint64 `url:"serviceId"` + Label string `url:"label"` +} + +func (bsrq SnapshotDeleteRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.Label == "" { + return errors.New("field Label can not be empty") + } + + return nil +} + +func (b BService) SnapshotDelete(ctx context.Context, req SnapshotDeleteRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/snapshotDelete" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/snapshot_list.go b/bservice/snapshot_list.go new file mode 100644 index 0000000..9d2027d --- /dev/null +++ b/bservice/snapshot_list.go @@ -0,0 +1,41 @@ +package bservice + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotListRequest struct { + ServiceID uint64 `url:"serviceId"` +} + +func (bsrq SnapshotListRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) SnapshotList(ctx context.Context, req SnapshotListRequest, options ...opts.DecortOpts) ([]Snapshot, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/bservice/snapshotList" + snapshotListRaw, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + snapshotList := []Snapshot{} + if err := json.Unmarshal(snapshotListRaw, &snapshotList); err != nil { + return nil, err + } + + return snapshotList, nil +} diff --git a/bservice/snapshot_rollback.go b/bservice/snapshot_rollback.go new file mode 100644 index 0000000..20d9ead --- /dev/null +++ b/bservice/snapshot_rollback.go @@ -0,0 +1,41 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotRollbackRequest struct { + ServiceID uint64 `url:"serviceId"` + Label string `url:"label"` +} + +func (bsrq SnapshotRollbackRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + if bsrq.Label == "" { + return errors.New("field Label can not be empty") + } + + return nil +} + +func (b BService) SnapshotRollback(ctx context.Context, req SnapshotRollbackRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/snapshotRollback" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/start.go b/bservice/start.go new file mode 100644 index 0000000..5d3a910 --- /dev/null +++ b/bservice/start.go @@ -0,0 +1,36 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type StartRequest struct { + ServiceID uint64 `url:"serviceId"` +} + +func (bsrq StartRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) Start(ctx context.Context, req StartRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/start" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/bservice/stop.go b/bservice/stop.go new file mode 100644 index 0000000..b1f8cbd --- /dev/null +++ b/bservice/stop.go @@ -0,0 +1,36 @@ +package bservice + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type StopRequest struct { + ServiceID uint64 `url:"serviceId"` +} + +func (bsrq StopRequest) Validate() error { + if bsrq.ServiceID == 0 { + return errors.New("field ServiceID can not be empty or equal to 0") + } + + return nil +} + +func (b BService) Stop(ctx context.Context, req StopRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/bservice/stop" + res, err := b.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/client.go b/client.go new file mode 100644 index 0000000..e9aaf9d --- /dev/null +++ b/client.go @@ -0,0 +1,50 @@ +package client + +import ( + "context" + "errors" + "io/ioutil" + "net/http" + "strings" + + "github.com/google/go-querystring/query" +) + +type decortClient struct { + decortUrl string + client *http.Client +} + +func New(config Config) *decortClient { + return &decortClient{ + decortUrl: config.DecortUrl, + client: newHttpClient(config), + } +} + +func (dc *decortClient) DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) { + values, err := query.Values(params) + if err != nil { + return nil, err + } + + body := strings.NewReader(values.Encode()) + req, _ := http.NewRequestWithContext(ctx, method, dc.decortUrl+"/restmachine"+url, body) + + resp, err := dc.client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + respBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + return nil, errors.New(string(respBytes)) + } + + return respBytes, nil +} diff --git a/compute.go b/compute.go new file mode 100644 index 0000000..3106ccb --- /dev/null +++ b/compute.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/compute" +) + +func (dc *decortClient) Compute() *compute.Compute { + return compute.New(dc) +} diff --git a/compute/affinity_group_check_start.go b/compute/affinity_group_check_start.go new file mode 100644 index 0000000..8289107 --- /dev/null +++ b/compute/affinity_group_check_start.go @@ -0,0 +1,49 @@ +package compute + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityGroupCheckStartRequest struct { + RGID uint64 `url:"rgId"` + AffinityLabel string `url:"affinityLabel"` +} + +func (crq AffinityGroupCheckStartRequest) Validate() error { + if crq.RGID == 0 { + return errors.New("validation-error: field RGID can not be empty or equal to 0") + } + if crq.AffinityLabel == "" { + return errors.New("validation-error: field AffinityLabel can not be empty") + } + + return nil +} + +func (c Compute) AffinityGroupCheckStart(ctx context.Context, req AffinityGroupCheckStartRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/compute/affinityGroupCheckStart" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/compute/affinity_label_remove.go b/compute/affinity_label_remove.go new file mode 100644 index 0000000..34837ff --- /dev/null +++ b/compute/affinity_label_remove.go @@ -0,0 +1,51 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityLabelRemoveRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq AffinityLabelRemoveRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) AffinityLabelRemove(ctx context.Context, req AffinityLabelRemoveRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/affinityLabelRemove" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/affinity_label_set.go b/compute/affinity_label_set.go new file mode 100644 index 0000000..055d052 --- /dev/null +++ b/compute/affinity_label_set.go @@ -0,0 +1,55 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityLabelSetRequest struct { + ComputeId uint64 `url:"computeId"` + AffinityLabel string `url:"affinityLabel"` +} + +func (crq AffinityLabelSetRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.AffinityLabel == "" { + return errors.New("validation-error: field AffinityLabel can not be empty") + } + + return nil +} + +func (c Compute) AffinityLabelSet(ctx context.Context, req AffinityLabelSetRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/affinityLabelSet" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/affinity_relations.go b/compute/affinity_relations.go new file mode 100644 index 0000000..097fdd1 --- /dev/null +++ b/compute/affinity_relations.go @@ -0,0 +1,54 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityRelationsRequest struct { + ComputeId uint64 `url:"computeId"` + AffinityLabel string `url:"affinityLabel"` +} + +func (crq AffinityRelationsRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) AffinityRelations(ctx context.Context, req AffinityRelationsRequest, options ...opts.DecortOpts) (*AffinityRelations, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/affinityRelations" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + relations := &AffinityRelations{} + + err = json.Unmarshal([]byte(res), relations) + if err != nil { + return nil, err + } + + return relations, nil +} diff --git a/compute/affinity_rule_add.go b/compute/affinity_rule_add.go new file mode 100644 index 0000000..cf35f34 --- /dev/null +++ b/compute/affinity_rule_add.go @@ -0,0 +1,91 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityRuleAddRequest struct { + ComputeId uint64 `url:"computeId"` + Topology string `url:"topology"` + Policy string `url:"policy"` + Mode string `url:"mode"` + Key string `url:"key"` + Value string `url:"value"` +} + +func (crq AffinityRuleAddRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Topology == "" { + return errors.New("validation-error: field Topology can not be empty") + } + + validator := validators.StringInSlice(crq.Topology, []string{"compute", "node"}) + if !validator { + return errors.New("validation-error: field Topology can be only compute or node") + } + + if crq.Policy == "" { + return errors.New("validation-error: field Policy can not be empty") + } + + validator = validators.StringInSlice(crq.Policy, []string{"RECOMMENDED", "REQUIRED"}) + if !validator { + return errors.New("validation-error: field Policy can be only RECOMMENDED or REQUIRED") + } + + if crq.Mode == "" { + return errors.New("validation-error: field Mode can not be empty") + } + + validator = validators.StringInSlice(crq.Mode, []string{"EQ", "NE", "ANY"}) + if !validator { + return errors.New("validation-error: field Mode can be only EQ, NE or ANY") + } + + if crq.Key == "" { + return errors.New("validation-error: field Key can not be empty") + } + + if crq.Value == "" { + return errors.New("validation-error: field Value can not be empty") + } + + return nil +} + +func (c Compute) AffinityRuleAdd(ctx context.Context, req AffinityRuleAddRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/affinityRuleAdd" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/affinity_rule_remove.go b/compute/affinity_rule_remove.go new file mode 100644 index 0000000..2b2ed19 --- /dev/null +++ b/compute/affinity_rule_remove.go @@ -0,0 +1,91 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityRuleRemoveRequest struct { + ComputeId uint64 `url:"computeId"` + Topology string `url:"topology"` + Policy string `url:"policy"` + Mode string `url:"mode"` + Key string `url:"key"` + Value string `url:"value"` +} + +func (crq AffinityRuleRemoveRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Topology == "" { + return errors.New("validation-error: field Topology can not be empty") + } + + validator := validators.StringInSlice(crq.Topology, []string{"compute", "node"}) + if !validator { + return errors.New("validation-error: field Topology can be only compute or node") + } + + if crq.Policy == "" { + return errors.New("validation-error: field Policy can not be empty") + } + + validator = validators.StringInSlice(crq.Policy, []string{"RECOMMENDED", "REQUIRED"}) + if !validator { + return errors.New("validation-error: field Policy can be only RECOMMENDED or REQUIRED") + } + + if crq.Mode == "" { + return errors.New("validation-error: field Mode can not be empty") + } + + validator = validators.StringInSlice(crq.Mode, []string{"EQ", "NE", "ANY"}) + if !validator { + return errors.New("validation-error: field Mode can be only EQ, NE or ANY") + } + + if crq.Key == "" { + return errors.New("validation-error: field Key can not be empty") + } + + if crq.Value == "" { + return errors.New("validation-error: field Value can not be empty") + } + + return nil +} + +func (c Compute) AffinityRuleRemove(ctx context.Context, req AffinityRuleRemoveRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/affinityRuleRemove" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/affinity_rules_clear.go b/compute/affinity_rules_clear.go new file mode 100644 index 0000000..a37fd1a --- /dev/null +++ b/compute/affinity_rules_clear.go @@ -0,0 +1,51 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityRulesClearRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq AffinityRulesClearRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) AffinityRulesClear(ctx context.Context, req AffinityRulesClearRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/affinityRulesClear" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/anti_affinity_rule_add.go b/compute/anti_affinity_rule_add.go new file mode 100644 index 0000000..d64e40c --- /dev/null +++ b/compute/anti_affinity_rule_add.go @@ -0,0 +1,91 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AntiAffinityRuleAddRequest struct { + ComputeId uint64 `url:"computeId"` + Topology string `url:"topology"` + Policy string `url:"policy"` + Mode string `url:"mode"` + Key string `url:"key"` + Value string `url:"value"` +} + +func (crq AntiAffinityRuleAddRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Topology == "" { + return errors.New("validation-error: field Topology can not be empty") + } + + validator := validators.StringInSlice(crq.Topology, []string{"compute", "node"}) + if !validator { + return errors.New("validation-error: field Topology can be only compute or node") + } + + if crq.Policy == "" { + return errors.New("validation-error: field Policy can not be empty") + } + + validator = validators.StringInSlice(crq.Policy, []string{"RECOMMENDED", "REQUIRED"}) + if !validator { + return errors.New("validation-error: field Policy can be only RECOMMENDED or REQUIRED") + } + + if crq.Mode == "" { + return errors.New("validation-error: field Mode can not be empty") + } + + validator = validators.StringInSlice(crq.Mode, []string{"EQ", "NE", "ANY"}) + if !validator { + return errors.New("validation-error: field Mode can be only EQ, NE or ANY") + } + + if crq.Key == "" { + return errors.New("validation-error: field Key can not be empty") + } + + if crq.Value == "" { + return errors.New("validation-error: field Value can not be empty") + } + + return nil +} + +func (c Compute) AntiAffinityRuleAdd(ctx context.Context, req AntiAffinityRuleAddRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/antiAffinityRuleAdd" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/anti_affinity_rule_remove.go b/compute/anti_affinity_rule_remove.go new file mode 100644 index 0000000..4f9637d --- /dev/null +++ b/compute/anti_affinity_rule_remove.go @@ -0,0 +1,91 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AntiAffinityRuleRemoveRequest struct { + ComputeId uint64 `url:"computeId"` + Topology string `url:"topology"` + Policy string `url:"policy"` + Mode string `url:"mode"` + Key string `url:"key"` + Value string `url:"value"` +} + +func (crq AntiAffinityRuleRemoveRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Topology == "" { + return errors.New("validation-error: field Topology can not be empty") + } + + validator := validators.StringInSlice(crq.Topology, []string{"compute", "node"}) + if !validator { + return errors.New("validation-error: field Topology can be only compute or node") + } + + if crq.Policy == "" { + return errors.New("validation-error: field Policy can not be empty") + } + + validator = validators.StringInSlice(crq.Policy, []string{"RECOMMENDED", "REQUIRED"}) + if !validator { + return errors.New("validation-error: field Policy can be only RECOMMENDED or REQUIRED") + } + + if crq.Mode == "" { + return errors.New("validation-error: field Mode can not be empty") + } + + validator = validators.StringInSlice(crq.Mode, []string{"EQ", "NE", "ANY"}) + if !validator { + return errors.New("validation-error: field Mode can be only EQ, NE or ANY") + } + + if crq.Key == "" { + return errors.New("validation-error: field Key can not be empty") + } + + if crq.Value == "" { + return errors.New("validation-error: field Value can not be empty") + } + + return nil +} + +func (c Compute) AntiAffinityRuleRemove(ctx context.Context, req AntiAffinityRuleRemoveRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/antiAffinityRuleRemove" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/anti_affinity_rules_clear.go b/compute/anti_affinity_rules_clear.go new file mode 100644 index 0000000..989e49c --- /dev/null +++ b/compute/anti_affinity_rules_clear.go @@ -0,0 +1,51 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AntiAffinityRulesClearRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq AntiAffinityRulesClearRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) AntiAffinityRulesClear(ctx context.Context, req AntiAffinityRulesClearRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/antiAffinityRulesClear" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/attach_gpu.go b/compute/attach_gpu.go new file mode 100644 index 0000000..4d1e963 --- /dev/null +++ b/compute/attach_gpu.go @@ -0,0 +1,56 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AttachGPURequest struct { + ComputeId uint64 `url:"computeId"` + VGPUID uint64 `url:"vgpuId"` +} + +func (crq AttachGPURequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.VGPUID == 0 { + return errors.New("validation-error: field VGPUID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) AttachGPU(ctx context.Context, req AttachGPURequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/compute/attachGpu" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, nil + } + + return result, nil +} diff --git a/compute/attach_pci_device.go b/compute/attach_pci_device.go new file mode 100644 index 0000000..1dc4bed --- /dev/null +++ b/compute/attach_pci_device.go @@ -0,0 +1,56 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AttachPciDeviceRequest struct { + ComputeId uint64 `url:"computeId"` + DeviceID uint64 `url:"deviceId"` +} + +func (crq AttachPciDeviceRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.DeviceID == 0 { + return errors.New("validation-error: field DeviceID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) AttachPciDevice(ctx context.Context, req AttachPciDeviceRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/attachPciDevice" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/audits.go b/compute/audits.go new file mode 100644 index 0000000..0f15277 --- /dev/null +++ b/compute/audits.go @@ -0,0 +1,41 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AuditsRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq AuditsRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Audits(ctx context.Context, req AuditsRequest, options ...opts.DecortOpts) (AuditList, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/compute/audits" + auditListRaw, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + auditList := AuditList{} + if err := json.Unmarshal(auditListRaw, &auditList); err != nil { + return nil, err + } + + return auditList, nil +} diff --git a/compute/cd_eject.go b/compute/cd_eject.go new file mode 100644 index 0000000..a6bf7d3 --- /dev/null +++ b/compute/cd_eject.go @@ -0,0 +1,50 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CDEjectRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq CDEjectRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) CDEject(ctx context.Context, req CDEjectRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/cdEject" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/cd_insert.go b/compute/cd_insert.go new file mode 100644 index 0000000..7e5ddcf --- /dev/null +++ b/compute/cd_insert.go @@ -0,0 +1,54 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CDInsertRequest struct { + ComputeId uint64 `url:"computeId"` + CDROMID uint64 `url:"cdromId"` +} + +func (crq CDInsertRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.CDROMID == 0 { + return errors.New("validation-error: field CDROMID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) CDInsert(ctx context.Context, req CDInsertRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/cdInsert" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/clone.go b/compute/clone.go new file mode 100644 index 0000000..3b219c9 --- /dev/null +++ b/compute/clone.go @@ -0,0 +1,56 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CloneRequest struct { + ComputeId uint64 `url:"computeId"` + Name string `url:"name"` + SnapshotTimestamp uint64 `url:"snapshotTimestamp"` + SnapshotName string `url:"snapshotName"` +} + +func (crq CloneRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Name == "" { + return errors.New("validation-error: field Name can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Clone(ctx context.Context, req CloneRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/compute/clone" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + return result, nil +} diff --git a/compute/compute.go b/compute/compute.go new file mode 100644 index 0000000..73f0a90 --- /dev/null +++ b/compute/compute.go @@ -0,0 +1,15 @@ +package compute + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Compute struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Compute { + return &Compute{ + client, + } +} diff --git a/compute/create_template.go b/compute/create_template.go new file mode 100644 index 0000000..f05c071 --- /dev/null +++ b/compute/create_template.go @@ -0,0 +1,88 @@ +package compute + +import ( + "context" + "errors" + "strconv" + "strings" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateTemplateRequest struct { + ComputeId uint64 `url:"computeId"` + Name string `url:"name"` + Async bool `url:"async"` +} + +func (crq CreateTemplateRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + return nil +} + +func (c Compute) CreateTemplate(ctx context.Context, req CreateTemplateRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + req.Async = false + + url := "/compute/createTemplate" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, nil + } + + return result, nil +} + +func (c Compute) CreateTemplateAsync(ctx context.Context, req CreateTemplateRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + req.Async = true + + url := "/compute/createTemplate" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + result := strings.ReplaceAll(string(res), "\"", "") + + return result, nil +} diff --git a/compute/delete.go b/compute/delete.go new file mode 100644 index 0000000..3570ff6 --- /dev/null +++ b/compute/delete.go @@ -0,0 +1,52 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + ComputeId uint64 `url:"computeId"` + Permanently bool `url:"permanently,omitempty"` + DetachDisks bool `url:"detachDisks,omitempty"` +} + +func (crq DeleteRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/delete" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/detach_gpu.go b/compute/detach_gpu.go new file mode 100644 index 0000000..132f77e --- /dev/null +++ b/compute/detach_gpu.go @@ -0,0 +1,52 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DetachGPURequest struct { + ComputeId uint64 `url:"computeId"` + VGPUID int64 `url:"vgpuId,omitempty"` +} + +func (crq DetachGPURequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) DetachGPU(ctx context.Context, req DetachGPURequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/detachGpu" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/detach_pci_device.go b/compute/detach_pci_device.go new file mode 100644 index 0000000..2731e0d --- /dev/null +++ b/compute/detach_pci_device.go @@ -0,0 +1,56 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DetachPciDeviceRequest struct { + ComputeId uint64 `url:"computeId"` + DeviceID uint64 `url:"deviceId"` +} + +func (crq DetachPciDeviceRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.DeviceID == 0 { + return errors.New("validation-error: field DeviceID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) DetachPciDevice(ctx context.Context, req DetachPciDeviceRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/detachPciDevice" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/disable.go b/compute/disable.go new file mode 100644 index 0000000..efc3795 --- /dev/null +++ b/compute/disable.go @@ -0,0 +1,51 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DisableRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq DisableRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Disable(ctx context.Context, req DisableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/disable" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/disk_add.go b/compute/disk_add.go new file mode 100644 index 0000000..ba118fa --- /dev/null +++ b/compute/disk_add.go @@ -0,0 +1,66 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DiskAddRequest struct { + ComputeId uint64 `url:"computeId"` + DiskName string `url:"diskName"` + Size uint64 `url:"size"` + DiskType string `url:"diskType,omitempty"` + SepID uint64 `url:"sepId,omitempty"` + Pool string `url:"pool,omitempty"` + Description string `url:"desc,omitempty"` + ImageID uint64 `url:"imageId,omitempty"` +} + +func (crq DiskAddRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.Size == 0 { + return errors.New("validation-error: field Size can not be empty or equal to 0") + } + + if crq.DiskName == "" { + return errors.New("validation-error: field DiskName can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) DiskAdd(ctx context.Context, req DiskAddRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/compute/diskAdd" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, nil + } + + return result, nil +} diff --git a/compute/disk_attach.go b/compute/disk_attach.go new file mode 100644 index 0000000..e37e238 --- /dev/null +++ b/compute/disk_attach.go @@ -0,0 +1,56 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DiskAttachRequest struct { + ComputeId uint64 `url:"computeId"` + DiskID uint64 `url:"diskId"` +} + +func (crq DiskAttachRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.DiskID == 0 { + return errors.New("validation-error: field DiskID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) DiskAttach(ctx context.Context, req DiskAttachRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/diskAttach" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/disk_del.go b/compute/disk_del.go new file mode 100644 index 0000000..e162117 --- /dev/null +++ b/compute/disk_del.go @@ -0,0 +1,57 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DiskDelRequest struct { + ComputeId uint64 `url:"computeId"` + DiskID uint64 `url:"diskId"` + Permanently bool `url:"permanently"` +} + +func (crq DiskDelRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.DiskID == 0 { + return errors.New("validation-error: field DiskID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) DiskDel(ctx context.Context, req DiskDelRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/diskDel" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/disk_detach.go b/compute/disk_detach.go new file mode 100644 index 0000000..696a2c9 --- /dev/null +++ b/compute/disk_detach.go @@ -0,0 +1,56 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DiskDetachRequest struct { + ComputeId uint64 `url:"computeId"` + DiskID uint64 `url:"diskId"` +} + +func (crq DiskDetachRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.DiskID == 0 { + return errors.New("validation-error: field DiskID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) DiskDetach(ctx context.Context, req DiskDetachRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/diskDetach" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/disk_qos.go b/compute/disk_qos.go new file mode 100644 index 0000000..5c0466a --- /dev/null +++ b/compute/disk_qos.go @@ -0,0 +1,61 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DiskQOSRequest struct { + ComputeId uint64 `url:"computeId"` + DiskID uint64 `url:"diskId"` + Limits string `url:"limits"` +} + +func (crq DiskQOSRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.DiskID == 0 { + return errors.New("validation-error: field DiskID can not be empty or equal to 0") + } + + if crq.Limits == "" { + return errors.New("validation-error: field Limits can not be empty") + } + + return nil +} + +func (c Compute) DiskQOS(ctx context.Context, req DiskQOSRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/diskQos" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/disk_resize.go b/compute/disk_resize.go new file mode 100644 index 0000000..f95a67c --- /dev/null +++ b/compute/disk_resize.go @@ -0,0 +1,61 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DiskResizeRequest struct { + ComputeId uint64 `url:"computeId"` + DiskID uint64 `url:"diskId"` + Size uint64 `url:"size"` +} + +func (crq DiskResizeRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.DiskID == 0 { + return errors.New("validation-error: field DiskID can not be empty or equal to 0") + } + + if crq.Size == 0 { + return errors.New("validation-error: field Size can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) DiskResize(ctx context.Context, req DiskResizeRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/diskResize" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/enable.go b/compute/enable.go new file mode 100644 index 0000000..db52dc2 --- /dev/null +++ b/compute/enable.go @@ -0,0 +1,51 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type EnableRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq EnableRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Enable(ctx context.Context, req EnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/enable" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/compute/get.go b/compute/get.go new file mode 100644 index 0000000..54c545c --- /dev/null +++ b/compute/get.go @@ -0,0 +1,52 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq GetRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*ComputeRecord, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/get" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + compute := &ComputeRecord{} + err = json.Unmarshal(res, compute) + if err != nil { + return nil, err + } + + return compute, nil +} diff --git a/compute/get_audits.go b/compute/get_audits.go new file mode 100644 index 0000000..3c47a73 --- /dev/null +++ b/compute/get_audits.go @@ -0,0 +1,52 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetAuditsRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq GetAuditsRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) GetAudits(ctx context.Context, req GetAuditsRequest, options ...opts.DecortOpts) (AuditShortList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/getAudits" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + auditsList := AuditShortList{} + err = json.Unmarshal(res, &auditsList) + if err != nil { + return nil, err + } + + return auditsList, nil +} diff --git a/compute/get_console_url.go b/compute/get_console_url.go new file mode 100644 index 0000000..12b1ed6 --- /dev/null +++ b/compute/get_console_url.go @@ -0,0 +1,48 @@ +package compute + +import ( + "context" + "errors" + "strings" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetConsoleURLRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq GetConsoleURLRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) GetConsoleURL(ctx context.Context, req GetConsoleURLRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/compute/getConsoleUrl" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + result := strings.ReplaceAll(string(res), "\"", "") + + return result, nil +} diff --git a/compute/get_log.go b/compute/get_log.go new file mode 100644 index 0000000..e8263f7 --- /dev/null +++ b/compute/get_log.go @@ -0,0 +1,74 @@ +package compute + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetLogRequest struct { + ComputeId uint64 `url:"computeId"` + Path string `url:"path"` +} + +func (crq GetLogRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.Path == "" { + return errors.New("validation-error: field Path can not be empty") + } + + return nil +} + +func (c Compute) GetLog(ctx context.Context, req GetLogRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/compute/getLog" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} + +func (c Compute) GetLogGet(ctx context.Context, req GetLogRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/compute/getLog" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.GET, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/compute/list.go b/compute/list.go new file mode 100644 index 0000000..77f724c --- /dev/null +++ b/compute/list.go @@ -0,0 +1,42 @@ +package compute + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + IncludeDeleted bool `url:"includedeleted,omitempty"` + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (c Compute) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (ComputeList, error) { + + url := "/compute/list" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + computeList := ComputeList{} + + err = json.Unmarshal(res, &computeList) + if err != nil { + return nil, err + } + + return computeList, nil +} diff --git a/compute/list_deleted.go b/compute/list_deleted.go new file mode 100644 index 0000000..af85954 --- /dev/null +++ b/compute/list_deleted.go @@ -0,0 +1,41 @@ +package compute + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListDeletedRequest struct { + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (c Compute) ListDeleted(ctx context.Context, req ListDeletedRequest, options ...opts.DecortOpts) (ComputeList, error) { + + url := "/compute/listDeleted" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + computeList := ComputeList{} + + err = json.Unmarshal(res, &computeList) + if err != nil { + return nil, err + } + + return computeList, nil +} diff --git a/compute/list_pci_device.go b/compute/list_pci_device.go new file mode 100644 index 0000000..9f80863 --- /dev/null +++ b/compute/list_pci_device.go @@ -0,0 +1,53 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListPCIDeviceRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq ListPCIDeviceRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) ListPCIDevice(ctx context.Context, req ListPCIDeviceRequest, options ...opts.DecortOpts) ([]interface{}, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/listPciDevice" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + pciDeviceList := []interface{}{} + + err = json.Unmarshal(res, &pciDeviceList) + if err != nil { + return nil, err + } + + return pciDeviceList, nil +} diff --git a/compute/list_vgpu.go b/compute/list_vgpu.go new file mode 100644 index 0000000..dfe1996 --- /dev/null +++ b/compute/list_vgpu.go @@ -0,0 +1,53 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListVGPURequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq ListVGPURequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) ListVGPU(ctx context.Context, req ListVGPURequest, options ...opts.DecortOpts) ([]interface{}, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/listVgpu" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + pciDeviceList := []interface{}{} + + err = json.Unmarshal(res, &pciDeviceList) + if err != nil { + return nil, err + } + + return pciDeviceList, nil +} diff --git a/compute/models.go b/compute/models.go new file mode 100644 index 0000000..c7bcf36 --- /dev/null +++ b/compute/models.go @@ -0,0 +1,288 @@ +package compute + +//ACL for compute +type UserList struct { + AccountACL ACLList `json:"accountACL"` + ComputeACL ACLList `json:"computeACL"` + RGACL ACLList `json:"rgACL"` +} + +type ACL struct { + Explicit bool `json:"explicit"` + GUID string `json:"guid"` + Rigth string `json:"right"` + Status string `json:"status"` + Type string `json:"type"` + UserGroupId string `json:"userGroupId"` +} + +type ACLList []ACL + +type SnapshotUsage struct { + Count uint64 `json:"count,omitempty"` + Stored float64 `json:"stored"` + Label string `json:"label,omitempty"` + Timestamp uint64 `json:"timestamp,omitempty"` +} + +type SnapshotUsageList []SnapshotUsage + +type Snapshot struct { + Disks []uint64 `json:"disks"` + GUID string `json:"guid"` + Label string `json:"label"` + Timestamp uint64 `json:"timestamp"` +} + +type SnapshotList []Snapshot + +type PFW struct { + ID uint64 `json:"id"` + LocalIP string `json:"localIp"` + LocalPort uint64 `json:"localPort"` + Protocol string `json:"protocol"` + PublicPortEnd uint64 `json:"publicPortEnd"` + PublicPortStart uint64 `json:"publicPortStart"` + VMID uint64 `json:"vmId"` +} + +type PFWList []PFW + +type AffinityRelations struct { + OtherNode []interface{} `json:"otherNode"` + OtherNodeIndirect []interface{} `json:"otherNodeIndirect"` + OtherNodeIndirectSoft []interface{} `json:"otherNodeIndirectSoft"` + OtherNodeSoft []interface{} `json:"otherNodeSoft"` + SameNode []interface{} `json:"sameNode"` + SameNodeSoft []interface{} `json:"sameNodeSoft"` +} + +type NetAttach struct { + ConnID uint64 `json:"connId"` + ConnType string `json:"connType"` + DefGW string `json:"defGw"` + FlipGroupID uint64 `json:"flipgroupId"` + GUID string `json:"guid"` + IPAddress string `json:"ipAddress"` + ListenSSH bool `json:"listenSsh"` + MAC string `json:"mac"` + Name string `json:"name"` + NetID uint64 `json:"netId"` + NetMask uint64 `json:"netMask"` + NetType string `json:"netType"` + PCISlot uint64 `json:"pciSlot"` + QOS QOS `json:"qos"` + Target string `json:"target"` + Type string `json:"type"` + VNFS []uint64 `json:"vnfs"` +} + +type Audit struct { + Call string `json:"call"` + ResponseTime float64 `json:"responsetime"` + StatusCode uint64 `json:"statuscode"` + Timestamp float64 `json:"timestamp"` + User string `json:"user"` +} + +type AuditList []Audit + +type AuditShort struct { + Epoch float64 `json:"epoch"` + Message string `json:"message"` +} + +type AuditShortList []AuditShort + +type Rule struct { + GUID string `json:"guid"` + Key string `json:"key"` + Mode string `json:"mode"` + Policy string `json:"policy"` + Topology string `json:"topology"` + Value string `json:"value"` +} + +type RuleList []Rule + +type ComputeRecord struct { + ACL UserList `json:"ACL"` + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + AffinityLabel string `json:"affinityLabel"` + AffinityRules RuleList `json:"affinityRules"` + AffinityWeight uint64 `json:"affinityWeight"` + AntiAffinityRules RuleList `json:"antiAffinityRules"` + Architecture string `json:"arch"` + BootOrder []string `json:"bootOrder"` + BootDiskSize uint64 `json:"bootdiskSize"` + CloneReference uint64 `json:"cloneReference"` + Clones []uint64 `json:"clones"` + ComputeCIID uint64 `json:"computeciId"` + CPU uint64 `json:"cpus"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + CustomFields map[string]interface{} `json:"customFields"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + Devices interface{} `json:"devices"` + Disks ComputeDiskList `json:"disks"` + Driver string `json:"driver"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + ImageID uint64 `json:"imageId"` + ImageName string `json:"imageName"` + Intefaces IntefaceList `json:"interfaces"` + LockStatus string `json:"lockStatus"` + ManagerID uint64 `json:"managerId"` + ManagerType string `json:"managerType"` + MigrationJob uint64 `json:"migrationjob"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + NatableVinsID uint64 `json:"natableVinsId"` + NatableVinsIP string `json:"natableVinsIp"` + NatableVinsName string `json:"natableVinsName"` + NatableVinsNetwork string `json:"natableVinsNetwork"` + NatableVinsNetworkName string `json:"natableVinsNetworkName"` + OSUsers OSUserList `json:"osUsers"` + Pinned bool `json:"pinned"` + RAM uint64 `json:"ram"` + ReferenceID string `json:"referenceId"` + Registered bool `json:"registered"` + ResName string `json:"resName"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + SnapSets SnapSetList `json:"snapSets"` + StatelessSepID uint64 `json:"statelessSepId"` + StatelessSepType string `json:"statelessSepType"` + Status string `json:"status"` + Tags map[string]string `json:"tags"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + UserManaged bool `json:"userManaged"` + Userdata interface{} `json:"userdata"` + VGPUs []uint64 `json:"vgpus"` + VirtualImageID uint64 `json:"virtualImageId"` + VirtualImageName string `json:"virtualImageName"` +} + +type ComputeList []ComputeRecord + +type OSUser struct { + GUID string `json:"guid"` + Login string `json:"login"` + Password string `json:"password"` + PubKey string `json:"pubkey"` +} + +type OSUserList []OSUser + +type SnapSet struct { + Disks []uint64 `json:"disks"` + GUID string `json:"guid"` + Label string `json:"label"` + Timestamp uint64 `json:"timestamp"` +} + +type SnapSetList []SnapSet + +type VNFInterface struct { + ConnId uint64 `json:"connId"` + ConnType string `json:"connType"` + DefGW string `json:"defGw"` + FlipGroupId uint64 `json:"flipgroupId"` + GUID string `json:"guid"` + IPAddress string `json:"ipAddress"` + ListenSSH bool `json:"listenSsh"` + MAC string `json:"mac"` + Name string `json:"name"` + NetId uint64 `json:"netId"` + NetMask uint64 `json:"netMask"` + NetType string `json:"netType"` + PCISlot uint64 `json:"pciSlot"` + QOS QOS `json:"qos"` + Target string `json:"target"` + Type string `json:"type"` + VNFS []uint64 `json:"vnfs"` +} + +type QOS struct { + ERate uint64 `json:"eRate"` + GUID string `json:"guid"` + InBurst uint64 `json:"inBurst"` + InRate uint64 `json:"inRate"` +} + +type IntefaceList []VNFInterface + +type ComputeDiskList []ComputeDisk + +type ComputeDisk struct { + Ckey string `json:"_ckey"` + Acl map[string]interface{} `json:"acl"` + AccountID int `json:"accountId"` + Bootpartition uint64 `json:"bootPartition"` + CreatedTime uint64 `json:"createdTime"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + DestructionTime uint64 `json:"destructionTime"` + DiskPath string `json:"diskPath"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + ImageID uint64 `json:"imageId"` + Images []uint64 `json:"images"` + IOTune IOTune `json:"iotune"` + IQN string `json:"iqn"` + Login string `json:"login"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + Order uint64 `json:"order"` + Params string `json:"params"` + ParentID uint64 `json:"parentId"` + Passwd string `json:"passwd"` + PciSlot uint64 `json:"pciSlot"` + Pool string `json:"pool"` + PurgeTime uint64 `json:"purgeTime"` + RealityDeviceNumber uint64 `json:"realityDeviceNumber"` + ResID string `json:"resId"` + Role string `json:"role"` + SepID int `json:"sepId"` // NOTE: absent from compute/get output + SizeMax int `json:"sizeMax"` + SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space + Snapshots SnapshotExtendList `json:"snapshots"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` + VMID int `json:"vmid"` +} + +type SnapshotExtend struct { + Guid string `json:"guid"` + Label string `json:"label"` + ResId string `json:"resId"` + SnapSetGuid string `json:"snapSetGuid"` + SnapSetTime uint64 `json:"snapSetTime"` + TimeStamp uint64 `json:"timestamp"` +} + +type SnapshotExtendList []SnapshotExtend + +type IOTune struct { + ReadBytesSec int `json:"read_bytes_sec"` + ReadBytesSecMax int `json:"read_bytes_sec_max"` + ReadIopsSec int `json:"read_iops_sec"` + ReadIopsSecMax int `json:"read_iops_sec_max"` + SizeIopsSec int `json:"size_iops_sec"` + TotalBytesSec int `json:"total_bytes_sec"` + TotalBytesSecMax int `json:"total_bytes_sec_max"` + TotalIopsSec int `json:"total_iops_sec"` + TotalIopsSecMax int `json:"total_iops_sec_max"` + WriteBytesSec int `json:"write_bytes_sec"` + WriteBytesSecMax int `json:"write_bytes_sec_max"` + WriteIopsSec int `json:"write_iops_sec"` + WriteIopsSecMax int `json:"write_iops_sec_max"` +} diff --git a/compute/move_to_rg.go b/compute/move_to_rg.go new file mode 100644 index 0000000..ef412e7 --- /dev/null +++ b/compute/move_to_rg.go @@ -0,0 +1,57 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type MoveToRGRequest struct { + ComputeId uint64 `url:"computeId"` + RGID uint64 `url:"rgId"` + Name string `url:"name,omitempty"` + Autostart bool `url:"autostart,omitempty"` + ForceStop bool `url:"forceStop,omitempty"` +} + +func (crq MoveToRGRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.RGID == 0 { + return errors.New("validation-error: field RGID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) MoveToRG(ctx context.Context, req MoveToRGRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/moveToRg" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/net_attach.go b/compute/net_attach.go new file mode 100644 index 0000000..b89caba --- /dev/null +++ b/compute/net_attach.go @@ -0,0 +1,67 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type NetAttachRequest struct { + ComputeId uint64 `url:"computeId"` + NetType string `url:"netType"` + NetID uint64 `url:"netId"` + IPAddr string `url:"ipAddr,omitempty"` +} + +func (crq NetAttachRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.NetType == "" { + return errors.New("validation-error: field NetType can not be empty") + } + validator := validators.StringInSlice(crq.NetType, []string{"EXTNET", "VINS"}) + if !validator { + return errors.New("validation-error: field NetType can be only EXTNET or VINS") + } + + if crq.NetID == 0 { + return errors.New("validation-error: field NetID can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) NetAttach(ctx context.Context, req NetAttachRequest, options ...opts.DecortOpts) (*NetAttach, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/netAttach" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + netAttach := &NetAttach{} + err = json.Unmarshal(res, netAttach) + if err != nil { + return nil, err + } + + return netAttach, nil +} diff --git a/compute/net_detach.go b/compute/net_detach.go new file mode 100644 index 0000000..cb209b6 --- /dev/null +++ b/compute/net_detach.go @@ -0,0 +1,52 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type NetDetachRequest struct { + ComputeId uint64 `url:"computeId"` + IPAddr string `url:"ipAddr,omitempty"` + MAC string `url:"mac,omitempty"` +} + +func (crq NetDetachRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) NetDetach(ctx context.Context, req NetDetachRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/netDetach" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/pause.go b/compute/pause.go new file mode 100644 index 0000000..bd0b809 --- /dev/null +++ b/compute/pause.go @@ -0,0 +1,50 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type PauseRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq PauseRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Pause(ctx context.Context, req PauseRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/pause" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/pfw_add.go b/compute/pfw_add.go new file mode 100644 index 0000000..1ac4c49 --- /dev/null +++ b/compute/pfw_add.go @@ -0,0 +1,69 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type PFWAddRequest struct { + ComputeId uint64 `url:"computeId"` + PublicPortStart uint64 `url:"publicPortStart"` + PublicPortEnd uint64 `url:"publicPortEnd,omitempty"` + LocalBasePort uint64 `url:"localBasePort"` + Proto string `url:"proto"` +} + +func (crq PFWAddRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.PublicPortStart == 0 { + return errors.New("validation-error: field PublicPortStart can not be empty or equal to 0") + } + if crq.LocalBasePort == 0 { + return errors.New("validation-error: field LocalBasePort can not be empty or equal to 0") + } + if crq.Proto == "" { + return errors.New("validation-error: field Proto can not be empty") + } + validator := validators.StringInSlice(crq.Proto, []string{"tcp", "udp"}) + if !validator { + return errors.New("validation-error: field Proto can be only tcp or udp") + } + + return nil +} + +func (c Compute) PFWAdd(ctx context.Context, req PFWAddRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/compute/pfwAdd" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + + return result, nil +} diff --git a/compute/pfw_del.go b/compute/pfw_del.go new file mode 100644 index 0000000..9f9ecdb --- /dev/null +++ b/compute/pfw_del.go @@ -0,0 +1,56 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type PFWDelRequest struct { + ComputeId uint64 `url:"computeId"` + PFWId uint64 `url:"ruleId,omitempty"` + PublicPortStart uint64 `url:"publicPortStart,omitempty"` + PublicPortEnd uint64 `url:"publicPortEnd,omitempty"` + LocalBasePort uint64 `url:"localBasePort,omitempty"` + Proto string `url:"proto,omitempty"` +} + +func (crq PFWDelRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) PFWDel(ctx context.Context, req PFWDelRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/pfwDel" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/pfw_list.go b/compute/pfw_list.go new file mode 100644 index 0000000..69fb55c --- /dev/null +++ b/compute/pfw_list.go @@ -0,0 +1,53 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type PFWListRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq PFWListRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) PFWList(ctx context.Context, req PFWListRequest, options ...opts.DecortOpts) (PFWList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/pfwList" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + pfwList := PFWList{} + + err = json.Unmarshal(res, &pfwList) + if err != nil { + return nil, err + } + + return pfwList, nil +} diff --git a/compute/pin_to_stack.go b/compute/pin_to_stack.go new file mode 100644 index 0000000..606f91c --- /dev/null +++ b/compute/pin_to_stack.go @@ -0,0 +1,50 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type PinToStackRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq PinToStackRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) PinToStack(ctx context.Context, req PinToStackRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/compute/pinToStack" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + return result, nil +} diff --git a/compute/power_cycle.go b/compute/power_cycle.go new file mode 100644 index 0000000..5cc0091 --- /dev/null +++ b/compute/power_cycle.go @@ -0,0 +1,50 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type PowerCycleRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq PowerCycleRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) PowerCycle(ctx context.Context, req PowerCycleRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/powerCycle" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/reboot.go b/compute/reboot.go new file mode 100644 index 0000000..e350776 --- /dev/null +++ b/compute/reboot.go @@ -0,0 +1,50 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RebootRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq RebootRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Reboot(ctx context.Context, req RebootRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/reboot" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/redeploy.go b/compute/redeploy.go new file mode 100644 index 0000000..d105c8a --- /dev/null +++ b/compute/redeploy.go @@ -0,0 +1,55 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RedeployRequest struct { + ComputeId uint64 `url:"computeId"` + ImageId uint64 `url:"imageId,omitempty"` + DiskSize uint64 `url:"diskSize,omitempty"` + DataDisks string `url:"dataDisks,omitempty"` + AutoStart bool `url:"autoStart,omitempty"` + ForceStop bool `url:"forceStop,omitempty"` +} + +func (crq RedeployRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Redeploy(ctx context.Context, req RedeployRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/redeploy" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/reset.go b/compute/reset.go new file mode 100644 index 0000000..7757649 --- /dev/null +++ b/compute/reset.go @@ -0,0 +1,50 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ResetRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq ResetRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Reset(ctx context.Context, req ResetRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/reset" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/resize.go b/compute/resize.go new file mode 100644 index 0000000..7a6f4a8 --- /dev/null +++ b/compute/resize.go @@ -0,0 +1,53 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ResizeRequest struct { + ComputeId uint64 `url:"computeId"` + Force bool `url:"force,omitempty"` + CPU uint64 `url:"cpu,omitempty"` + RAM uint64 `url:"ram,omitempty"` +} + +func (crq ResizeRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Resize(ctx context.Context, req ResizeRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/resize" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/restore.go b/compute/restore.go new file mode 100644 index 0000000..904f59f --- /dev/null +++ b/compute/restore.go @@ -0,0 +1,45 @@ +package compute + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestoreRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq RestoreRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Restore(ctx context.Context, req RestoreRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/compute/restore" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/compute/resume.go b/compute/resume.go new file mode 100644 index 0000000..c9f1011 --- /dev/null +++ b/compute/resume.go @@ -0,0 +1,50 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ResumeRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq ResumeRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Resume(ctx context.Context, req ResumeRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/resume" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/snapshot_create.go b/compute/snapshot_create.go new file mode 100644 index 0000000..b139fb5 --- /dev/null +++ b/compute/snapshot_create.go @@ -0,0 +1,52 @@ +package compute + +import ( + "context" + "errors" + "strings" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotCreateRequest struct { + ComputeId uint64 `url:"computeId"` + Label string `url:"label"` +} + +func (crq SnapshotCreateRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Label == "" { + return errors.New("validation-error: field Label can not be empty") + } + + return nil +} + +func (c Compute) SnapshotCreate(ctx context.Context, req SnapshotCreateRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/compute/snapshotCreate" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + result := strings.ReplaceAll(string(res), "\"", "") + + return result, nil +} diff --git a/compute/snapshot_delete.go b/compute/snapshot_delete.go new file mode 100644 index 0000000..d157f59 --- /dev/null +++ b/compute/snapshot_delete.go @@ -0,0 +1,55 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotDeleteRequest struct { + ComputeId uint64 `url:"computeId"` + Label string `url:"label"` +} + +func (crq SnapshotDeleteRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Label == "" { + return errors.New("validation-error: field Label can not be empty") + } + + return nil +} + +func (c Compute) SnapshotDelete(ctx context.Context, req SnapshotDeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/snapshotDelete" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/snapshot_list.go b/compute/snapshot_list.go new file mode 100644 index 0000000..0161384 --- /dev/null +++ b/compute/snapshot_list.go @@ -0,0 +1,53 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotListRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq SnapshotListRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) SnapshotList(ctx context.Context, req SnapshotListRequest, options ...opts.DecortOpts) (SnapshotList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/snapshotList" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + snapshotList := SnapshotList{} + + err = json.Unmarshal(res, &snapshotList) + if err != nil { + return nil, err + } + + return snapshotList, nil +} diff --git a/compute/snapshot_rollback.go b/compute/snapshot_rollback.go new file mode 100644 index 0000000..25d5934 --- /dev/null +++ b/compute/snapshot_rollback.go @@ -0,0 +1,55 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotRollbackRequest struct { + ComputeId uint64 `url:"computeId"` + Label string `url:"label"` +} + +func (crq SnapshotRollbackRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Label == "" { + return errors.New("validation-error: field Label can not be empty") + } + + return nil +} + +func (c Compute) SnapshotRollback(ctx context.Context, req SnapshotRollbackRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/snapshotRollback" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/compute/snapshot_usage.go b/compute/snapshot_usage.go new file mode 100644 index 0000000..bd77670 --- /dev/null +++ b/compute/snapshot_usage.go @@ -0,0 +1,54 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotUsageRequest struct { + ComputeId uint64 `url:"computeId"` + Label string `url:"label,omitempty"` +} + +func (crq SnapshotUsageRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) SnapshotUsage(ctx context.Context, req SnapshotUsageRequest, options ...opts.DecortOpts) (SnapshotUsageList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/compute/snapshotUsage" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + snapshotUsage := SnapshotUsageList{} + + err = json.Unmarshal(res, &snapshotUsage) + if err != nil { + return nil, err + } + + return snapshotUsage, nil +} diff --git a/compute/start.go b/compute/start.go new file mode 100644 index 0000000..5b75870 --- /dev/null +++ b/compute/start.go @@ -0,0 +1,51 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type StartRequest struct { + ComputeId uint64 `url:"computeId"` + AltBootId uint64 `url:"altBootId,omitempty"` +} + +func (crq StartRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Start(ctx context.Context, req StartRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/start" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/stop.go b/compute/stop.go new file mode 100644 index 0000000..1a8e379 --- /dev/null +++ b/compute/stop.go @@ -0,0 +1,51 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type StopRequest struct { + ComputeId uint64 `url:"computeId"` + Force bool `url:"force,omitempty"` +} + +func (crq StopRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Stop(ctx context.Context, req StopRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/stop" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/tag_add.go b/compute/tag_add.go new file mode 100644 index 0000000..41126e3 --- /dev/null +++ b/compute/tag_add.go @@ -0,0 +1,59 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type TagAddRequest struct { + ComputeId uint64 `url:"computeId"` + Key string `url:"key"` + Value string `url:"value"` +} + +func (crq TagAddRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Key == "" { + return errors.New("validation-error: field Key can not be empty") + } + + if crq.Value == "" { + return errors.New("validation-error: field Value can not be empty") + } + + return nil +} + +func (c Compute) TagAdd(ctx context.Context, req TagAddRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/tagAdd" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/tag_remove.go b/compute/tag_remove.go new file mode 100644 index 0000000..f18480f --- /dev/null +++ b/compute/tag_remove.go @@ -0,0 +1,54 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type TagRemoveRequest struct { + ComputeId uint64 `url:"computeId"` + Key string `url:"key"` +} + +func (crq TagRemoveRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + if crq.Key == "" { + return errors.New("validation-error: field Key can not be empty") + } + + return nil +} + +func (c Compute) TagRemove(ctx context.Context, req TagRemoveRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/tagRemove" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/unpin_from_stack.go b/compute/unpin_from_stack.go new file mode 100644 index 0000000..4a0810e --- /dev/null +++ b/compute/unpin_from_stack.go @@ -0,0 +1,50 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UnpinFromStackRequest struct { + ComputeId uint64 `url:"computeId"` +} + +func (crq UnpinFromStackRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) UnpinFromStack(ctx context.Context, req UnpinFromStackRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/unpinFromStack" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/update.go b/compute/update.go new file mode 100644 index 0000000..2fd6c10 --- /dev/null +++ b/compute/update.go @@ -0,0 +1,52 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UpdateRequest struct { + ComputeId uint64 `url:"computeId"` + Name string `url:"name,omitempty"` + Description string `url:"desc,omitempty"` +} + +func (crq UpdateRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) Update(ctx context.Context, req UpdateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/update" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/user_grant.go b/compute/user_grant.go new file mode 100644 index 0000000..8b9b683 --- /dev/null +++ b/compute/user_grant.go @@ -0,0 +1,65 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UserGrantRequest struct { + ComputeId uint64 `url:"computeId"` + Username string `url:"userName"` + AccessType string `url:"accesstype"` +} + +func (crq UserGrantRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.Username == "" { + return errors.New("validation-error: field Username can not be empty") + } + + if crq.AccessType == "" { + return errors.New("validation-error: field AccessType can not be empty") + } + validator := validators.StringInSlice(crq.AccessType, []string{"R", "RCX", "ARCXDU"}) + if !validator { + return errors.New("validation-error: field AccessType can be only R, RCX or ARCXDU") + } + + return nil +} + +func (c Compute) UserGrant(ctx context.Context, req UserGrantRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/userGrant" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/user_list.go b/compute/user_list.go new file mode 100644 index 0000000..e72cdd3 --- /dev/null +++ b/compute/user_list.go @@ -0,0 +1,49 @@ +package compute + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UserListRequest struct { + ComputeId uint64 `url:"computeId "` +} + +func (crq UserListRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + return nil +} + +func (c Compute) UserList(ctx context.Context, req UserListRequest, options ...opts.DecortOpts) (*UserList, error) { + + url := "/compute/userList" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + userList := &UserList{} + + err = json.Unmarshal(res, userList) + if err != nil { + return nil, err + } + + return userList, nil +} diff --git a/compute/user_revoke.go b/compute/user_revoke.go new file mode 100644 index 0000000..54e82d1 --- /dev/null +++ b/compute/user_revoke.go @@ -0,0 +1,55 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UserRevokeRequest struct { + ComputeId uint64 `url:"computeId"` + Username string `url:"userName"` +} + +func (crq UserRevokeRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.Username == "" { + return errors.New("validation-error: field Username can not be empty") + } + + return nil +} + +func (c Compute) UserRevoke(ctx context.Context, req UserRevokeRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/userRevoke" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/compute/user_update.go b/compute/user_update.go new file mode 100644 index 0000000..b69d2b5 --- /dev/null +++ b/compute/user_update.go @@ -0,0 +1,65 @@ +package compute + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UserUpdateRequest struct { + ComputeId uint64 `url:"computeId"` + Username string `url:"userName"` + AccessType string `url:"accesstype"` +} + +func (crq UserUpdateRequest) Validate() error { + if crq.ComputeId == 0 { + return errors.New("validation-error: field ComputeId can not be empty or equal to 0") + } + + if crq.Username == "" { + return errors.New("validation-error: field Username can not be empty") + } + + if crq.AccessType == "" { + return errors.New("validation-error: field AccessType can not be empty") + } + validator := validators.StringInSlice(crq.AccessType, []string{"R", "RCX", "ARCXDU"}) + if !validator { + return errors.New("validation-error: field AccessType can be only R, RCX or ARCXDU") + } + + return nil +} + +func (c Compute) UserUpdate(ctx context.Context, req UserUpdateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/compute/userUpdate" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/computeci.go b/computeci.go new file mode 100644 index 0000000..f09c7cf --- /dev/null +++ b/computeci.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/computeci" +) + +func (dc *decortClient) ComputeCI() *computeci.ComputeCI { + return computeci.New(dc) +} diff --git a/computeci/computeci.go b/computeci/computeci.go new file mode 100644 index 0000000..12a99ff --- /dev/null +++ b/computeci/computeci.go @@ -0,0 +1,15 @@ +package computeci + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type ComputeCI struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *ComputeCI { + return &ComputeCI{ + client, + } +} diff --git a/computeci/get.go b/computeci/get.go new file mode 100644 index 0000000..0c0b840 --- /dev/null +++ b/computeci/get.go @@ -0,0 +1,41 @@ +package computeci + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + ComputeCIID uint64 `url:"computeciId"` +} + +func (krq GetRequest) Validate() error { + if krq.ComputeCIID == 0 { + return errors.New("field ComputeCIID can not be empty or equal to 0") + } + + return nil +} + +func (c ComputeCI) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*ComputeCIRecord, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/computeci/get" + computeciRaw, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + computeci := &ComputeCIRecord{} + if err := json.Unmarshal(computeciRaw, computeci); err != nil { + return nil, err + } + + return computeci, nil +} diff --git a/computeci/list.go b/computeci/list.go new file mode 100644 index 0000000..e7f9dcf --- /dev/null +++ b/computeci/list.go @@ -0,0 +1,30 @@ +package computeci + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + IncludeDeleted bool `url:"includeDeleted,omitempty"` + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (c ComputeCI) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (ComputeCIList, error) { + url := "/cloudapi/computeci/list" + computeciListRaw, err := c.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + computeciList := ComputeCIList{} + if err := json.Unmarshal(computeciListRaw, &computeciList); err != nil { + return nil, err + } + + return computeciList, nil +} diff --git a/computeci/models.go b/computeci/models.go new file mode 100644 index 0000000..6a5e63c --- /dev/null +++ b/computeci/models.go @@ -0,0 +1,14 @@ +package computeci + +type ComputeCIRecord struct { + CustomFields map[string]interface{} `json:"customFields"` + Description string `json:"desc"` + Drivers []string `json:"drivers"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + Template string `jsnn:"template"` +} + +type ComputeCIList []ComputeCIRecord diff --git a/config.go b/config.go new file mode 100644 index 0000000..8f6abcc --- /dev/null +++ b/config.go @@ -0,0 +1,10 @@ +package client + +type Config struct { + AppID string + AppSecret string + SSOURL string + DecortURL string + Retries uint64 + SSLSkipVerify bool +} diff --git a/disks.go b/disks.go new file mode 100644 index 0000000..6589640 --- /dev/null +++ b/disks.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/disks" +) + +func (dc *decortClient) Disks() *disks.Disks { + return disks.New(dc) +} diff --git a/disks/create.go b/disks/create.go new file mode 100644 index 0000000..8e03ac9 --- /dev/null +++ b/disks/create.go @@ -0,0 +1,77 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + AccountId uint64 `url:"accountId"` + GID uint64 `url:"gid"` + Name string `url:"name"` + Description string `url:"description,omitempty"` + Size uint64 `url:"size,omitempty"` + Type string `url:"type"` + SSDSize uint64 `url:"ssdSize,omitempty"` + IOps uint64 `url:"iops"` + SepId uint64 `url:"sep_id,omitempty"` + Pool string `url:"pool,omitempty"` +} + +func (drq CreateRequest) Validate() error { + if drq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + if drq.GID == 0 { + return errors.New("validation-error: field Gid can not be empty or equal to 0") + } + if drq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + validType := validators.StringInSlice(drq.Type, []string{"B", "D", "T"}) + if !validType { + return errors.New("validation-error: field Type must be set as B, D or T") + } + + if drq.IOps == 0 { + return errors.New("validation-error: field IOps must be set") + } + + return nil +} + +func (d Disks) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/disks/create" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + return result, nil + +} diff --git a/disks/delete.go b/disks/delete.go new file mode 100644 index 0000000..94c3ecd --- /dev/null +++ b/disks/delete.go @@ -0,0 +1,53 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + DiskId uint64 `url:"diskId"` + Detach bool `url:"detach,omitempty"` + Permanently bool `url:"permanently,omitempty"` + Reason string `url:"reason,omitempty"` +} + +func (d DeleteRequest) Validate() error { + + if d.DiskId == 0 { + return errors.New("validation-error: field DiskId must be set") + } + return nil +} + +func (d Disks) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/delete" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/disks/delete_disks.go b/disks/delete_disks.go new file mode 100644 index 0000000..ae3a778 --- /dev/null +++ b/disks/delete_disks.go @@ -0,0 +1,55 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DisksDeleteRequest struct { + DisksIds []uint64 `url:"diskIds"` + Reason string `url:"reason"` + Permanently bool `url:"permanently"` +} + +func (drq DisksDeleteRequest) Validate() error { + if len(drq.DisksIds) == 0 { + return errors.New("validation-error: field DisksIds must include one or more disks ids") + } + + return nil +} + +func (d Disks) DeleteDisks(ctx context.Context, req DisksDeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/deleteDisks" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/disks/disks.go b/disks/disks.go new file mode 100644 index 0000000..13a5d2d --- /dev/null +++ b/disks/disks.go @@ -0,0 +1,15 @@ +package disks + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Disks struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Disks { + return &Disks{ + client, + } +} diff --git a/disks/get.go b/disks/get.go new file mode 100644 index 0000000..6663699 --- /dev/null +++ b/disks/get.go @@ -0,0 +1,55 @@ +package disks + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + DiskId uint64 `url:"diskId"` +} + +func (drq GetRequest) Validate() error { + if drq.DiskId == 0 { + return errors.New("validation-error: field DiskId can not be empty or equal to 0") + } + + return nil +} + +func (d Disks) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*DiskRecord, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/disks/get" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + disk := &DiskRecord{} + + err = json.Unmarshal(res, disk) + if err != nil { + return nil, err + } + + return disk, nil + +} diff --git a/disks/limitio.go b/disks/limitio.go new file mode 100644 index 0000000..23e66a2 --- /dev/null +++ b/disks/limitio.go @@ -0,0 +1,67 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type LimitIORequest struct { + DiskId uint64 `url:"diskId"` + IOps uint64 `url:"iops"` + TotalBytesSec uint64 `url:"total_bytes_sec"` + ReadBytesSec uint64 `url:"read_bytes_sec"` + WriteBytesSec uint64 `url:"write_bytes_sec"` + TotalIOpsSec uint64 `url:"total_iops_sec"` + ReadIOpsSec uint64 `url:"read_iops_sec"` + WriteIOpsSec uint64 `url:"write_iops_sec"` + TotalBytesSecMax uint64 `url:"total_bytes_sec_max"` + ReadBytesSecMax uint64 `url:"read_bytes_sec_max"` + WriteBytesSecMax uint64 `url:"write_bytes_sec_max"` + TotalIOpsSecMax uint64 `url:"total_iops_sec_max"` + ReadIOpsSecMax uint64 `url:"read_iops_sec_max"` + WriteIOpsSecMax uint64 `url:"write_iops_sec_max"` + SizeIOpsSec uint64 `url:"size_iops_sec"` +} + +func (drq LimitIORequest) Validate() error { + if drq.DiskId == 0 { + return errors.New("validation-error: field DiskId can not be empty or equal to 0") + } + + return nil +} + +func (d Disks) LimitIO(ctx context.Context, req LimitIORequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/limitIO" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/disks/list.go b/disks/list.go new file mode 100644 index 0000000..8b33aab --- /dev/null +++ b/disks/list.go @@ -0,0 +1,72 @@ +package disks + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + AccountId uint64 `url:"accountId,omitempty"` + Type string `url:"type,omitempty"` + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (d Disks) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (DiskList, error) { + url := "/disks/list" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + diskList := DiskList{} + + err = json.Unmarshal(res, &diskList) + if err != nil { + return nil, err + } + + return diskList, nil + +} + +func (d Disks) ListDeleted(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (DiskList, error) { + url := "/disks/listDeleted" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + diskList := DiskList{} + + err = json.Unmarshal(res, &diskList) + if err != nil { + return nil, err + } + + return diskList, nil + +} diff --git a/disks/list_types.go b/disks/list_types.go new file mode 100644 index 0000000..e95afcd --- /dev/null +++ b/disks/list_types.go @@ -0,0 +1,41 @@ +package disks + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListTypesRequest struct { + Detailed bool `url:"detailed"` +} + +func (d Disks) ListTypes(ctx context.Context, req ListTypesRequest, options ...opts.DecortOpts) ([]interface{}, error) { + url := "/disks/listTypes" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + typesList := make([]interface{}, 0) + + err = json.Unmarshal(res, &typesList) + if err != nil { + return nil, err + } + + return typesList, nil + +} diff --git a/disks/list_unattached.go b/disks/list_unattached.go new file mode 100644 index 0000000..fff0e96 --- /dev/null +++ b/disks/list_unattached.go @@ -0,0 +1,41 @@ +package disks + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListUnattachedRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (d Disks) ListUnattached(ctx context.Context, req ListUnattachedRequest, options ...opts.DecortOpts) (DiskList, error) { + url := "/disks/listUnattached" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + diskList := DiskList{} + + err = json.Unmarshal(res, &diskList) + if err != nil { + return nil, err + } + + return diskList, nil + +} diff --git a/disks/models.go b/disks/models.go new file mode 100644 index 0000000..05815af --- /dev/null +++ b/disks/models.go @@ -0,0 +1,116 @@ +package disks + +type Disk struct { + Acl map[string]interface{} `json:"acl"` + AccountID int `json:"accountId"` + AccountName string `json:"accountName"` + BootPartition int `json:"bootPartition"` + CreatedTime uint64 `json:"createdTime"` + ComputeID int `json:"computeId"` + ComputeName string `json:"computeName"` + DeletedTime uint64 `json:"deletedTime"` + DeviceName string `json:"devicename"` + Description string `json:"desc"` + DestructionTime uint64 `json:"destructionTime"` + GID uint64 `json:"gid"` + ID uint64 `json:"id"` + ImageID uint64 `json:"imageId"` + Images []uint64 `json:"images"` + IOTune IOTune `json:"iotune"` + MachineId int `json:"machineId"` + MachineName string `json:"machineName"` + Name string `json:"name"` + Order int `json:"order"` + Params string `json:"params"` + ParentId uint64 `json:"parentId"` + PciSlot uint64 `json:"pciSlot"` + Pool string `json:"pool"` + PurgeTime uint64 `json:"purgeTime"` + ResID string `json:"resId"` + ResName string `json:"resName"` + Role string `json:"role"` + SepType string `json:"sepType"` + SepID int `json:"sepId"` // NOTE: absent from compute/get output + SizeMax int `json:"sizeMax"` + Snapshots []Snapshot `json:"snapshots"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` + VMID int `json:"vmid"` +} + +type Snapshot struct { + Guid string `json:"guid"` + Label string `json:"label"` + ResId string `json:"resId"` + SnapSetGuid string `json:"snapSetGuid"` + SnapSetTime uint64 `json:"snapSetTime"` + TimeStamp uint64 `json:"timestamp"` +} + +type SnapshotList []Snapshot + +type IOTune struct { + ReadBytesSec int `json:"read_bytes_sec"` + ReadBytesSecMax int `json:"read_bytes_sec_max"` + ReadIopsSec int `json:"read_iops_sec"` + ReadIopsSecMax int `json:"read_iops_sec_max"` + SizeIopsSec int `json:"size_iops_sec"` + TotalBytesSec int `json:"total_bytes_sec"` + TotalBytesSecMax int `json:"total_bytes_sec_max"` + TotalIopsSec int `json:"total_iops_sec"` + TotalIopsSecMax int `json:"total_iops_sec_max"` + WriteBytesSec int `json:"write_bytes_sec"` + WriteBytesSecMax int `json:"write_bytes_sec_max"` + WriteIopsSec int `json:"write_iops_sec"` + WriteIopsSecMax int `json:"write_iops_sec_max"` +} + +type DiskList []Disk + +type DisksTypesListCoomon []string + +type DisksTypesListDetailed struct { + Pools []Pool `json:"pools"` + SepId uint64 `json:"sepId"` +} + +type Pool struct { + Name string `json:"name"` + Types []string `json:"types"` +} + +type DiskRecord struct { + Acl map[string]interface{} `json:"acl"` + AccountID int `json:"accountId"` + AccountName string `json:"accountName"` + CreatedTime uint64 `json:"createdTime"` + DeletedTime uint64 `json:"deletedTime"` + DeviceName string `json:"devicename"` + Description string `json:"desc"` + DestructionTime uint64 `json:"destructionTime"` + GID int `json:"gid"` + ID uint `json:"id"` + ImageID int `json:"imageId"` + Images []int `json:"images"` + IOTune IOTune `json:"iotune"` + Name string `json:"name"` + Order int `json:"order"` + Params string `json:"params"` + ParentId int `json:"parentId"` + PciSlot int `json:"pciSlot"` + Pool string `json:"pool"` + PurgeTime uint64 `json:"purgeTime"` + ResID string `json:"resId"` + ResName string `json:"resName"` + Role string `json:"role"` + SepType string `json:"sepType"` + SepID int `json:"sepId"` // NOTE: absent from compute/get output + SizeMax int `json:"sizeMax"` + SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space + Snapshots []Snapshot `json:"snapshots"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` + VMID int `json:"vmid"` +} diff --git a/disks/rename.go b/disks/rename.go new file mode 100644 index 0000000..7b193b5 --- /dev/null +++ b/disks/rename.go @@ -0,0 +1,58 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RenameRequest struct { + DiskId uint64 `url:"diskId"` + Name string `url:"name"` +} + +func (drq RenameRequest) Validate() error { + if drq.DiskId == 0 { + return errors.New("validation-error: field DiskId can not be empty or equal to 0") + } + + if drq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + return nil +} + +func (d Disks) Rename(ctx context.Context, req RenameRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/rename" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/disks/resize.go b/disks/resize.go new file mode 100644 index 0000000..c7120c0 --- /dev/null +++ b/disks/resize.go @@ -0,0 +1,89 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ResizeRequest struct { + DiskId uint64 `url:"diskId"` + Size uint64 `url:"size"` +} + +func (drq ResizeRequest) Validate() error { + if drq.DiskId == 0 { + return errors.New("validation-error: field DiskId can not be empty or equal to 0") + } + + if drq.Size == 0 { + return errors.New("validation-error: field Size can not be empty or equal to 0") + } + + return nil +} + +func (d Disks) Resize(ctx context.Context, req ResizeRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/resize" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} + +func (d Disks) Resize2(ctx context.Context, req ResizeRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/resize2" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/disks/restore.go b/disks/restore.go new file mode 100644 index 0000000..ad205ba --- /dev/null +++ b/disks/restore.go @@ -0,0 +1,58 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestoreRequest struct { + DiskId uint64 `url:"diskId"` + Reason string `url:"reason"` +} + +func (drq RestoreRequest) Validate() error { + if drq.DiskId == 0 { + return errors.New("validation-error: field DiskId can not be empty or equal to 0") + } + + if drq.Reason == "" { + return errors.New("validation-error: field Reason can not be empty") + } + + return nil +} + +func (d Disks) Restore(ctx context.Context, req RestoreRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/restore" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/disks/search.go b/disks/search.go new file mode 100644 index 0000000..68565c0 --- /dev/null +++ b/disks/search.go @@ -0,0 +1,43 @@ +package disks + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SearchRequest struct { + AccountId uint64 `url:"accountId,omitempty"` + Name string `url:"name,omitempty"` + ShowAll bool `url:"show_all,omitempty"` +} + +func (d Disks) Search(ctx context.Context, req SearchRequest, options ...opts.DecortOpts) (DiskList, error) { + url := "/disks/search" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + diskList := DiskList{} + + err = json.Unmarshal(res, &diskList) + if err != nil { + return nil, err + } + + return diskList, nil + +} diff --git a/disks/snapshot_delete.go b/disks/snapshot_delete.go new file mode 100644 index 0000000..2f5a87c --- /dev/null +++ b/disks/snapshot_delete.go @@ -0,0 +1,58 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotDeleteRequest struct { + DiskId uint64 `url:"diskId"` + Label string `url:"label"` +} + +func (drq SnapshotDeleteRequest) Validate() error { + if drq.DiskId == 0 { + return errors.New("validation-error: field DiskId can not be empty or equal to 0") + } + + if drq.Label == "" { + return errors.New("validation-error: field Label can not be empty") + } + + return nil +} + +func (d Disks) SnapshotDelete(ctx context.Context, req SnapshotDeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/snapshotDelete" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/disks/snapshot_rollback.go b/disks/snapshot_rollback.go new file mode 100644 index 0000000..909c148 --- /dev/null +++ b/disks/snapshot_rollback.go @@ -0,0 +1,59 @@ +package disks + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SnapshotRollbackRequest struct { + DiskId uint64 `url:"diskId"` + Label string `url:"label"` + TimeStamp uint64 `url:"timestamp"` +} + +func (drq SnapshotRollbackRequest) Validate() error { + if drq.DiskId == 0 { + return errors.New("validation-error: field DiskId can not be empty or equal to 0") + } + + if drq.Label == "" && drq.TimeStamp == 0 { + return errors.New("validation-error: field Label or field TimeStamp can not be empty") + } + + return nil +} + +func (d Disks) SnapshotRollback(ctx context.Context, req SnapshotRollbackRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/disks/snapshotRollback" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := d.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/extnet.go b/extnet.go new file mode 100644 index 0000000..6e3e787 --- /dev/null +++ b/extnet.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/extnet" +) + +func (dc *decortClient) Extnet() *extnet.Extnet { + return extnet.New(dc) +} diff --git a/extnet/extnet.go b/extnet/extnet.go new file mode 100644 index 0000000..aaf36aa --- /dev/null +++ b/extnet/extnet.go @@ -0,0 +1,15 @@ +package extnet + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Extnet struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Extnet { + return &Extnet{ + client, + } +} diff --git a/extnet/get.go b/extnet/get.go new file mode 100644 index 0000000..7070456 --- /dev/null +++ b/extnet/get.go @@ -0,0 +1,53 @@ +package extnet + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + NetId uint64 `url:"net_id"` +} + +func (erq GetRequest) Validate() error { + if erq.NetId == 0 { + return errors.New("validation-error: field NetId can not be empty or equal to 0") + } + return nil +} + +func (e Extnet) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*ExtnetDetailed, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/extnet/get" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + extnetRaw, err := e.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + extnet := &ExtnetDetailed{} + err = json.Unmarshal(extnetRaw, &extnet) + if err != nil { + return nil, err + } + + return extnet, nil + +} diff --git a/extnet/get_default.go b/extnet/get_default.go new file mode 100644 index 0000000..4dcb68a --- /dev/null +++ b/extnet/get_default.go @@ -0,0 +1,35 @@ +package extnet + +import ( + "context" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +func (e Extnet) GetDefault(ctx context.Context, options ...opts.DecortOpts) (uint64, error) { + url := "/extnet/getDefault" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := e.client.DecortApiCall(ctx, typed.POST, url, nil) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + + return result, nil + +} diff --git a/extnet/list.go b/extnet/list.go new file mode 100644 index 0000000..20a25ee --- /dev/null +++ b/extnet/list.go @@ -0,0 +1,42 @@ +package extnet + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + AccountId uint64 `url:"accountId"` + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (e Extnet) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (ExtnetList, error) { + url := "/extnet/list" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + extnetListRaw, err := e.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + extnetList := ExtnetList{} + err = json.Unmarshal(extnetListRaw, &extnetList) + if err != nil { + return nil, err + } + + return extnetList, nil + +} diff --git a/extnet/list_computes.go b/extnet/list_computes.go new file mode 100644 index 0000000..aa7a854 --- /dev/null +++ b/extnet/list_computes.go @@ -0,0 +1,49 @@ +package extnet + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListComputesRequest struct { + AccountId uint64 `url:"accountId"` +} + +func (erq ListComputesRequest) Validate() error { + if erq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (e Extnet) ListComputes(ctx context.Context, req ListComputesRequest, options ...opts.DecortOpts) (ExtnetComputesList, error) { + url := "/extnet/listComputes" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + extnetComputesListRaw, err := e.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + extnetComputesList := ExtnetComputesList{} + err = json.Unmarshal(extnetComputesListRaw, &extnetComputesList) + if err != nil { + return nil, err + } + + return extnetComputesList, nil + +} diff --git a/extnet/models.go b/extnet/models.go new file mode 100644 index 0000000..be6b2f0 --- /dev/null +++ b/extnet/models.go @@ -0,0 +1,80 @@ +package extnet + +type ExtnetRecord struct { + ID int `json:"id"` + IPCidr string `json:"ipcidr"` + Name string `json:"name"` +} +type ExtnetExtend struct { + ExtnetRecord + IPAddr string `json:"ipaddr"` +} + +type ExtnetList []ExtnetRecord +type ExtnetExtendList []ExtnetExtend + +type ExtnetComputes struct { + AccountId int `json:"accountId"` + AccountName string `json:"accountName"` + Extnets ExtnetExtendList `json:"extnets"` + ID int `json:"id"` + Name string `json:"name"` + RGID int `json:"rgId"` + RGName string `json:"rgName"` +} + +type ExtnetComputesList []ExtnetComputes + +type ExtnetQos struct { + ERate int `json:"eRate"` + GUID string `json:"guid"` + InBurst int `json:"inBurst"` + InRate int `json:"inRate"` +} + +type ExtnetReservation struct { + ClientType string `json:"clientType"` + Description string `json:"desc"` + DomainName string `json:"domainname"` + HostName string `json:"hostname"` + IP string `json:"ip"` + MAC string `json:"mac"` + Type string `json:"type"` + VMID int `json:"vmId"` +} + +type ExtnetReservations []ExtnetReservation + +type ExtnetVNFS struct { + DHCP int `json:"dhcp"` +} + +type ExtnetDetailed struct { + CKey string `json:"_ckey"` + Meta []interface{} `json:"_meta"` + CheckIPs []string `json:"checkIPs"` + CheckIps []string `json:"checkIps"` + Default bool `json:"default"` + DefaultQos ExtnetQos `json:"defaultQos"` + Description string `json:"desc"` + Dns []string `json:"dns"` + Excluded []string `json:"excluded"` + FreeIps int `json:"free_ips"` + Gateway string `json:"gateway"` + GID int `json:"gid"` + GUID int `json:"guid"` + ID int `json:"id"` + IPCidr string `json:"ipcidr"` + Milestones int `json:"milestones"` + Name string `json:"name"` + Network string `json:"network"` + NetworkId int `json:"networkId"` + PreReservationsNum int `json:"preReservationsNum"` + Prefix int `json:"prefix"` + PriVnfDevId int `json:"priVnfDevId"` + Reservations ExtnetReservations `json:"reservations"` + SharedWith []int `json:"sharedWith"` + Status string `json:"status"` + VlanID int `json:"vlanId"` + VNFS ExtnetVNFS `json:"vnfs"` +} diff --git a/flipgroup.go b/flipgroup.go new file mode 100644 index 0000000..15befce --- /dev/null +++ b/flipgroup.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/flipgroup" +) + +func (dc *decortClient) FlipGroup() *flipgroup.FlipGroup { + return flipgroup.New(dc) +} diff --git a/flipgroup/compute_add.go b/flipgroup/compute_add.go new file mode 100644 index 0000000..2f05d60 --- /dev/null +++ b/flipgroup/compute_add.go @@ -0,0 +1,45 @@ +package flipgroup + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ComputeAddRequest struct { + FlipGroupID uint64 `url:"flipgroupId"` + ComputeID uint64 `url:"computeId"` +} + +func (frq ComputeAddRequest) Validate() error { + if frq.FlipGroupID == 0 { + return errors.New("field FlipGroupID can not be empty or equal to 0") + } + if frq.ComputeID == 0 { + return errors.New("field ComputeID can not be empty or equal to 0") + } + + return nil +} + +func (f FlipGroup) ComputeAdd(ctx context.Context, req ComputeAddRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/flipgroup/computeAdd" + res, err := f.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/flipgroup/compute_remove.go b/flipgroup/compute_remove.go new file mode 100644 index 0000000..a135c5c --- /dev/null +++ b/flipgroup/compute_remove.go @@ -0,0 +1,45 @@ +package flipgroup + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ComputeRemoveRequest struct { + FlipGroupID uint64 `url:"flipgroupId"` + ComputeID uint64 `url:"computeId"` +} + +func (frq ComputeRemoveRequest) Validate() error { + if frq.FlipGroupID == 0 { + return errors.New("field FlipGroupID can not be empty or equal to 0") + } + if frq.ComputeID == 0 { + return errors.New("field ComputeID can not be empty or equal to 0") + } + + return nil +} + +func (f FlipGroup) ComputeRemove(ctx context.Context, req ComputeRemoveRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/flipgroup/computeRemove" + res, err := f.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/flipgroup/create.go b/flipgroup/create.go new file mode 100644 index 0000000..055fb77 --- /dev/null +++ b/flipgroup/create.go @@ -0,0 +1,63 @@ +package flipgroup + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + AccountID uint64 `url:"accountId"` + Name string `url:"name"` + NetType string `url:"netType"` + NetID uint64 `url:"netId"` + ClientType string `url:"clientType"` + IP string `url:"ip,omitempty"` + Description string `url:"desc,omitempty"` +} + +func (frq CreateRequest) Validate() error { + if frq.AccountID == 0 { + return errors.New("field AccountID can not be empty or equal to 0") + } + if frq.NetID == 0 { + return errors.New("field NetID can not be empty or equal to 0") + } + if frq.Name == "" { + return errors.New("field Name can not be empty") + } + + validator := validators.StringInSlice(frq.NetType, []string{"EXTNET", "VINS"}) + if !validator { + return errors.New("field Name can be only EXTNET or VINS") + } + validator = validators.StringInSlice(frq.ClientType, []string{"compute", "node"}) + if !validator { + return errors.New("field Name can be only compute or node") + } + + return nil +} + +func (f FlipGroup) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (*FlipGroupRecord, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/flipgroup/create" + fgRaw, err := f.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + fg := &FlipGroupRecord{} + if err := json.Unmarshal(fgRaw, fg); err != nil { + return nil, err + } + + return fg, nil +} diff --git a/flipgroup/delete.go b/flipgroup/delete.go new file mode 100644 index 0000000..b9231b1 --- /dev/null +++ b/flipgroup/delete.go @@ -0,0 +1,41 @@ +package flipgroup + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + FlipGroupID uint64 `url:"flipgroupId"` +} + +func (frq DeleteRequest) Validate() error { + if frq.FlipGroupID == 0 { + return errors.New("field FlipGroupID can not be empty or equal to 0") + } + + return nil +} + +func (f FlipGroup) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/flipgroup/delete" + res, err := f.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/flipgroup/edit.go b/flipgroup/edit.go new file mode 100644 index 0000000..434d174 --- /dev/null +++ b/flipgroup/edit.go @@ -0,0 +1,43 @@ +package flipgroup + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type EditRequest struct { + FlipGroupID uint64 `url:"flipgroupId"` + Name string `url:"name,omitempty"` + Description string `url:"desc,omitempty"` +} + +func (frq EditRequest) Validate() error { + if frq.FlipGroupID == 0 { + return errors.New("field FlipGroupID can not be empty or equal to 0") + } + + return nil +} + +func (f FlipGroup) Edit(ctx context.Context, req EditRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/flipgroup/edit" + res, err := f.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/flipgroup/flipgroup.go b/flipgroup/flipgroup.go new file mode 100644 index 0000000..810d2af --- /dev/null +++ b/flipgroup/flipgroup.go @@ -0,0 +1,15 @@ +package flipgroup + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type FlipGroup struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *FlipGroup { + return &FlipGroup{ + client, + } +} diff --git a/flipgroup/get.go b/flipgroup/get.go new file mode 100644 index 0000000..b9b0775 --- /dev/null +++ b/flipgroup/get.go @@ -0,0 +1,42 @@ +package flipgroup + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + FlipGroupID uint64 `url:"flipgroupId"` +} + +func (frq GetRequest) Validate() error { + if frq.FlipGroupID == 0 { + return errors.New("field FlipGroupID can not be empty or equal to 0") + } + + return nil +} + +func (f FlipGroup) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*FlipGroupItem, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/flipgroup/get" + res, err := f.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + fg := &FlipGroupItem{} + err = json.Unmarshal(res, fg) + if err != nil { + return nil, err + } + + return fg, nil +} diff --git a/flipgroup/list.go b/flipgroup/list.go new file mode 100644 index 0000000..e84642a --- /dev/null +++ b/flipgroup/list.go @@ -0,0 +1,29 @@ +package flipgroup + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (f FlipGroup) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (FlipGroupList, error) { + url := "/cloudapi/flipgroup/list" + fgListRaw, err := f.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + fgList := FlipGroupList{} + if err := json.Unmarshal(fgListRaw, &fgList); err != nil { + return nil, err + } + + return fgList, nil +} diff --git a/flipgroup/models.go b/flipgroup/models.go new file mode 100644 index 0000000..0d66d7e --- /dev/null +++ b/flipgroup/models.go @@ -0,0 +1,40 @@ +package flipgroup + +type FlipGroupRecord struct { + DefaultGW string `json:"defaultGW"` + ID uint64 `json:"id"` + IP string `json:"ip"` + Name string `json:"name"` + Netmask uint64 `json:"netmask"` +} + +type FlipGroupItem struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + ClientIds []uint64 `json:"clientIds"` + ClientType string `json:"clientType"` + ConnID uint64 `json:"connId"` + ConnType string `json:"connType"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DefaultGW string `json:"defaultGW"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + IP string `json:"ip"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + NetID uint64 `json:"netId"` + NetType string `json:"netType"` + Network string `json:"network"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` +} + +type FlipGroupList []FlipGroupItem diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..ee993d1 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/rudecs/decort-sdk + +go 1.19 + +require github.com/google/go-querystring v1.1.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f99081b --- /dev/null +++ b/go.sum @@ -0,0 +1,5 @@ +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/http-client.go b/http-client.go new file mode 100644 index 0000000..84ba388 --- /dev/null +++ b/http-client.go @@ -0,0 +1,25 @@ +package client + +import ( + "crypto/tls" + "net/http" + "time" +) + +func newHttpClient(config Config) *http.Client { + + transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.SSLSkipVerify}} + + return &http.Client{ + Transport: &transport{ + base: transCfg, + retries: config.Retries, + clientId: config.AppId, + clientSecret: config.AppSecret, + ssoUrl: config.SSOUrl, + //TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + + Timeout: 5 * time.Minute, + } +} diff --git a/image.go b/image.go new file mode 100644 index 0000000..8ae4d54 --- /dev/null +++ b/image.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/image" +) + +func (dc *decortClient) Image() *image.Image { + return image.New(dc) +} diff --git a/image/create.go b/image/create.go new file mode 100644 index 0000000..0d84208 --- /dev/null +++ b/image/create.go @@ -0,0 +1,102 @@ +package image + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + Name string `url:"name"` + URL string `url:"url"` + GID uint64 `url:"gid"` + BootType string `url:"boottype"` + ImageType string `url:"imagetype"` + Hotresize bool `url:"hotresize,omitempty"` + Username string `url:"username,omitempty"` + Password string `url:"password,omitempty"` + AccountId uint64 `url:"accountId,omitempty"` + UsernameDL string `url:"usernameDL,omitempty"` + PasswordDL string `url:"passwordDL,omitempty"` + SepId uint64 `url:"sepId,omitempty"` + Pool string `url:"poolName,omitempty"` + Architecture string `url:"architecture,omitempty"` + Drivers []string `url:"drivers"` +} + +func (irq CreateRequest) Validate() error { + if irq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + if irq.URL == "" { + return errors.New("validation-error: field URL can not be empty") + } + + if irq.GID == 0 { + return errors.New("validation-error: field GID can not be empty or equal to 0") + } + if irq.BootType == "" { + return errors.New("validation-error: field BootType can not be empty") + } + + validate := validators.StringInSlice(irq.BootType, []string{"bios", "uefi"}) + if !validate { + return errors.New("validation-error: field BootType can be bios or uefi") + } + if irq.ImageType == "" { + return errors.New("validation-error: field ImageType can not be empty") + } + + validate = validators.StringInSlice(irq.ImageType, []string{"bios", "uefi"}) + if !validate { + return errors.New("validation-error: field ImageType can be windows, linux or other") + } + + if len(irq.Drivers) == 0 || len(irq.Drivers) > 1 { + return errors.New("validation-error: field Drivers can not be empty or have 2 or more elements") + } + + for _, v := range irq.Drivers { + validate := validators.StringInSlice(v, []string{"KVM_X86"}) + if !validate { + return errors.New("validation-error: field Drivers can be KVM_X86 only") + } + } + + return nil +} + +func (i Image) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/image/create" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := i.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + + return result, nil + +} diff --git a/image/create_virtual.go b/image/create_virtual.go new file mode 100644 index 0000000..541385b --- /dev/null +++ b/image/create_virtual.go @@ -0,0 +1,58 @@ +package image + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateVirtualRequest struct { + Name string `url:"name"` + TargetId uint64 `url:"targetId"` +} + +func (irq CreateVirtualRequest) Validate() error { + if irq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + if irq.TargetId == 0 { + return errors.New("validation-error: field TargetId can not be empty or equal to 0") + } + + return nil +} + +func (i Image) CreateVirtual(ctx context.Context, req CreateVirtualRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/image/createVirtual" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := i.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + + return result, nil + +} diff --git a/image/delete.go b/image/delete.go new file mode 100644 index 0000000..215176e --- /dev/null +++ b/image/delete.go @@ -0,0 +1,54 @@ +package image + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + ImageId uint64 `url:"imageId"` + Permanently bool `url:"permanently"` +} + +func (irq DeleteRequest) Validate() error { + if irq.ImageId == 0 { + return errors.New("validation-error: field ImageId can not be empty or equal to 0") + } + + return nil +} + +func (i Image) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/image/delete" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := i.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/image/get.go b/image/get.go new file mode 100644 index 0000000..133392d --- /dev/null +++ b/image/get.go @@ -0,0 +1,54 @@ +package image + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + ImageId uint64 `url:"imageId"` + ShowAll bool `url:"show_all,omitempty"` +} + +func (irq GetRequest) Validate() error { + if irq.ImageId == 0 { + return errors.New("validation-error: field ImageId can not be empty or equal to 0") + } + + return nil +} + +func (i Image) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*ImageExtend, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/image/get" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := i.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + imageInfo := &ImageExtend{} + + err = json.Unmarshal(res, imageInfo) + if err != nil { + return nil, err + } + + return imageInfo, nil +} diff --git a/image/image.go b/image/image.go new file mode 100644 index 0000000..455b3f9 --- /dev/null +++ b/image/image.go @@ -0,0 +1,15 @@ +package image + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Image struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Image { + return &Image{ + client, + } +} diff --git a/image/link.go b/image/link.go new file mode 100644 index 0000000..0c923c6 --- /dev/null +++ b/image/link.go @@ -0,0 +1,57 @@ +package image + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type LinkRequest struct { + ImageId uint64 `url:"imageId"` + TargetId uint64 `url:"targetId"` +} + +func (irq LinkRequest) Validate() error { + if irq.ImageId == 0 { + return errors.New("validation-error: field ImageId can not be empty or equal to 0") + } + if irq.TargetId == 0 { + return errors.New("validation-error: field TargetId can not be empty or equal to 0") + } + + return nil +} + +func (i Image) Link(ctx context.Context, req LinkRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/image/link" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := i.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/image/list.go b/image/list.go new file mode 100644 index 0000000..17e7807 --- /dev/null +++ b/image/list.go @@ -0,0 +1,42 @@ +package image + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + AccountId uint64 `json:"accountId"` + Page uint64 `json:"page"` + Size uint64 `json:"size"` +} + +func (i Image) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (ImageList, error) { + + url := "/image/list" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := i.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + imageList := ImageList{} + + err = json.Unmarshal(res, &imageList) + if err != nil { + return nil, err + } + + return imageList, nil +} diff --git a/image/models.go b/image/models.go new file mode 100644 index 0000000..8b95f3b --- /dev/null +++ b/image/models.go @@ -0,0 +1,68 @@ +package image + +type ImageRecord struct { + AccountId uint64 `json:"accountId"` + Architecture string `json:"architecture"` + BootType string `json:"bootType"` + Bootable bool `json:"bootable"` + CDROM bool `json:"cdrom"` + Description string `json:"desc"` + Drivers []string `json:"drivers"` + HotResize bool `json:"hotResize"` + ID uint64 `json:"id"` + LinkTo uint64 `json:"linkTo"` + Name string `json:"name"` + Pool string `json:"pool"` + SepId uint64 `json:"sepId"` + Size uint64 `json:"size"` + Status string `json:"status"` + Type string `json:"type"` + Username string `json:"username"` + Virtual bool `json:"virtual"` +} + +type ImageList []ImageRecord + +type History struct { + GUID string `json:"guid"` + ID uint64 `json:"id"` + Timestamp uint64 `json:"timestamp"` +} + +type ImageExtend struct { + UNCPath string `json:"UNCPath"` + CKey string `json:"_ckey"` + AccountId uint64 `json:"accountId"` + Acl interface{} `json:"acl"` + Architecture string `json:"architecture"` + BootType string `json:"bootType"` + Bootable bool `json:"bootable"` + ComputeCiId uint64 `json:"computeciId"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + Drivers []string `json:"drivers"` + Enabled bool `json:"enabled"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + History []History `json:"history"` + HotResize bool `json:"hotResize"` + ID uint64 `json:"id"` + LastModified uint64 `json:"lastModified"` + LinkTo uint64 `json:"linkTo"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + Password string `json:"password"` + Pool string `json:"pool"` + ProviderName string `json:"provider_name"` + PurgeAttempts int `json:"purgeAttempts"` + ResId string `json:"resId"` + RescueCD bool `json:"rescuecd"` + SepId uint64 `json:"sepId"` + SharedWith []int `json:"sharedWith"` + Size uint64 `json:"size"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` + Username string `json:"username"` + Version string `json:"version"` +} diff --git a/image/rename.go b/image/rename.go new file mode 100644 index 0000000..152654a --- /dev/null +++ b/image/rename.go @@ -0,0 +1,58 @@ +package image + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RenameRequest struct { + ImageId uint64 `url:"imageId"` + Name string `url:"name"` +} + +func (irq RenameRequest) Validate() error { + if irq.ImageId == 0 { + return errors.New("validation-error: field ImageId can not be empty or equal to 0") + } + + if irq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + return nil +} + +func (i Image) Rename(ctx context.Context, req RenameRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/image/rename" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := i.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil + +} diff --git a/interfaces/caller.go b/interfaces/caller.go new file mode 100644 index 0000000..7dbcdfe --- /dev/null +++ b/interfaces/caller.go @@ -0,0 +1,7 @@ +package interfaces + +import "context" + +type Caller interface { + DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) +} diff --git a/internal/validators/helper.go b/internal/validators/helper.go new file mode 100644 index 0000000..737c1ba --- /dev/null +++ b/internal/validators/helper.go @@ -0,0 +1,10 @@ +package validators + +func StringInSlice(str string, target []string) bool { + for _, v := range target { + if v == str { + return true + } + } + return false +} diff --git a/k8ci.go b/k8ci.go new file mode 100644 index 0000000..8a5075a --- /dev/null +++ b/k8ci.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/k8ci" +) + +func (dc *decortClient) K8CI() *k8ci.K8CI { + return k8ci.New(dc) +} diff --git a/k8ci/get.go b/k8ci/get.go new file mode 100644 index 0000000..4f5c06f --- /dev/null +++ b/k8ci/get.go @@ -0,0 +1,41 @@ +package k8ci + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + K8CIID uint64 `url:"k8ciId"` +} + +func (krq GetRequest) Validate() error { + if krq.K8CIID == 0 { + return errors.New("field K8CIID can not be empty or equal to 0") + } + + return nil +} + +func (k K8CI) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*K8CIRecord, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/k8ci/get" + k8ciRaw, err := k.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + k8ci := &K8CIRecord{} + if err := json.Unmarshal(k8ciRaw, k8ci); err != nil { + return nil, err + } + + return k8ci, nil +} diff --git a/k8ci/k8ci.go b/k8ci/k8ci.go new file mode 100644 index 0000000..0e5a774 --- /dev/null +++ b/k8ci/k8ci.go @@ -0,0 +1,15 @@ +package k8ci + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type K8CI struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *K8CI { + return &K8CI{ + client, + } +} diff --git a/k8ci/list.go b/k8ci/list.go new file mode 100644 index 0000000..de4dc52 --- /dev/null +++ b/k8ci/list.go @@ -0,0 +1,30 @@ +package k8ci + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + IncludeDisabled bool `url:"includeDisabled,omitempty"` + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (k K8CI) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (K8CIList, error) { + url := "/cloudapi/k8ci/list" + k8ciListRaw, err := k.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + k8ciList := K8CIList{} + if err := json.Unmarshal(k8ciListRaw, &k8ciList); err != nil { + return nil, err + } + + return k8ciList, nil +} diff --git a/k8ci/list_deleted.go b/k8ci/list_deleted.go new file mode 100644 index 0000000..2051a2a --- /dev/null +++ b/k8ci/list_deleted.go @@ -0,0 +1,29 @@ +package k8ci + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListDeletedRequest struct { + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (k K8CI) ListDeleted(ctx context.Context, req ListDeletedRequest, options ...opts.DecortOpts) (K8CIList, error) { + url := "/cloudapi/k8ci/listDeleted" + k8ciListRaw, err := k.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + k8ciList := K8CIList{} + if err := json.Unmarshal(k8ciListRaw, &k8ciList); err != nil { + return nil, err + } + + return k8ciList, nil +} diff --git a/k8ci/models.go b/k8ci/models.go new file mode 100644 index 0000000..fcb1af0 --- /dev/null +++ b/k8ci/models.go @@ -0,0 +1,15 @@ +package k8ci + +type K8CIItem struct { + CreatedTime uint64 `json:"createdTime"` + K8CIRecord +} + +type K8CIList []K8CIItem + +type K8CIRecord struct { + Description string `json:"desc"` + ID uint64 `json:"id"` + Name string `json:"name"` + Version string `json:"version"` +} diff --git a/k8s.go b/k8s.go new file mode 100644 index 0000000..d4fff95 --- /dev/null +++ b/k8s.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/k8s" +) + +func (dc *decortClient) K8S() *k8s.K8S { + return k8s.New(dc) +} diff --git a/k8s/create.go b/k8s/create.go new file mode 100644 index 0000000..64f90b1 --- /dev/null +++ b/k8s/create.go @@ -0,0 +1,75 @@ +package k8s + +import ( + "context" + "errors" + "strings" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + Name string `url:"name"` + RGID uint64 `url:"rgId"` + K8SCIId uint64 `url:"k8ciId"` + WorkerGroupName string `url:"workerGroupName"` + Labels []string `url:"labels,omitempty"` + Taints []string `url:"taints,omitempty"` + Annotations []string `url:"annotations,omitempty"` + MasterNum uint `url:"masterNum,omitempty"` + MasterCPU uint `url:"masterCPU,omitempty"` + MasterRAM uint `url:"masterRam,omitempty"` + MasterDisk uint `url:"masterDisk,omitempty"` + WorkerNum uint `url:"workerNum,omitempty"` + WorkerCPU uint `url:"workerCPU,omitempty"` + WorkerRAM uint `url:"workerRam,omitempty"` + WorkerDisk uint `url:"workerDisk,omitempty"` + ExtnetId uint64 `url:"extnetId,omitempty"` + WithLB bool `url:"withLB,omitempty"` + Description string `url:"desc, omitempty"` +} + +func (krq CreateRequest) Validate() error { + if krq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + if krq.RGID == 0 { + return errors.New("validation-error: field RgId can not be empty or equal to 0") + } + if krq.K8SCIId == 0 { + return errors.New("validation-error: field K8SCIId can not be empty or equal to 0") + } + + if krq.WorkerGroupName == "" { + return errors.New("validation-error: field WorkerGroupName can not be empty") + } + + return nil +} + +func (k8s K8S) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/k8s/create" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return strings.ReplaceAll(string(res), "\"", ""), nil + +} diff --git a/k8s/delete.go b/k8s/delete.go new file mode 100644 index 0000000..a2c4c73 --- /dev/null +++ b/k8s/delete.go @@ -0,0 +1,51 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + K8SId uint64 `url:"k8sId"` + Permanently bool `url:"permanently"` +} + +func (krq DeleteRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/delete" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/delete_master_from_group.go b/k8s/delete_master_from_group.go new file mode 100644 index 0000000..43b7c2b --- /dev/null +++ b/k8s/delete_master_from_group.go @@ -0,0 +1,59 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteMasterFromGroupRequest struct { + K8SId uint64 `url:"k8sId"` + MasterGroupId uint64 `url:"masterGroupId"` + MasterIds []string `url:"masterIds"` +} + +func (krq DeleteMasterFromGroupRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + if krq.MasterGroupId == 0 { + return errors.New("validation-error: field MasterGroupId can not be empty or equal to 0") + } + + if len(krq.MasterIds) == 0 { + return errors.New("validation-error: field MasterIds can not be empty") + } + + return nil +} + +func (k8s K8S) DeleteMasterFromGroup(ctx context.Context, req DeleteMasterFromGroupRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/deleteMasterFromGroup" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/delete_worker_from_group.go b/k8s/delete_worker_from_group.go new file mode 100644 index 0000000..447e1bf --- /dev/null +++ b/k8s/delete_worker_from_group.go @@ -0,0 +1,59 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteWorkerFromGroupRequest struct { + K8SId uint64 `url:"k8sId"` + WorkersGroupId uint64 `url:"workersGroupId"` + WorkerId uint64 `url:"workerId"` +} + +func (krq DeleteWorkerFromGroupRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + if krq.WorkersGroupId == 0 { + return errors.New("validation-error: field WorkersGroupId can not be empty or equal to 0") + } + + if krq.WorkerId == 0 { + return errors.New("validation-error: field WorkerId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) DeleteWorkerFromGroup(ctx context.Context, req DeleteWorkerFromGroupRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/deleteWorkerFromGroup" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/disable_enable.go b/k8s/disable_enable.go new file mode 100644 index 0000000..f9f8321 --- /dev/null +++ b/k8s/disable_enable.go @@ -0,0 +1,78 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DisabelEnableRequest struct { + K8SId uint64 `url:"k8sId"` +} + +func (krq DisabelEnableRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) Disable(ctx context.Context, req DisabelEnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/disable" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} + +func (k8s K8S) Enable(ctx context.Context, req DisabelEnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/enable" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/find_group_by_label.go b/k8s/find_group_by_label.go new file mode 100644 index 0000000..c9760bf --- /dev/null +++ b/k8s/find_group_by_label.go @@ -0,0 +1,59 @@ +package k8s + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type FindGroupByLabelRequest struct { + K8SId uint64 `url:"k8sId"` + Labels []string `url:"labels"` + Strict bool `url:"strict"` +} + +func (krq FindGroupByLabelRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + if len(krq.Labels) == 0 { + return errors.New("validation-error: field Labels can not be empty") + } + + return nil +} + +func (k8s K8S) FindGroupByLabel(ctx context.Context, req FindGroupByLabelRequest, options ...opts.DecortOpts) (K8SGroupList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/k8s/findGroupByLabel" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + k8sGroupList := K8SGroupList{} + + err = json.Unmarshal(res, &k8sGroupList) + if err != nil { + return nil, err + } + + return k8sGroupList, nil +} diff --git a/k8s/get.go b/k8s/get.go new file mode 100644 index 0000000..deea0ce --- /dev/null +++ b/k8s/get.go @@ -0,0 +1,53 @@ +package k8s + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + K8SId uint64 `url:"k8sId"` +} + +func (krq GetRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*K8SRecord, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/k8s/get" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + k8sInfo := &K8SRecord{} + + err = json.Unmarshal(res, k8sInfo) + if err != nil { + return nil, err + } + + return k8sInfo, nil +} diff --git a/k8s/get_config.go b/k8s/get_config.go new file mode 100644 index 0000000..f1fe5fe --- /dev/null +++ b/k8s/get_config.go @@ -0,0 +1,45 @@ +package k8s + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetConfigRequest struct { + K8SId uint64 `url:"k8sId"` +} + +func (krq GetConfigRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) GetConfig(ctx context.Context, req GetConfigRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/k8s/getConfig" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/k8s/get_node_annotations.go b/k8s/get_node_annotations.go new file mode 100644 index 0000000..b452df4 --- /dev/null +++ b/k8s/get_node_annotations.go @@ -0,0 +1,49 @@ +package k8s + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetNodeAnnotationsRequest struct { + K8SId uint64 `url:"k8sId"` + NodeId uint64 `url:"nodeId"` +} + +func (krq GetNodeAnnotationsRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + if krq.NodeId == 0 { + return errors.New("validation-error: field NodeId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) GetNodeAnnotations(ctx context.Context, req GetNodeAnnotationsRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/k8s/getNodeAnnotations" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/k8s/get_node_taints.go b/k8s/get_node_taints.go new file mode 100644 index 0000000..b38048a --- /dev/null +++ b/k8s/get_node_taints.go @@ -0,0 +1,49 @@ +package k8s + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetNodeTaintsRequest struct { + K8SId uint64 `url:"k8sId"` + NodeId uint64 `url:"nodeId"` +} + +func (krq GetNodeTaintsRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + if krq.NodeId == 0 { + return errors.New("validation-error: field NodeId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) GetNodeTaints(ctx context.Context, req GetNodeTaintsRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/k8s/getNodeTaints" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/k8s/k8s.go b/k8s/k8s.go new file mode 100644 index 0000000..ac40198 --- /dev/null +++ b/k8s/k8s.go @@ -0,0 +1,15 @@ +package k8s + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type K8S struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *K8S { + return &K8S{ + client, + } +} diff --git a/k8s/list.go b/k8s/list.go new file mode 100644 index 0000000..7eb89e8 --- /dev/null +++ b/k8s/list.go @@ -0,0 +1,42 @@ +package k8s + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + IncludeDeleted bool `json:"includedeleted"` + Page uint64 `json:"page"` + Size uint64 `json:"size"` +} + +func (k8s K8S) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (K8SList, error) { + + url := "/k8s/list" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + k8sList := K8SList{} + + err = json.Unmarshal(res, &k8sList) + if err != nil { + return nil, err + } + + return k8sList, nil +} diff --git a/k8s/list_deleted.go b/k8s/list_deleted.go new file mode 100644 index 0000000..01375a0 --- /dev/null +++ b/k8s/list_deleted.go @@ -0,0 +1,41 @@ +package k8s + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListDeletedRequest struct { + Page uint64 `json:"page"` + Size uint64 `json:"size"` +} + +func (k8s K8S) ListDeleted(ctx context.Context, req ListDeletedRequest, options ...opts.DecortOpts) (K8SList, error) { + + url := "/k8s/listDeleted" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + k8sList := K8SList{} + + err = json.Unmarshal(res, &k8sList) + if err != nil { + return nil, err + } + + return k8sList, nil +} diff --git a/k8s/models.go b/k8s/models.go new file mode 100644 index 0000000..c1ffa39 --- /dev/null +++ b/k8s/models.go @@ -0,0 +1,119 @@ +package k8s + +type K8SGroup struct { + Annotations []string `json:"annotations"` + CPU uint `json:"cpu"` + DetailedInfo DetailedInfoList `json:"detailedInfo"` + Disk uint `json:"disk"` + GUID string `json:"guid"` + ID uint64 `json:"id"` + Labels []string `json:"labels"` + Name string `json:"name"` + Num uint `json:"num"` + RAM uint `json:"ram"` + Taints []string `json:"taints"` +} + +type K8SGroupList []K8SGroup + +type DetailedInfo struct { + ID uint64 `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` +} + +type DetailedInfoList []DetailedInfo + +type K8SRecord struct { + ACL ACLGroup `json:"ACL"` + AccountId uint64 `json:"accountId"` + AccountName string `json:"accountName"` + BServiceId uint64 `json:"bserviceId"` + CIId uint64 `json:"ciId"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + ID uint64 `json:"id"` + K8CIName string `json:"k8ciName"` + K8SGroups K8SGroups `json:"k8sGroups"` + LBId uint64 `json:"lbId"` + Name string `json:"name"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` +} + +type K8SGroups struct { + Masters MasterGroup `json:"masters"` + Workers K8SGroupList `json:"workers"` +} + +type MasterGroup struct { + CPU uint `json:"cpu"` + DetailedInfo DetailedInfoList `json:"detailedInfo"` + Disk uint `json:"disk"` + ID uint64 `json:"id"` + Name string `json:"name"` + Num uint `json:"num"` + RAM uint `json:"ram"` +} + +type ACLGroup struct { + AccountAcl AclList `json:"accountAcl"` + K8SAcl AclList `json:"k8sAcl"` + RGAcl AclList `json:"rgAcl"` +} + +type Acl struct { + Explicit bool `json:"explicit"` + GUID string `json:"guid"` + Right string `json:"right"` + Status string `json:"status"` + Type string `json:"type"` + UserGroupId string `json:"userGroupId"` +} + +type AclList []Acl + +type K8SItem struct { + AccountId uint64 `json:"accountId"` + AccountName string `json:"accountName"` + Acl string `json:"acl"` + BServiceId uint64 `json:"bserviceId"` + CIId uint64 `json:"ciId"` + Config string `json:"config"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + ExtnetId uint64 `json:"extnetId"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LBId uint64 `json:"lbId"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + ServiceAccount ServiceAccount `json:"serviceAccount"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + VinsId uint64 `json:"vinsId"` + WorkersGroup K8SGroupList `json:"workersGroups"` +} + +type ServiceAccount struct { + GUID string `json:"guid"` + Password string `json:"password"` + Username string `json:"username"` +} + +type K8SList []K8SItem diff --git a/k8s/restore.go b/k8s/restore.go new file mode 100644 index 0000000..eda1150 --- /dev/null +++ b/k8s/restore.go @@ -0,0 +1,50 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestoreRequest struct { + K8SId uint64 `url:"k8sId"` +} + +func (krq RestoreRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) Restore(ctx context.Context, req RestoreRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/restore" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/start.go b/k8s/start.go new file mode 100644 index 0000000..0114157 --- /dev/null +++ b/k8s/start.go @@ -0,0 +1,50 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type StartRequest struct { + K8SId uint64 `url:"k8sId"` +} + +func (krq StartRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) Start(ctx context.Context, req StartRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/start" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/stop.go b/k8s/stop.go new file mode 100644 index 0000000..339b96f --- /dev/null +++ b/k8s/stop.go @@ -0,0 +1,50 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type StopRequest struct { + K8SId uint64 `url:"k8sId"` +} + +func (krq StopRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) Stop(ctx context.Context, req StopRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/stop" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/update.go b/k8s/update.go new file mode 100644 index 0000000..22ffb68 --- /dev/null +++ b/k8s/update.go @@ -0,0 +1,52 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UpdateRequest struct { + K8SId uint64 `url:"k8sId"` + Name string `url:"name,omitempty"` + Description string `url:"desc,omitempty"` +} + +func (krq UpdateRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) Update(ctx context.Context, req UpdateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/update" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/worker_add.go b/k8s/worker_add.go new file mode 100644 index 0000000..be75474 --- /dev/null +++ b/k8s/worker_add.go @@ -0,0 +1,60 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type WorkerAddRequest struct { + K8SId uint64 `url:"k8sId"` + WorkersGroupId uint64 `url:"workersGroupId"` + Num uint `url:"num"` +} + +func (krq WorkerAddRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + if krq.WorkersGroupId == 0 { + return errors.New("validation-error: field WorkersGroupId can not be empty or equal to 0") + } + + if krq.Num == 0 { + return errors.New("validation-error: field Num can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) WorkerAdd(ctx context.Context, req WorkerAddRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/workerAdd" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/worker_reset.go b/k8s/worker_reset.go new file mode 100644 index 0000000..58d7bdf --- /dev/null +++ b/k8s/worker_reset.go @@ -0,0 +1,60 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type WorkerResetRequest struct { + K8SId uint64 `url:"k8sId"` + WorkersGroupId uint64 `url:"workersGroupId"` + WorkerId uint64 `url:"workerId"` +} + +func (krq WorkerResetRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + if krq.WorkersGroupId == 0 { + return errors.New("validation-error: field WorkersGroupId can not be empty or equal to 0") + } + + if krq.WorkerId == 0 { + return errors.New("validation-error: field WorkerId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) WorkerReset(ctx context.Context, req WorkerResetRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/workerReset" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/worker_restart.go b/k8s/worker_restart.go new file mode 100644 index 0000000..cb21615 --- /dev/null +++ b/k8s/worker_restart.go @@ -0,0 +1,60 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type WorkerRestartRequest struct { + K8SId uint64 `url:"k8sId"` + WorkersGroupId uint64 `url:"workersGroupId"` + WorkerId uint64 `url:"workerId"` +} + +func (krq WorkerRestartRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + if krq.WorkersGroupId == 0 { + return errors.New("validation-error: field WorkersGroupId can not be empty or equal to 0") + } + + if krq.WorkerId == 0 { + return errors.New("validation-error: field WorkerId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) WorkerRestart(ctx context.Context, req WorkerRestartRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/workerRestart" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/workers_group_add.go b/k8s/workers_group_add.go new file mode 100644 index 0000000..73e7b5b --- /dev/null +++ b/k8s/workers_group_add.go @@ -0,0 +1,74 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type WorkersGroupAddRequest struct { + K8SId uint64 `url:"k8sId"` + Name string `url:"name"` + Labels []string `url:"labels"` + Taints []string `url:"taints"` + Annotations []string `url:"annotations"` + WorkerNum uint `url:"workerNum"` + WorkerCpu uint `url:"workerCpu"` + WorkerRam uint `url:"workerRam"` + WorkerDisk uint `url:"workerDisk"` +} + +func (krq WorkersGroupAddRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + if krq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + if krq.WorkerNum == 0 { + return errors.New("validation-error: field WorkerNum can not be empty or equal to 0") + } + + if krq.WorkerCpu == 0 { + return errors.New("validation-error: field WorkerCpu can not be empty or equal to 0") + } + + if krq.WorkerRam < 1024 { + return errors.New("validation-error: field WorkerRam must be greater or equal 1024") + } + + return nil +} + +func (k8s K8S) WorkersGroupAdd(ctx context.Context, req WorkersGroupAddRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/workersGroupAdd" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/workers_group_delete.go b/k8s/workers_group_delete.go new file mode 100644 index 0000000..a626ded --- /dev/null +++ b/k8s/workers_group_delete.go @@ -0,0 +1,55 @@ +package k8s + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type WorkersGroupDeleteRequest struct { + K8SId uint64 `url:"k8sId"` + WorkersGroupId uint64 `url:"workersGroupId"` +} + +func (krq WorkersGroupDeleteRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + if krq.WorkersGroupId == 0 { + return errors.New("validation-error: field WorkersGroupId can not be empty or equal to 0") + } + + return nil +} + +func (k8s K8S) WorkersGroupDelete(ctx context.Context, req WorkersGroupDeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/k8s/workersGroupDelete" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + return result, nil +} diff --git a/k8s/workers_group_get_by_name.go b/k8s/workers_group_get_by_name.go new file mode 100644 index 0000000..9d5166e --- /dev/null +++ b/k8s/workers_group_get_by_name.go @@ -0,0 +1,58 @@ +package k8s + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type WorkersGroupGetByNameRequest struct { + K8SId uint64 `url:"k8sId"` + GroupName string `url:"groupName "` +} + +func (krq WorkersGroupGetByNameRequest) Validate() error { + if krq.K8SId == 0 { + return errors.New("validation-error: field K8SId can not be empty or equal to 0") + } + + if krq.GroupName == "" { + return errors.New("validation-error: field WorkersGroupId can not be empty") + } + + return nil +} + +func (k8s K8S) WorkersGroupGetByName(ctx context.Context, req WorkersGroupGetByNameRequest, options ...opts.DecortOpts) (*K8SGroup, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/k8s/workersGroupGetByName" + prefix := "/cloudapi" + + option := opts.New(options) + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k8s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + group := &K8SGroup{} + + err = json.Unmarshal(res, group) + if err != nil { + return nil, err + } + + return group, nil +} diff --git a/kvmppc.go b/kvmppc.go new file mode 100644 index 0000000..0731e01 --- /dev/null +++ b/kvmppc.go @@ -0,0 +1,7 @@ +package client + +import "github.com/rudecs/decort-sdk/kvmppc" + +func (dc *decortClient) KVMPPC() *kvmppc.KVMPPC { + return kvmppc.New(dc) +} diff --git a/kvmppc/create.go b/kvmppc/create.go new file mode 100644 index 0000000..0ca4eb3 --- /dev/null +++ b/kvmppc/create.go @@ -0,0 +1,79 @@ +package kvmppc + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + RGID uint64 `url:"rgId"` + Name string `url:"name"` + CPU uint64 `url:"cpu"` + RAM uint64 `url:"ram"` + ImageID uint64 `url:"imageId"` + BootDisk uint64 `url:"bootDisk,omitempty"` + SepID uint64 `url:"sepId,omitempty"` + Pool string `url:"pool,omitempty"` + NetType string `url:"netType,omitempty"` + NetID uint64 `url:"netId,omitempty"` + IPAddr string `url:"ipAddr,omitempty"` + Userdata string `url:"userdata,omitempty"` + Description string `url:"desc,omitempty"` + Start bool `url:"start,omitempty"` + IS string `url:"IS,omitempty"` + IPAType string `url:"ipaType,omitempty"` +} + +func (krq CreateRequest) Validate() error { + if krq.RGID == 0 { + return errors.New("validation-error: field RGID can not be empty or equal to 0") + } + if krq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + if krq.CPU == 0 { + return errors.New("validation-error: field CPU can not be empty or equal to 0") + } + if krq.RAM == 0 { + return errors.New("validation-error: field RAM can not be empty or equal to 0") + } + if krq.ImageID == 0 { + return errors.New("validation-error: field ImageID can not be empty or equal to 0") + } + + return nil +} + +func (k KVMPPC) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/kvmppc/create" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + return result, nil + +} diff --git a/kvmppc/create_blank.go b/kvmppc/create_blank.go new file mode 100644 index 0000000..ae5249c --- /dev/null +++ b/kvmppc/create_blank.go @@ -0,0 +1,80 @@ +package kvmppc + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateBlankRequest struct { + RGID uint64 `url:"rgId"` + Name string `url:"name"` + CPU uint64 `url:"cpu"` + RAM uint64 `url:"ram"` + BootDisk uint64 `url:"bootDisk"` + SepID uint64 `url:"sepId"` + Pool string `url:"pool"` + NetType string `url:"netType,omitempty"` + NetID uint64 `url:"netId,omitempty"` + IPAddr string `url:"ipAddr,omitempty"` + Description string `url:"desc,omitempty"` +} + +func (krq CreateBlankRequest) Validate() error { + if krq.RGID == 0 { + return errors.New("validation-error: field RGID can not be empty or equal to 0") + } + if krq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + if krq.CPU == 0 { + return errors.New("validation-error: field CPU can not be empty or equal to 0") + } + if krq.RAM == 0 { + return errors.New("validation-error: field RAM can not be empty or equal to 0") + } + if krq.BootDisk == 0 { + return errors.New("validation-error: field BootDisk can not be empty or equal to 0") + } + if krq.SepID == 0 { + return errors.New("validation-error: field SepID can not be empty or equal to 0") + } + if krq.Pool == "" { + return errors.New("validation-error: field Pool can not be empty") + } + + return nil +} + +func (k KVMPPC) CreateBlank(ctx context.Context, req CreateBlankRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/kvmppc/createBlank" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + return result, nil + +} diff --git a/kvmppc/kvmppc.go b/kvmppc/kvmppc.go new file mode 100644 index 0000000..e206e75 --- /dev/null +++ b/kvmppc/kvmppc.go @@ -0,0 +1,15 @@ +package kvmppc + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type KVMPPC struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *KVMPPC { + return &KVMPPC{ + client, + } +} diff --git a/kvmx86.go b/kvmx86.go new file mode 100644 index 0000000..32d3333 --- /dev/null +++ b/kvmx86.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/kvmx86" +) + +func (dc *decortClient) KVMX86() *kvmx86.KVMX86 { + return kvmx86.New(dc) +} diff --git a/kvmx86/create.go b/kvmx86/create.go new file mode 100644 index 0000000..fb1e8c0 --- /dev/null +++ b/kvmx86/create.go @@ -0,0 +1,79 @@ +package kvmx86 + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + RGID uint64 `url:"rgId"` + Name string `url:"name"` + CPU uint64 `url:"cpu"` + RAM uint64 `url:"ram"` + ImageID uint64 `url:"imageId"` + BootDisk uint64 `url:"bootDisk,omitempty"` + SepID uint64 `url:"sepId,omitempty"` + Pool string `url:"pool,omitempty"` + NetType string `url:"netType,omitempty"` + NetID uint64 `url:"netId,omitempty"` + IPAddr string `url:"ipAddr,omitempty"` + Userdata string `url:"userdata,omitempty"` + Description string `url:"desc,omitempty"` + Start bool `url:"start,omitempty"` + IS string `url:"IS,omitempty"` + IPAType string `url:"ipaType,omitempty"` +} + +func (krq CreateRequest) Validate() error { + if krq.RGID == 0 { + return errors.New("validation-error: field RGID can not be empty or equal to 0") + } + if krq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + if krq.CPU == 0 { + return errors.New("validation-error: field CPU can not be empty or equal to 0") + } + if krq.RAM == 0 { + return errors.New("validation-error: field RAM can not be empty or equal to 0") + } + if krq.ImageID == 0 { + return errors.New("validation-error: field ImageID can not be empty or equal to 0") + } + + return nil +} + +func (k KVMX86) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/kvmx86/create" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + return result, nil + +} diff --git a/kvmx86/create_blank.go b/kvmx86/create_blank.go new file mode 100644 index 0000000..90de019 --- /dev/null +++ b/kvmx86/create_blank.go @@ -0,0 +1,80 @@ +package kvmx86 + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateBlankRequest struct { + RGID uint64 `url:"rgId"` + Name string `url:"name"` + CPU uint64 `url:"cpu"` + RAM uint64 `url:"ram"` + BootDisk uint64 `url:"bootDisk"` + SepID uint64 `url:"sepId"` + Pool string `url:"pool"` + NetType string `url:"netType,omitempty"` + NetID uint64 `url:"netId,omitempty"` + IPAddr string `url:"ipAddr,omitempty"` + Description string `url:"desc,omitempty"` +} + +func (krq CreateBlankRequest) Validate() error { + if krq.RGID == 0 { + return errors.New("validation-error: field RGID can not be empty or equal to 0") + } + if krq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + if krq.CPU == 0 { + return errors.New("validation-error: field CPU can not be empty or equal to 0") + } + if krq.RAM == 0 { + return errors.New("validation-error: field RAM can not be empty or equal to 0") + } + if krq.BootDisk == 0 { + return errors.New("validation-error: field BootDisk can not be empty or equal to 0") + } + if krq.SepID == 0 { + return errors.New("validation-error: field SepID can not be empty or equal to 0") + } + if krq.Pool == "" { + return errors.New("validation-error: field Pool can not be empty") + } + + return nil +} + +func (k KVMX86) CreateBlank(ctx context.Context, req CreateBlankRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/kvmx86/createBlank" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := k.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + return result, nil + +} diff --git a/kvmx86/kvmx86.go b/kvmx86/kvmx86.go new file mode 100644 index 0000000..40cd87a --- /dev/null +++ b/kvmx86/kvmx86.go @@ -0,0 +1,15 @@ +package kvmx86 + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type KVMX86 struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *KVMX86 { + return &KVMX86{ + client, + } +} diff --git a/lb.go b/lb.go new file mode 100644 index 0000000..e20674b --- /dev/null +++ b/lb.go @@ -0,0 +1,7 @@ +package client + +import "github.com/rudecs/decort-sdk/lb" + +func (dc *decortClient) LB() *lb.LB { + return lb.New(dc) +} diff --git a/lb/backend_create.go b/lb/backend_create.go new file mode 100644 index 0000000..fe56fcf --- /dev/null +++ b/lb/backend_create.go @@ -0,0 +1,66 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type BackendCreateRequest struct { + LBID uint64 `url:"lbId"` + BackendName string `url:"backendName"` + Algorithm string `url:"algorithm,omitempty"` + Inter uint64 `url:"inter,omitempty"` + DownInter uint64 `url:"downinter,omitempty"` + Rise uint `url:"rise,omitempty"` + Fall uint `url:"fall,omitempty"` + SlowStart uint64 `url:"slowstart,omitempty"` + MaxConn uint `url:"maxconn,omitempty"` + MaxQueue uint `url:"maxqueue,omitempty"` + Weight uint `url:"weight,omitempty"` +} + +func (lbrq BackendCreateRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.BackendName == "" { + return errors.New("validation-error: field BackendName can not be empty") + } + + return nil +} + +func (l LB) BackendCreate(ctx context.Context, req BackendCreateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/backendCreate" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/backend_delete.go b/lb/backend_delete.go new file mode 100644 index 0000000..1ad68e6 --- /dev/null +++ b/lb/backend_delete.go @@ -0,0 +1,57 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type BackendDeleteRequest struct { + LBID uint64 `url:"lbId"` + BackendName string `url:"backendName"` +} + +func (lbrq BackendDeleteRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.BackendName == "" { + return errors.New("validation-error: field BackendName can not be empty") + } + + return nil +} + +func (l LB) BackendDelete(ctx context.Context, req BackendDeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/backendDelete" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/backend_server_add.go b/lb/backend_server_add.go new file mode 100644 index 0000000..e23f7b7 --- /dev/null +++ b/lb/backend_server_add.go @@ -0,0 +1,81 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type BackendServerAddRequest struct { + LBID uint64 `url:"lbId"` + BackendName string `url:"backendName"` + ServerName string `url:"serverName"` + Address string `url:"address"` + Port uint `url:"port"` + Check string `url:"check,omitempty"` + Inter uint64 `url:"inter,omitempty"` + DownInter uint64 `url:"downinter,omitempty"` + Rise uint `url:"rise,omitempty"` + Fall uint `url:"fall,omitempty"` + SlowStart uint64 `url:"slowstart,omitempty"` + MaxConn uint `url:"maxconn,omitempty"` + MaxQueue uint `url:"maxqueue,omitempty"` + Weight uint `url:"weight,omitempty"` +} + +func (lbrq BackendServerAddRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.BackendName == "" { + return errors.New("validation-error: field BackendName can not be empty") + } + + if lbrq.ServerName == "" { + return errors.New("validation-error: field ServerName can not be empty") + } + + if lbrq.Address == "" { + return errors.New("validation-error: field Address can not be empty") + } + + if lbrq.Port == 0 { + return errors.New("validation-error: field Port can not be empty or equal to 0") + } + + return nil +} + +func (l LB) BackendServerAdd(ctx context.Context, req BackendServerAddRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/backendServerAdd" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/backend_server_delete.go b/lb/backend_server_delete.go new file mode 100644 index 0000000..199e549 --- /dev/null +++ b/lb/backend_server_delete.go @@ -0,0 +1,62 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type BackendServerDeleteRequest struct { + LBID uint64 `url:"lbId"` + BackendName string `url:"backendName"` + ServerName string `url:"serverName"` +} + +func (lbrq BackendServerDeleteRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.BackendName == "" { + return errors.New("validation-error: field BackendName can not be empty") + } + + if lbrq.ServerName == "" { + return errors.New("validation-error: field ServerName can not be empty") + } + + return nil +} + +func (l LB) BackendServerDelete(ctx context.Context, req BackendServerDeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/backendServerDelete" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/backend_server_update.go b/lb/backend_server_update.go new file mode 100644 index 0000000..058fe38 --- /dev/null +++ b/lb/backend_server_update.go @@ -0,0 +1,81 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type BackendServerUpdateRequest struct { + LBID uint64 `url:"lbId"` + BackendName string `url:"backendName"` + ServerName string `url:"serverName"` + Address string `url:"address"` + Port uint `url:"port"` + Check string `url:"check,omitempty"` + Inter uint64 `url:"inter,omitempty"` + DownInter uint64 `url:"downinter,omitempty"` + Rise uint `url:"rise,omitempty"` + Fall uint `url:"fall,omitempty"` + SlowStart uint64 `url:"slowstart,omitempty"` + MaxConn uint `url:"maxconn,omitempty"` + MaxQueue uint `url:"maxqueue,omitempty"` + Weight uint `url:"weight,omitempty"` +} + +func (lbrq BackendServerUpdateRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.BackendName == "" { + return errors.New("validation-error: field BackendName can not be empty") + } + + if lbrq.ServerName == "" { + return errors.New("validation-error: field ServerName can not be empty") + } + + if lbrq.Address == "" { + return errors.New("validation-error: field Address can not be empty") + } + + if lbrq.Port == 0 { + return errors.New("validation-error: field Port can not be empty or equal to 0") + } + + return nil +} + +func (l LB) BackendServerUpdate(ctx context.Context, req BackendServerUpdateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/backendServerUpdate" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/backend_update.go b/lb/backend_update.go new file mode 100644 index 0000000..5961724 --- /dev/null +++ b/lb/backend_update.go @@ -0,0 +1,66 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type BackendUpdateRequest struct { + LBID uint64 `url:"lbId"` + BackendName string `url:"backendName"` + Algorithm string `url:"algorithm,omitempty"` + Inter uint64 `url:"inter,omitempty"` + DownInter uint64 `url:"downinter,omitempty"` + Rise uint `url:"rise,omitempty"` + Fall uint `url:"fall,omitempty"` + SlowStart uint64 `url:"slowstart,omitempty"` + MaxConn uint `url:"maxconn,omitempty"` + MaxQueue uint `url:"maxqueue,omitempty"` + Weight uint `url:"weight,omitempty"` +} + +func (lbrq BackendUpdateRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.BackendName == "" { + return errors.New("validation-error: field BackendName can not be empty") + } + + return nil +} + +func (l LB) BackendUpdate(ctx context.Context, req BackendUpdateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/backendUpdate" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/config_reset.go b/lb/config_reset.go new file mode 100644 index 0000000..395d79f --- /dev/null +++ b/lb/config_reset.go @@ -0,0 +1,52 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ConfigResetRequest struct { + LBID uint64 `url:"lbId"` +} + +func (lbrq ConfigResetRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + return nil +} + +func (l LB) ConfigReset(ctx context.Context, req ConfigResetRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/configReset" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/create.go b/lb/create.go new file mode 100644 index 0000000..97cf5f7 --- /dev/null +++ b/lb/create.go @@ -0,0 +1,64 @@ +package lb + +import ( + "context" + "errors" + "strings" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + RGID uint64 `url:"rgId"` + Name string `url:"name"` + ExtnetId uint64 `url:"extnetId"` + VinsId uint64 `url:"vinsId"` + Start bool `url:"start"` + Description string `url:"desc,omitempty"` +} + +func (lbrq CreateRequest) Validate() error { + if lbrq.RGID == 0 { + return errors.New("validation-error: field RGID can not be empty or equal to 0") + } + + if lbrq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + if lbrq.ExtnetId == 0 { + return errors.New("validation-error: field ExtnetId can not be empty or equal to 0") + } + + if lbrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (l LB) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/lb/create" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return strings.ReplaceAll(string(res), "\"", ""), nil +} diff --git a/lb/delete.go b/lb/delete.go new file mode 100644 index 0000000..10e8b05 --- /dev/null +++ b/lb/delete.go @@ -0,0 +1,53 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + LBID uint64 `url:"lbId"` + Permanently bool `url:"permanently"` +} + +func (lbrq DeleteRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + return nil +} + +func (l LB) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/delete" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/disable_enable.go b/lb/disable_enable.go new file mode 100644 index 0000000..73eea00 --- /dev/null +++ b/lb/disable_enable.go @@ -0,0 +1,82 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DisabelEnableRequest struct { + LBID uint64 `url:"lbId"` +} + +func (lbrq DisabelEnableRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + return nil +} + +func (l LB) Disable(ctx context.Context, req DisabelEnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/disable" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} + +func (l LB) Enable(ctx context.Context, req DisabelEnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/enable" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/frontend_bind.go b/lb/frontend_bind.go new file mode 100644 index 0000000..5229870 --- /dev/null +++ b/lb/frontend_bind.go @@ -0,0 +1,59 @@ +package lb + +import ( + "context" + "errors" + "strings" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type FrontendBindRequest struct { + LBID uint64 `url:"lbId"` + FrontendName string `url:"frontendName"` + BindingName string `url:"bindingName"` + BindingAddress string `url:"bindingAddress,omitempty"` + BindingPort uint `url:"bindingPort,omitempty"` +} + +func (lbrq FrontendBindRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.FrontendName == "" { + return errors.New("validation-error: field FrontendName can not be empty") + } + + if lbrq.BindingName == "" { + return errors.New("validation-error: field BindingName can not be empty") + } + + return nil +} + +func (l LB) FrontendBind(ctx context.Context, req FrontendBindRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/lb/frontendBind" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return strings.ReplaceAll(string(res), "\"", ""), nil +} diff --git a/lb/frontend_bind_delete.go b/lb/frontend_bind_delete.go new file mode 100644 index 0000000..6e386d6 --- /dev/null +++ b/lb/frontend_bind_delete.go @@ -0,0 +1,57 @@ +package lb + +import ( + "context" + "errors" + "strings" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type FrontendBindDeleteRequest struct { + LBID uint64 `url:"lbId"` + FrontendName string `url:"frontendName"` + BindingName string `url:"bindingName"` +} + +func (lbrq FrontendBindDeleteRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.FrontendName == "" { + return errors.New("validation-error: field FrontendName can not be empty") + } + + if lbrq.BindingName == "" { + return errors.New("validation-error: field BindingName can not be empty") + } + + return nil +} + +func (l LB) FrontendBindDelete(ctx context.Context, req FrontendBindDeleteRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/lb/frontendBindDelete" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return strings.ReplaceAll(string(res), "\"", ""), nil +} diff --git a/lb/frontend_bind_update.go b/lb/frontend_bind_update.go new file mode 100644 index 0000000..dde8f9a --- /dev/null +++ b/lb/frontend_bind_update.go @@ -0,0 +1,59 @@ +package lb + +import ( + "context" + "errors" + "strings" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type FrontendBindUpdateRequest struct { + LBID uint64 `url:"lbId"` + FrontendName string `url:"frontendName"` + BindingName string `url:"bindingName"` + BindingAddress string `url:"bindingAddress,omitempty"` + BindingPort uint `url:"bindingPort,omitempty"` +} + +func (lbrq FrontendBindUpdateRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.FrontendName == "" { + return errors.New("validation-error: field FrontendName can not be empty") + } + + if lbrq.BindingName == "" { + return errors.New("validation-error: field BindingName can not be empty") + } + + return nil +} + +func (l LB) FrontendBindUpdate(ctx context.Context, req FrontendBindUpdateRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/lb/frontendBindingUpdate" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return strings.ReplaceAll(string(res), "\"", ""), nil +} diff --git a/lb/frontend_create.go b/lb/frontend_create.go new file mode 100644 index 0000000..cba1626 --- /dev/null +++ b/lb/frontend_create.go @@ -0,0 +1,62 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type FrontendCreateRequest struct { + LBID uint64 `url:"lbId"` + FrontendName string `url:"frontendName"` + BackendName string `url:"backendName"` +} + +func (lbrq FrontendCreateRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.FrontendName == "" { + return errors.New("validation-error: field FrontendName can not be empty") + } + + if lbrq.BackendName == "" { + return errors.New("validation-error: field BackendName can not be empty") + } + + return nil +} + +func (l LB) FrontendCreate(ctx context.Context, req FrontendCreateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/frontendCreate" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/frontend_delete.go b/lb/frontend_delete.go new file mode 100644 index 0000000..1497f7d --- /dev/null +++ b/lb/frontend_delete.go @@ -0,0 +1,57 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type FrontendDeleteRequest struct { + LBID uint64 `url:"lbId"` + FrontendName string `url:"frontendName"` +} + +func (lbrq FrontendDeleteRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + if lbrq.FrontendName == "" { + return errors.New("validation-error: field FrontendName can not be empty") + } + + return nil +} + +func (l LB) FrontendDelete(ctx context.Context, req FrontendDeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/frontendDelete" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/get.go b/lb/get.go new file mode 100644 index 0000000..9de1290 --- /dev/null +++ b/lb/get.go @@ -0,0 +1,54 @@ +package lb + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + LBID uint64 `url:"lbId"` +} + +func (lbrq GetRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + return nil +} + +func (l LB) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*LoadBalancer, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/lb/get" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + lbRaw, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + lb := &LoadBalancer{} + err = json.Unmarshal(lbRaw, lb) + if err != nil { + return nil, err + } + + return lb, nil + +} diff --git a/lb/lb.go b/lb/lb.go new file mode 100644 index 0000000..51f578c --- /dev/null +++ b/lb/lb.go @@ -0,0 +1,15 @@ +package lb + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type LB struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *LB { + return &LB{ + client, + } +} diff --git a/lb/list.go b/lb/list.go new file mode 100644 index 0000000..6aae11d --- /dev/null +++ b/lb/list.go @@ -0,0 +1,42 @@ +package lb + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + IncludeDeleted bool `url:"includedeleted"` + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (l LB) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (LBList, error) { + url := "/lb/list" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + lbListRaw, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + lbList := LBList{} + err = json.Unmarshal(lbListRaw, &lbList) + if err != nil { + return nil, err + } + + return lbList, nil + +} diff --git a/lb/list_deleted.go b/lb/list_deleted.go new file mode 100644 index 0000000..da4c4ff --- /dev/null +++ b/lb/list_deleted.go @@ -0,0 +1,41 @@ +package lb + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListDeletedRequest struct { + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (l LB) ListDeleted(ctx context.Context, req ListDeletedRequest, options ...opts.DecortOpts) (LBList, error) { + url := "/lb/listDeleted" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + lbListRaw, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + lbList := LBList{} + err = json.Unmarshal(lbListRaw, &lbList) + if err != nil { + return nil, err + } + + return lbList, nil + +} diff --git a/lb/models.go b/lb/models.go new file mode 100644 index 0000000..918db52 --- /dev/null +++ b/lb/models.go @@ -0,0 +1,89 @@ +package lb + +type LoadBalancer struct { + HAMode bool `json:"HAmode"` + ACL interface{} `json:"acl"` + Backends []Backend `json:"backends"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + DPAPIUser string `json:"dpApiUser"` + ExtnetId uint64 `json:"extnetId"` + Frontends []Frontend `json:"frontends"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + ImageId uint64 `json:"imageId"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + PrimaryNode Node `json:"primaryNode"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + SecondaryNode Node `json:"secondaryNode"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + VinsId uint64 `json:"vinsId"` +} + +type LoadBalancerDetailed struct { + DPAPIPassword string `json:"dpApiPassword"` + LoadBalancer +} + +type Backend struct { + Algorithm string `json:"algorithm"` + GUID string `json:"guid"` + Name string `json:"name"` + ServerDefaultSettings ServerSettings `json:"serverDefaultSettings"` + Servers []Server `json:"servers"` +} + +type LBList []LoadBalancerDetailed + +type ServerSettings struct { + Inter uint64 `json:"inter"` + GUID string `json:"guid"` + DownInter uint64 `json:"downinter"` + Rise uint `json:"rise"` + Fall uint `json:"fall"` + SlowStart uint64 `json:"slowstart"` + MaxConn uint `json:"maxconn"` + MaxQueue uint `json:"maxqueue"` + Weight uint `json:"weight"` +} + +type Server struct { + Address string `json:"address"` + Check string `json:"check"` + GUID string `json:"guid"` + Name string `json:"name"` + Port uint `json:"port"` + ServerSettings ServerSettings `json:"serverSettings"` +} + +type Node struct { + BackendIp string `json:"backendIp"` + ComputeId uint64 `json:"computeId"` + FrontendIp string `json:"frontendIp"` + GUID string `json:"guid"` + MGMTIp string `json:"mgmtIp"` + NetworkId uint64 `json:"networkId"` +} + +type Frontend struct { + Backend string `json:"backend"` + Bindings []Binding `json:"bindings"` + GUID string `json:"guid"` + Name string `json:"name"` +} + +type Binding struct { + Address string `json:"address"` + GUID string `json:"guid"` + Name string `json:"name"` + Port uint `json:"port"` +} diff --git a/lb/restart.go b/lb/restart.go new file mode 100644 index 0000000..0ef4be3 --- /dev/null +++ b/lb/restart.go @@ -0,0 +1,52 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestartRequest struct { + LBID uint64 `url:"lbId"` +} + +func (lbrq RestartRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + return nil +} + +func (l LB) Restart(ctx context.Context, req RestartRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/restart" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/restore.go b/lb/restore.go new file mode 100644 index 0000000..26cdcea --- /dev/null +++ b/lb/restore.go @@ -0,0 +1,52 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestoreRequest struct { + LBID uint64 `url:"lbId"` +} + +func (lbrq RestoreRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + + return nil +} + +func (l LB) Restore(ctx context.Context, req RestoreRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/restore" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/lb/update.go b/lb/update.go new file mode 100644 index 0000000..fdc8be7 --- /dev/null +++ b/lb/update.go @@ -0,0 +1,56 @@ +package lb + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UpdateRequest struct { + LBID uint64 `url:"lbId"` + Description string `url:"desc"` +} + +func (lbrq UpdateRequest) Validate() error { + if lbrq.LBID == 0 { + return errors.New("validation-error: field LBID can not be empty or equal to 0") + } + if lbrq.Description == "" { + return errors.New("validation-error: field Description can not be empty") + } + + return nil +} + +func (l LB) Update(ctx context.Context, req UpdateRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/lb/update" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, err + } + + return result, nil +} diff --git a/locations/get_url.go b/locations/get_url.go new file mode 100644 index 0000000..39af841 --- /dev/null +++ b/locations/get_url.go @@ -0,0 +1,28 @@ +package locations + +import ( + "context" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +func (l Locations) GetUrl(ctx context.Context, options ...opts.DecortOpts) (string, error) { + url := "/locations/getUrl" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := l.client.DecortApiCall(ctx, typed.POST, url, nil) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/locations/list.go b/locations/list.go new file mode 100644 index 0000000..1b58b7a --- /dev/null +++ b/locations/list.go @@ -0,0 +1,41 @@ +package locations + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (l Locations) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (LocationsList, error) { + url := "/locations/list" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + locationsListRaw, err := l.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + locationsList := LocationsList{} + err = json.Unmarshal(locationsListRaw, &locationsList) + if err != nil { + return nil, err + } + + return locationsList, nil + +} diff --git a/locations/locations.go b/locations/locations.go new file mode 100644 index 0000000..e96917e --- /dev/null +++ b/locations/locations.go @@ -0,0 +1,15 @@ +package locations + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Locations struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Locations { + return &Locations{ + client, + } +} diff --git a/locations/models.go b/locations/models.go new file mode 100644 index 0000000..0c5a11a --- /dev/null +++ b/locations/models.go @@ -0,0 +1,14 @@ +package locations + +type Location struct { + GID int `json:"gid"` + Id int `json:"id"` + Guid int `json:"guid"` + LocationCode string `json:"locationCode"` + Name string `json:"name"` + Flag string `json:"flag"` + Meta []interface{} `json:"_meta"` + CKey string `json:"_ckey"` +} + +type LocationsList []Location diff --git a/locatons.go b/locatons.go new file mode 100644 index 0000000..4bd232e --- /dev/null +++ b/locatons.go @@ -0,0 +1,7 @@ +package client + +import "github.com/rudecs/decort-sdk/locations" + +func (dc *decortClient) Locations() *locations.Locations { + return locations.New(dc) +} diff --git a/opts/decort_opts.go b/opts/decort_opts.go new file mode 100644 index 0000000..4d9f1e7 --- /dev/null +++ b/opts/decort_opts.go @@ -0,0 +1,6 @@ +package opts + +type DecortOpts struct { + Type string + Value string +} diff --git a/opts/opts.go b/opts/opts.go new file mode 100644 index 0000000..c5c76f6 --- /dev/null +++ b/opts/opts.go @@ -0,0 +1,26 @@ +package opts + +import "github.com/rudecs/decort-sdk/typed" + +type Opts struct { + IsAdmin bool + AdminValue string +} + +func New(options []DecortOpts) *Opts { + if len(options) == 0 { + return nil + } + + option := &Opts{} + + for _, v := range options { + if v.Type == typed.TypeAdmin { + option.IsAdmin = true + option.AdminValue = v.Value + } + + } + + return option +} diff --git a/rg.go b/rg.go new file mode 100644 index 0000000..554e7bf --- /dev/null +++ b/rg.go @@ -0,0 +1,7 @@ +package client + +import "github.com/rudecs/decort-sdk/rg" + +func (dc *decortClient) RG() *rg.RG { + return rg.New(dc) +} diff --git a/rg/access_grant.go b/rg/access_grant.go new file mode 100644 index 0000000..0812b0b --- /dev/null +++ b/rg/access_grant.go @@ -0,0 +1,48 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AccessGrantRequest struct { + RGID uint64 `url:"rgId"` + User string `url:"user"` + Right string `url:"right"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq AccessGrantRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + if rgrq.User == "" { + return errors.New("field User can not be empty") + } + + if !validators.StringInSlice(rgrq.Right, []string{"R", "RCX", "ARCXDU"}) { + return errors.New("field Right can only be one of 'R', 'RCX' or 'ARCXDU'") + } + + return nil +} + +func (r RG) AccessGrant(ctx context.Context, req AccessGrantRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/rg/accessGrant" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/rg/access_revoke.go b/rg/access_revoke.go new file mode 100644 index 0000000..cebf587 --- /dev/null +++ b/rg/access_revoke.go @@ -0,0 +1,42 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AccessRevokeRequest struct { + RGID uint64 `url:"rgId"` + User string `url:"user"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq AccessRevokeRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + if rgrq.User == "" { + return errors.New("field User can not be empty") + } + + return nil +} + +func (r RG) AccessRevoke(ctx context.Context, req AccessRevokeRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/rg/accessRevoke" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/rg/affinity_group_computes.go b/rg/affinity_group_computes.go new file mode 100644 index 0000000..cb64e32 --- /dev/null +++ b/rg/affinity_group_computes.go @@ -0,0 +1,46 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityGroupComputesRequest struct { + RGID uint64 `url:"rgId"` + AffinityGroup string `url:"affinityGroup"` +} + +func (rgrq AffinityGroupComputesRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + if rgrq.AffinityGroup == "" { + return errors.New("field AffinityGroup cat not be empty") + } + + return nil +} + +func (r RG) AffinityGroupComputes(ctx context.Context, req AffinityGroupComputesRequest, options ...opts.DecortOpts) (AffinityGroupComputeList, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/affinityGroupComputes" + agcListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + agcList := AffinityGroupComputeList{} + if err := json.Unmarshal(agcListRaw, &agcList); err != nil { + return nil, err + } + + return agcList, nil +} diff --git a/rg/affinity_groups_get.go b/rg/affinity_groups_get.go new file mode 100644 index 0000000..54ab42b --- /dev/null +++ b/rg/affinity_groups_get.go @@ -0,0 +1,46 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityGroupsGetRequest struct { + RGID uint64 `url:"rgId"` + AffinityGroup string `url:"affinityGroup"` +} + +func (rgrq AffinityGroupsGetRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + if rgrq.AffinityGroup == "" { + return errors.New("field AffinityGroup cat not be empty") + } + + return nil +} + +func (r RG) AffinityGroupsGet(ctx context.Context, req AffinityGroupsGetRequest, options ...opts.DecortOpts) ([]uint64, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/affinityGroupsGet" + agListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + agList := []uint64{} + if err := json.Unmarshal(agListRaw, &agList); err != nil { + return nil, err + } + + return agList, nil +} diff --git a/rg/affinity_groups_list.go b/rg/affinity_groups_list.go new file mode 100644 index 0000000..2fb4ead --- /dev/null +++ b/rg/affinity_groups_list.go @@ -0,0 +1,41 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AffinityGroupsListRequest struct { + RGID uint64 `url:"rgId"` +} + +func (rgrq AffinityGroupsListRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) AffinityGroupsList(ctx context.Context, req AffinityGroupsListRequest, options ...opts.DecortOpts) (map[string][]uint64, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/affinityGroupsList" + agListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + agList := map[string][]uint64{} + if err := json.Unmarshal(agListRaw, &agList); err != nil { + return nil, err + } + + return agList, nil +} diff --git a/rg/audits.go b/rg/audits.go new file mode 100644 index 0000000..4830b2e --- /dev/null +++ b/rg/audits.go @@ -0,0 +1,41 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AuditsRequest struct { + RGID uint64 `url:"rgId"` +} + +func (rgrq AuditsRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) Audits(ctx context.Context, req AuditsRequest, options ...opts.DecortOpts) (AuditList, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/audits" + auditListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + auditList := AuditList{} + if err := json.Unmarshal(auditListRaw, &auditList); err != nil { + return nil, err + } + + return auditList, nil +} diff --git a/rg/create.go b/rg/create.go new file mode 100644 index 0000000..d4deeac --- /dev/null +++ b/rg/create.go @@ -0,0 +1,59 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateRequest struct { + AccountID uint64 `url:"accountId"` + GID uint64 `url:"gid"` + Name string `url:"name"` + MaxMemoryCapacity uint64 `url:"maxMemoryCapacity,omitempty"` + MaxVDiskCapacity uint64 `url:"maxVDiskCapacity,omitempty"` + MaxCPUCapacity uint64 `url:"maxCPUCapacity,omitempty"` + MaxNetworkPeerTransfer uint64 `url:"maxNetworkPeerTransfer,omitempty"` + MaxNumPublicIP uint64 `url:"maxNumPublicIP,omitempty"` + Owner string `url:"owner,omitempty"` + DefNet string `url:"def_net,omitempty"` + IPCIDR string `url:"ipcidr,omitempty"` + Desc string `url:"desc,omitempty"` + Reason string `url:"reason,omitempty"` + ExtNetID uint64 `url:"extNetId,omitempty"` + ExtIP string `url:"extIp,omitempty"` + RegisterComputes bool `url:"registerComputes,omitempty"` +} + +func (rgrq CreateRequest) Validate() error { + if rgrq.AccountID == 0 { + return errors.New("field AccountID can not be empty or equal to 0") + } + + if rgrq.GID == 0 { + return errors.New("field GID can not be empty or equal to 0") + } + + if len(rgrq.Name) < 2 { + return errors.New("field Name can not be shorter than two bytes") + } + + return nil +} + +func (r RG) Create(ctx context.Context, req CreateRequest, options ...opts.DecortOpts) (uint64, error) { + if err := req.Validate(); err != nil { + return 0, err + } + + url := "/cloudapi/rg/create" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + return strconv.ParseUint(string(res), 10, 64) +} diff --git a/rg/delete.go b/rg/delete.go new file mode 100644 index 0000000..4264a5f --- /dev/null +++ b/rg/delete.go @@ -0,0 +1,39 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + RGID uint64 `url:"rgId"` + Force bool `url:"force,omitempty"` + Permanently bool `url:"permanently,omitempty"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq DeleteRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/rg/delete" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/rg/disable.go b/rg/disable.go new file mode 100644 index 0000000..f8cb7c1 --- /dev/null +++ b/rg/disable.go @@ -0,0 +1,37 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DisableRequest struct { + RGID uint64 `url:"rgId"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq DisableRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) Disable(ctx context.Context, req DisableRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/rg/disable" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/rg/enable.go b/rg/enable.go new file mode 100644 index 0000000..cde6914 --- /dev/null +++ b/rg/enable.go @@ -0,0 +1,37 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type EnableRequest struct { + RGID uint64 `url:"rgId"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq EnableRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) Enable(ctx context.Context, req EnableRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/rg/enable" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/rg/get.go b/rg/get.go new file mode 100644 index 0000000..f968cc3 --- /dev/null +++ b/rg/get.go @@ -0,0 +1,42 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + RGID uint64 `url:"rgId"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq GetRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*ResourceGroup, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/get" + rgRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + rg := &ResourceGroup{} + if err := json.Unmarshal(rgRaw, rg); err != nil { + return nil, err + } + + return rg, nil +} diff --git a/rg/list.go b/rg/list.go new file mode 100644 index 0000000..a4a83ec --- /dev/null +++ b/rg/list.go @@ -0,0 +1,30 @@ +package rg + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + IncludeDeleted bool `url:"includedeleted,omitempty"` + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (r RG) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (ResourceGroupList, error) { + url := "/cloudapi/rg/list" + rgListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + rgList := ResourceGroupList{} + if err := json.Unmarshal(rgListRaw, &rgList); err != nil { + return nil, err + } + + return rgList, nil +} diff --git a/rg/list_computes.go b/rg/list_computes.go new file mode 100644 index 0000000..61169ab --- /dev/null +++ b/rg/list_computes.go @@ -0,0 +1,42 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListComputesRequest struct { + RGID uint64 `url:"rgId"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq ListComputesRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) ListComputes(ctx context.Context, req ListComputesRequest, options ...opts.DecortOpts) (ComputeList, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/listComputes" + computeListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + computeList := ComputeList{} + if err := json.Unmarshal(computeListRaw, &computeList); err != nil { + return nil, err + } + + return computeList, nil +} diff --git a/rg/list_deleted.go b/rg/list_deleted.go new file mode 100644 index 0000000..7899123 --- /dev/null +++ b/rg/list_deleted.go @@ -0,0 +1,29 @@ +package rg + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListDeletedRequest struct { + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (r RG) ListDeleted(ctx context.Context, req ListDeletedRequest, options ...opts.DecortOpts) (ResourceGroupList, error) { + url := "/cloudapi/rg/listDeleted" + rgListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + rgList := ResourceGroupList{} + if err := json.Unmarshal(rgListRaw, &rgList); err != nil { + return nil, err + } + + return rgList, nil +} diff --git a/rg/list_lb.go b/rg/list_lb.go new file mode 100644 index 0000000..d1667d9 --- /dev/null +++ b/rg/list_lb.go @@ -0,0 +1,41 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListLBRequest struct { + RGID uint64 `url:"rgId"` +} + +func (rgrq ListLBRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) ListLB(ctx context.Context, req ListLBRequest, options ...opts.DecortOpts) (LBList, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/listLb" + lbListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + lbList := LBList{} + if err := json.Unmarshal(lbListRaw, &lbList); err != nil { + return nil, err + } + + return lbList, nil +} diff --git a/rg/list_pfw.go b/rg/list_pfw.go new file mode 100644 index 0000000..b820ffa --- /dev/null +++ b/rg/list_pfw.go @@ -0,0 +1,41 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListPFWRequest struct { + RGID uint64 `url:"rgId"` +} + +func (rgrq ListPFWRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) ListPFW(ctx context.Context, req ListPFWRequest, options ...opts.DecortOpts) (PortForwardList, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/listPFW" + pfwListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + pfwList := PortForwardList{} + if err := json.Unmarshal(pfwListRaw, &pfwList); err != nil { + return nil, err + } + + return pfwList, nil +} diff --git a/rg/list_vins.go b/rg/list_vins.go new file mode 100644 index 0000000..f629e9d --- /dev/null +++ b/rg/list_vins.go @@ -0,0 +1,42 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListVINSRequest struct { + RGID uint64 `url:"rgId"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq ListVINSRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) ListVINS(ctx context.Context, req ListVINSRequest, options ...opts.DecortOpts) (VINSList, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/listVins" + vinsListRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + vinsList := VINSList{} + if err := json.Unmarshal(vinsListRaw, &vinsList); err != nil { + return nil, err + } + + return vinsList, nil +} diff --git a/rg/models.go b/rg/models.go new file mode 100644 index 0000000..8cc77d0 --- /dev/null +++ b/rg/models.go @@ -0,0 +1,234 @@ +package rg + +type ResourceGroup struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + ACL []ACL `json:"acl"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DefNetID uint64 `json:"def_net_id"` + DefNetType string `json:"def_net_type"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Desc string `json:"desc"` + Dirty bool `url:"dirty"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + Milestones int `json:"milestones"` + Name string `json:"name"` + RegisterComputes bool `json:"registerComputes"` + ResourceLimits ResourceLimits `json:"resourceLimits"` + Secret string `json:"secret"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + VINS []uint64 `json:"vins"` + Computes []uint64 `json:"vms"` +} + +type ResourceGroupList []ResourceGroup + +type ACL struct { + Explicit bool `json:"explicit"` + GUID string `json:"guid"` + Right string `json:"right"` + Status string `json:"status"` + Type string `json:"type"` + UserGroupID string `json:"userGroupId"` +} + +type ResourceLimits struct { + CUC float64 `json:"CU_C"` + CUD float64 `json:"CU_D"` + CUI float64 `json:"CU_I"` + CUM float64 `json:"CU_M"` + CUNP float64 `json:"CU_NP"` + GPUUnits float64 `json:"gpu_units"` +} + +type AffinityGroupCompute struct { + ComputeID uint64 `json:"computeId"` + OtherNode []uint64 `json:"otherNode"` + OtherNodeIndirect []uint64 `json:"otherNodeIndirect"` + OtherNodeIndirectSoft []uint64 `json:"otherNodeIndirectSoft"` + OtherNodeSoft []uint64 `json:"otherNodeSoft"` + SameNode []uint64 `json:"sameNode"` + SameNodeSoft []uint64 `json:"sameNodeSoft"` +} + +type AffinityGroupComputeList []AffinityGroupCompute + +type Audit struct { + Call string `json:"call"` + ResponseTime float64 `json:"responsetime"` + StatusCode uint64 `json:"statuscode"` + Timestamp float64 `json:"timestamp"` + User string `json:"user"` +} + +type AuditList []Audit + +type Compute struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + AffinityLabel string `json:"affinityLabel"` + // TODO put actual type here + AffinityRules []any `json:"affinityRules"` + AffinityWeight uint64 `json:"affinityWeight"` + // TODO put actual type here + AntiAffinityRules []any `json:"antiAffinityRules"` + CPUs uint64 `json:"cpus"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + ID uint64 `json:"id"` + Name string `json:"name"` + RAM uint64 `json:"ram"` + Registered bool `json:"registered"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + TotalDisksSize uint64 `json:"totalDisksSize"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + UserManaged bool `json:"userManaged"` + VINSConnected uint64 `json:"vinsConnected"` +} + +type ComputeList []Compute + +type LoadBalancer struct { + HAMode bool `json:"HAmode"` + ACL interface{} `json:"acl"` + Backends []Backend `json:"backends"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + Description string `json:"desc"` + DPAPIUser string `json:"dpApiUser"` + ExtnetId uint64 `json:"extnetId"` + Frontends []Frontend `json:"frontends"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + ImageId uint64 `json:"imageId"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + PrimaryNode Node `json:"primaryNode"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + SecondaryNode Node `json:"secondaryNode"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` + VinsId uint64 `json:"vinsId"` +} + +type LoadBalancerDetailed struct { + DPAPIPassword string `json:"dpApiPassword"` + LoadBalancer +} + +type Backend struct { + Algorithm string `json:"algorithm"` + GUID string `json:"guid"` + Name string `json:"name"` + ServerDefaultSettings ServerSettings `json:"serverDefaultSettings"` + Servers []Server `json:"servers"` +} + +type LBList []LoadBalancerDetailed + +type ServerSettings struct { + Inter uint64 `json:"inter"` + GUID string `json:"guid"` + DownInter uint64 `json:"downinter"` + Rise uint `json:"rise"` + Fall uint `json:"fall"` + SlowStart uint64 `json:"slowstart"` + MaxConn uint `json:"maxconn"` + MaxQueue uint `json:"maxqueue"` + Weight uint `json:"weight"` +} + +type Server struct { + Address string `json:"address"` + Check string `json:"check"` + GUID string `json:"guid"` + Name string `json:"name"` + Port uint `json:"port"` + ServerSettings ServerSettings `json:"serverSettings"` +} + +type Node struct { + BackendIp string `json:"backendIp"` + ComputeId uint64 `json:"computeId"` + FrontendIp string `json:"frontendIp"` + GUID string `json:"guid"` + MGMTIp string `json:"mgmtIp"` + NetworkId uint64 `json:"networkId"` +} + +type Frontend struct { + Backend string `json:"backend"` + Bindings []Binding `json:"bindings"` + GUID string `json:"guid"` + Name string `json:"name"` +} + +type Binding struct { + Address string `json:"address"` + GUID string `json:"guid"` + Name string `json:"name"` + Port uint `json:"port"` +} + +type PortForward struct { + PublicPortEnd uint16 `json:"Public Port End"` + PublicPortStart uint16 `json:"Public Port Start"` + VMID uint64 `json:"VM ID"` + VMIP string `json:"VM IP"` + VMName string `json:"VM Name"` + VMPort uint16 `json:"VM Port"` + VINSID uint64 `json:"ViNS ID"` + VINSName string `json:"ViNS Name"` +} + +type PortForwardList []PortForward + +type VINS struct { + AccountID uint64 `json:"accountId"` + AccountName string `json:"accountName"` + Computes uint64 `json:"computes"` + CreatedBy string `json:"createdBy"` + CreatedTime uint64 `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime uint64 `json:"deletedTime"` + ExternalIP string `json:"externalIP"` + ID uint64 `json:"id"` + Name string `json:"name"` + Network string `json:"network"` + PriVNFDevID uint64 `json:"priVnfDevId"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime uint64 `json:"updatedTime"` +} + +type VINSList []VINS + +type ResourceUsage struct { + CPU uint64 `json:"cpu"` + DiskSize uint64 `json:"disksize"` + ExtIPs uint64 `json:"extips"` + ExtraTraffic uint64 `json:"exttraffic"` + GPU uint64 `json:"gpu"` + RAM uint64 `json:"ram"` +} diff --git a/rg/restore.go b/rg/restore.go new file mode 100644 index 0000000..8b2d947 --- /dev/null +++ b/rg/restore.go @@ -0,0 +1,37 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestoreRequest struct { + RGID uint64 `url:"rgId"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq RestoreRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) Restore(ctx context.Context, req RestoreRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/rg/restore" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/rg/rg.go b/rg/rg.go new file mode 100644 index 0000000..52ed4f1 --- /dev/null +++ b/rg/rg.go @@ -0,0 +1,15 @@ +package rg + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type RG struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *RG { + return &RG{ + client, + } +} diff --git a/rg/set_def_net.go b/rg/set_def_net.go new file mode 100644 index 0000000..75eaaa4 --- /dev/null +++ b/rg/set_def_net.go @@ -0,0 +1,44 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/internal/validators" + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SetDefNetRequest struct { + RGID uint64 `url:"rgId"` + NetType string `url:"netType"` + NetID uint64 `url:"netId"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq SetDefNetRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + if !validators.StringInSlice(rgrq.NetType, []string{"PUBLIC", "PRIVATE"}) { + return errors.New("field NetType can only be one of 'PUBLIC' or 'PRIVATE'") + } + + return nil +} + +func (r RG) SetDefNet(ctx context.Context, req SetDefNetRequest, options ...opts.DecortOpts) (uint64, error) { + if err := req.Validate(); err != nil { + return 0, err + } + + url := "/cloudapi/rg/setDefNet" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + return strconv.ParseUint(string(res), 10, 64) +} diff --git a/rg/update.go b/rg/update.go new file mode 100644 index 0000000..16b2dea --- /dev/null +++ b/rg/update.go @@ -0,0 +1,45 @@ +package rg + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UpdateRequest struct { + RGID uint64 `url:"rgId"` + Name string `url:"name,omitempty"` + Desc string `url:"desc,omitempty"` + MaxMemoryCapacity uint64 `url:"maxMemoryCapacity,omitempty"` + MaxVDiskCapacity uint64 `url:"maxVDiskCapacity,omitempty"` + MaxCPUCapacity uint64 `url:"maxCPUCapacity,omitempty"` + MaxNetworkPeerTransfer uint64 `url:"maxNetworkPeerTransfer,omitempty"` + MaxNumPublicIP uint64 `url:"maxNumPublicIP,omitempty"` + RegisterComputes bool `url:"registerComputes,omitempty"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq UpdateRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) Update(ctx context.Context, req UpdateRequest, options ...opts.DecortOpts) (bool, error) { + if err := req.Validate(); err != nil { + return false, err + } + + url := "/cloudapi/rg/update" + res, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + return strconv.ParseBool(string(res)) +} diff --git a/rg/usage.go b/rg/usage.go new file mode 100644 index 0000000..157802a --- /dev/null +++ b/rg/usage.go @@ -0,0 +1,42 @@ +package rg + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type UsageRequest struct { + RGID uint64 `url:"rgId"` + Reason string `url:"reason,omitempty"` +} + +func (rgrq UsageRequest) Validate() error { + if rgrq.RGID == 0 { + return errors.New("field RGID can not be empty or equal to 0") + } + + return nil +} + +func (r RG) Usage(ctx context.Context, req UpdateRequest, options ...opts.DecortOpts) (*ResourceUsage, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + url := "/cloudapi/rg/usage" + usageRaw, err := r.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + usage := &ResourceUsage{} + if err := json.Unmarshal(usageRaw, usage); err != nil { + return nil, err + } + + return usage, nil +} diff --git a/sizes.go b/sizes.go new file mode 100644 index 0000000..8511b91 --- /dev/null +++ b/sizes.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/sizes" +) + +func (dc *decortClient) Sizes() *sizes.Sizes { + return sizes.New(dc) +} diff --git a/sizes/list.go b/sizes/list.go new file mode 100644 index 0000000..d3dbea1 --- /dev/null +++ b/sizes/list.go @@ -0,0 +1,31 @@ +package sizes + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + CloudspaceID uint64 `url:"cloudspaceId,omitempty"` + Location string `url:"location,omitempty"` + Page uint64 `url:"page,omitempty"` + Size uint64 `url:"size,omitempty"` +} + +func (s Sizes) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (SizesList, error) { + url := "/cloudapi/sizes/list" + sizesListRaw, err := s.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + sizesList := SizesList{} + if err := json.Unmarshal(sizesListRaw, &sizesList); err != nil { + return nil, err + } + + return sizesList, nil +} diff --git a/sizes/models.go b/sizes/models.go new file mode 100644 index 0000000..b787111 --- /dev/null +++ b/sizes/models.go @@ -0,0 +1,12 @@ +package sizes + +type Size struct { + Description string `json:"desc"` + Disks []uint64 `json:"disks"` + ID uint64 `json:"id"` + Memory uint64 `json:"memory"` + Name string `json:"name"` + VCPUs uint64 `json:"vcpus"` +} + +type SizesList []Size diff --git a/sizes/sizes.go b/sizes/sizes.go new file mode 100644 index 0000000..d468422 --- /dev/null +++ b/sizes/sizes.go @@ -0,0 +1,15 @@ +package sizes + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Sizes struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Sizes { + return &Sizes{ + client, + } +} diff --git a/tasks.go b/tasks.go new file mode 100644 index 0000000..d0a998a --- /dev/null +++ b/tasks.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/tasks" +) + +func (dc *decortClient) Tasks() *tasks.Tasks { + return tasks.New(dc) +} diff --git a/tasks/get.go b/tasks/get.go new file mode 100644 index 0000000..10ed453 --- /dev/null +++ b/tasks/get.go @@ -0,0 +1,54 @@ +package tasks + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + AuditId string `url:"auditId"` +} + +func (trq GetRequest) Validate() error { + if trq.AuditId == "" { + return errors.New("validation-error: field AuditId can not be empty") + } + + return nil +} + +func (t Tasks) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*AsyncTask, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/tasks/get" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + taskRaw, err := t.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + task := &AsyncTask{} + err = json.Unmarshal(taskRaw, task) + if err != nil { + return nil, err + } + + return task, nil + +} diff --git a/tasks/list.go b/tasks/list.go new file mode 100644 index 0000000..4c89c66 --- /dev/null +++ b/tasks/list.go @@ -0,0 +1,41 @@ +package tasks + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (t Tasks) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (TasksList, error) { + url := "/tasks/list" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + taskListRaw, err := t.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + taskList := TasksList{} + err = json.Unmarshal(taskListRaw, &taskList) + if err != nil { + return nil, err + } + + return taskList, nil + +} diff --git a/tasks/models.go b/tasks/models.go new file mode 100644 index 0000000..acc4ee7 --- /dev/null +++ b/tasks/models.go @@ -0,0 +1,51 @@ +package tasks + +import ( + "encoding/json" + "fmt" + "strconv" +) + +type TaskResult int + +func (r *TaskResult) UnmarshalJSON(b []byte) error { + if b[0] == '"' { + b := b[1 : len(b)-1] + if len(b) == 0 { + *r = 0 + return nil + } + n, err := strconv.Atoi(string(b)) + if err != nil { + return err + } + *r = TaskResult(n) + } else if b[0] == '[' { + res := []interface{}{} + if err := json.Unmarshal(b, &res); err != nil { + return err + } + if n, ok := res[0].(float64); ok { + *r = TaskResult(n) + } else { + return fmt.Errorf("could not unmarshal %v into int", res[0]) + } + } + + return nil +} + +//AsyncTask represents a long task completion status +type AsyncTask struct { + AuditID string `json:"auditId"` + Completed bool `json:"completed"` + Error string `json:"error"` + Log []string `json:"log"` + Result TaskResult `json:"result"` + Stage string `json:"stage"` + Status string `json:"status"` + UpdateTime uint64 `json:"updateTime"` + UpdatedTime uint64 `json:"updatedTime"` +} + +type TasksList []AsyncTask diff --git a/tasks/tasks.go b/tasks/tasks.go new file mode 100644 index 0000000..e901ece --- /dev/null +++ b/tasks/tasks.go @@ -0,0 +1,15 @@ +package tasks + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Tasks struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Tasks { + return &Tasks{ + client, + } +} diff --git a/transport.go b/transport.go new file mode 100644 index 0000000..5186788 --- /dev/null +++ b/transport.go @@ -0,0 +1,65 @@ +package client + +import ( + "errors" + "fmt" + "io/ioutil" + "net/http" + "strings" + "time" +) + +type transport struct { + base http.RoundTripper + retries uint64 + clientId string + clientSecret string + token string + ssoUrl string + expiryTime time.Time +} + +func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { + if t.token == "" || time.Now().After(t.expiryTime) { + body := fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s&response_type=id_token", t.clientId, t.clientSecret) + bodyReader := strings.NewReader(body) + + req, _ := http.NewRequest("POST", t.ssoUrl+"/v1/oauth/access_token", bodyReader) + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + resp, err := t.base.RoundTrip(req) + if err != nil { + return nil, fmt.Errorf("cannot get token: %v", err) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("cannot get token: %v", err) + } + + tokenBytes, _ := ioutil.ReadAll(resp.Body) + resp.Body.Close() + token := string(tokenBytes) + + t.token = token + t.expiryTime = time.Now().AddDate(0, 0, 1) + } + + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add("Authorization", "bearer "+t.token) + req.Header.Set("Accept", "application/json") + + for i := uint64(0); i < t.retries; i++ { + resp, err := t.base.RoundTrip(req) + if err == nil { + if resp.StatusCode == 200 { + return resp, nil + } + respBytes, _ := ioutil.ReadAll(resp.Body) + err = fmt.Errorf("%s", respBytes) + resp.Body.Close() + } + fmt.Println(err) + time.Sleep(time.Second * 5) + } + return nil, errors.New("number of retries exceeded") +} diff --git a/typed/typed.go b/typed/typed.go new file mode 100644 index 0000000..06a4a6a --- /dev/null +++ b/typed/typed.go @@ -0,0 +1,6 @@ +package typed + +const TypeAdmin = "admin" +const ValueAdmin = "cloudbroker" +const POST = "POST" +const GET = "GET" diff --git a/vins.go b/vins.go new file mode 100644 index 0000000..1218406 --- /dev/null +++ b/vins.go @@ -0,0 +1,9 @@ +package client + +import ( + "github.com/rudecs/decort-sdk/vins" +) + +func (dc *decortClient) Vins() *vins.Vins { + return vins.New(dc) +} diff --git a/vins/audits.go b/vins/audits.go new file mode 100644 index 0000000..58e2b32 --- /dev/null +++ b/vins/audits.go @@ -0,0 +1,54 @@ +package vins + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type AuditsRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq AuditsRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) Audits(ctx context.Context, req AuditsRequest, options ...opts.DecortOpts) (VinsAuditsList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/vins/audits" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + auditsRaw, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + audits := VinsAuditsList{} + + err = json.Unmarshal([]byte(auditsRaw), &audits) + if err != nil { + return nil, err + } + + return audits, nil +} diff --git a/vins/create_in_account.go b/vins/create_in_account.go new file mode 100644 index 0000000..27521a9 --- /dev/null +++ b/vins/create_in_account.go @@ -0,0 +1,61 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateInAccountRequest struct { + Name string `url:"name"` + AccountId uint64 `url:"accountId"` + GID uint64 `url:"gid,omitempty"` + IPCidr string `url:"ipcidr,omitempty"` + Description string `url:"desc,omitempty"` + PreReservationsNum uint `url:"preReservationsNum,omitempty"` +} + +func (vrq CreateInAccountRequest) Validate() error { + if vrq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + if vrq.AccountId == 0 { + return errors.New("validation-error: field AccountId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) CreateInAccount(ctx context.Context, req CreateInAccountRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/vins/createInAccount" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + + return result, nil +} diff --git a/vins/create_in_rg.go b/vins/create_in_rg.go new file mode 100644 index 0000000..2fcc743 --- /dev/null +++ b/vins/create_in_rg.go @@ -0,0 +1,62 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type CreateInRGRequest struct { + Name string `url:"name"` + RGID uint64 `url:"rgId"` + IPCidr string `url:"ipcidr,omitempty"` + ExtNetId uint64 `url:"extNetId,omitempty"` + ExtIP string `url:"extIp,omitempty"` + Description string `url:"desc,omitempty"` + PreReservationsNum uint `url:"preReservationsNum,omitempty"` +} + +func (vrq CreateInRGRequest) Validate() error { + if vrq.Name == "" { + return errors.New("validation-error: field Name can not be empty") + } + + if vrq.RGID == 0 { + return errors.New("validation-error: field RGID can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) CreateInRG(ctx context.Context, req CreateInRGRequest, options ...opts.DecortOpts) (uint64, error) { + err := req.Validate() + if err != nil { + return 0, err + } + + url := "/vins/createInRG" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return 0, err + } + + result, err := strconv.ParseUint(string(res), 10, 64) + if err != nil { + return 0, err + } + + return result, nil +} diff --git a/vins/delete.go b/vins/delete.go new file mode 100644 index 0000000..1722301 --- /dev/null +++ b/vins/delete.go @@ -0,0 +1,54 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DeleteRequest struct { + VinsId uint64 `url:"vinsId"` + Force bool `url:"force"` + Permanently bool `url:"permanently"` +} + +func (vrq DeleteRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) Delete(ctx context.Context, req DeleteRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/delete" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/vins/disable_enable.go b/vins/disable_enable.go new file mode 100644 index 0000000..fda9f7a --- /dev/null +++ b/vins/disable_enable.go @@ -0,0 +1,84 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type DisableEnableRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq DisableEnableRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) Disable(ctx context.Context, req DisableEnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/disable" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil + +} + +func (v Vins) Enable(ctx context.Context, req DisableEnableRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/enable" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil + +} diff --git a/vins/extnet_connect.go b/vins/extnet_connect.go new file mode 100644 index 0000000..0540aff --- /dev/null +++ b/vins/extnet_connect.go @@ -0,0 +1,54 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ExtNetConnectRequest struct { + VinsId uint64 `url:"vinsId"` + NetId uint64 `url:"netId"` + IP string `url:"ip"` +} + +func (vrq ExtNetConnectRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) ExtNetConnect(ctx context.Context, req ExtNetConnectRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/extNetConnect" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/vins/extnet_disconnect.go b/vins/extnet_disconnect.go new file mode 100644 index 0000000..73f3c7d --- /dev/null +++ b/vins/extnet_disconnect.go @@ -0,0 +1,52 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ExtNetDisconnectRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq ExtNetDisconnectRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) ExtNetDisconnect(ctx context.Context, req ExtNetDisconnectRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/extNetDisconnect" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil +} diff --git a/vins/extnet_list.go b/vins/extnet_list.go new file mode 100644 index 0000000..362bd75 --- /dev/null +++ b/vins/extnet_list.go @@ -0,0 +1,49 @@ +package vins + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ExtNetListRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq ExtNetListRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) ExtNetList(ctx context.Context, req ExtNetListRequest, options ...opts.DecortOpts) (ExtnetList, error) { + url := "/vins/extNetList" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + extnetListRaw, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + extnetList := ExtnetList{} + err = json.Unmarshal(extnetListRaw, &extnetList) + if err != nil { + return nil, err + } + + return extnetList, nil + +} diff --git a/vins/get.go b/vins/get.go new file mode 100644 index 0000000..89296c9 --- /dev/null +++ b/vins/get.go @@ -0,0 +1,55 @@ +package vins + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type GetRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq GetRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) Get(ctx context.Context, req GetRequest, options ...opts.DecortOpts) (*VinsDetailed, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/vins/get" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + vins := &VinsDetailed{} + + err = json.Unmarshal(res, vins) + if err != nil { + return nil, err + } + + return vins, nil + +} diff --git a/vins/ip_list.go b/vins/ip_list.go new file mode 100644 index 0000000..671804a --- /dev/null +++ b/vins/ip_list.go @@ -0,0 +1,54 @@ +package vins + +import ( + "context" + "encoding/json" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type IPListRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq IPListRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) IPList(ctx context.Context, req IPListRequest, options ...opts.DecortOpts) (IPList, error) { + err := req.Validate() + if err != nil { + return nil, err + } + + url := "/vins/ipList" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + ipListRaw, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + ipList := IPList{} + err = json.Unmarshal(ipListRaw, &ipList) + if err != nil { + return nil, err + } + + return ipList, nil + +} diff --git a/vins/ip_release.go b/vins/ip_release.go new file mode 100644 index 0000000..624fa93 --- /dev/null +++ b/vins/ip_release.go @@ -0,0 +1,55 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type IPReleaseRequest struct { + VinsId uint64 `url:"vinsId"` + IPAddr string `url:"ipAddr,omitempty"` + MAC string `url:"mac,omitempty"` +} + +func (vrq IPReleaseRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) IPRelese(ctx context.Context, req IPReleaseRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/ipRelease" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil + +} diff --git a/vins/ip_reserve.go b/vins/ip_reserve.go new file mode 100644 index 0000000..8fec954 --- /dev/null +++ b/vins/ip_reserve.go @@ -0,0 +1,55 @@ +package vins + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type IPReserveRequest struct { + VinsId uint64 `url:"vinsId"` + Type string `url:"type"` + IPAddr string `url:"ipAddr,omitempty"` + MAC string `url:"mac,omitempty"` + ComputeId uint64 `url:"computeId,omitempty"` +} + +func (vrq IPReserveRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + if vrq.Type == "" { + return errors.New("validation-error: field Type can not be empty") + } + + return nil +} + +func (v Vins) IPReserve(ctx context.Context, req IPReserveRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/vins/ipReserve" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil + +} diff --git a/vins/list.go b/vins/list.go new file mode 100644 index 0000000..82f0d47 --- /dev/null +++ b/vins/list.go @@ -0,0 +1,42 @@ +package vins + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListRequest struct { + IncludeDeleted bool `url:"includeDeleted"` + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (v Vins) List(ctx context.Context, req ListRequest, options ...opts.DecortOpts) (VinsList, error) { + url := "/vins/list" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + vinsListRaw, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + vinsList := VinsList{} + err = json.Unmarshal(vinsListRaw, &vinsList) + if err != nil { + return nil, err + } + + return vinsList, nil + +} diff --git a/vins/list_deleted.go b/vins/list_deleted.go new file mode 100644 index 0000000..e3e52c5 --- /dev/null +++ b/vins/list_deleted.go @@ -0,0 +1,41 @@ +package vins + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type ListDeletedRequest struct { + Page uint64 `url:"page"` + Size uint64 `url:"size"` +} + +func (v Vins) ListDeleted(ctx context.Context, req ListDeletedRequest, options ...opts.DecortOpts) (VinsList, error) { + url := "/vins/listDeleted" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + vinsListRaw, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + vinsList := VinsList{} + err = json.Unmarshal(vinsListRaw, &vinsList) + if err != nil { + return nil, err + } + + return vinsList, nil + +} diff --git a/vins/models.go b/vins/models.go new file mode 100644 index 0000000..f31dd99 --- /dev/null +++ b/vins/models.go @@ -0,0 +1,271 @@ +package vins + +type VinsRecord struct { + AccountId int `json:"accountId"` + AccountName string `json:"accountName"` + CreatedBy string `json:"createdBy"` + CreatedTime int `json:"createdTime"` + DeletedBy string `json:"deletedBy"` + DeletedTime int `json:"deletedTime"` + ExternalIP string `json:"externalIP"` + ID int `json:"id"` + Name string `json:"name"` + Network string `json:"network"` + RGID int `json:"rgId"` + RGName string `json:"rgName"` + Status string `json:"status"` + UpdatedBy string `json:"updatedBy"` + UpdatedTime int `json:"updatedTime"` + VXLanID int `json:"vxlanId"` +} + +type VinsList []VinsRecord + +type VinsAudits struct { + Call string `json:"call"` + ResponseTime float64 `json:"responsetime"` + StatusCode int `json:"statuscode"` + Timestamp float64 `json:"timestamp"` + User string `json:"user"` +} + +type VinsAuditsList []VinsAudits + +type VinsExtnet struct { + DefaultGW string `json:"default_gw"` + ExtNetID uint64 `json:"ext_net_id"` + IP string `json:"ip"` + PrefixLen uint `json:"prefixlen"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` +} + +type ExtnetList []VinsExtnet + +type IP struct { + ClientType string `json:"clientType"` + DomainName string `json:"domainname"` + HostName string `json:"hostname"` + IP string `json:"ip"` + MAC string `json:"mac"` + Type string `json:"type"` + VMId uint64 `json:"vmId"` +} + +type IPList []IP + +type VNFDev struct { + CKey string `json:"_ckey"` + AccountId uint64 `json:"accountId"` + Capabilities []string `json:"capabilities"` + Config VNFConfig `json:"config"` + ConfigSaved bool `json:"configSaved"` + CustomPreConfig bool `json:"customPrecfg"` + Description string `json:"desc"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + Interfaces VNFInterfaceList `json:"interfaces"` + LockStatus string `json:"lockStatus"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` + Vins []uint64 `json:"vins"` +} + +type VNFConfig struct { + MGMT VNFConfigMGMT `json:"mgmt"` + Resources VNFConfigResources `json:"resources"` +} + +type VNFConfigMGMT struct { + IPAddr string `json:"ipaddr"` + Password string `json:"password"` + SSHKey string `json:"sshkey"` + User string `json:"user"` +} + +type VNFConfigResources struct { + CPU uint64 `json:"cpu"` + RAM uint64 `json:"ram"` + StackId uint64 `json:"stackId"` + UUID string `json:"uuid"` +} + +type VNFInterface struct { + ConnId uint64 `json:"connId"` + ConnType string `json:"connType"` + DefGW string `json:"defGw"` + FlipGroupId uint64 `json:"flipgroupId"` + GUID string `json:"guid"` + IPAddress string `json:"ipAddress"` + ListenSSH bool `json:"listenSsh"` + MAC string `json:"mac"` + Name string `json:"name"` + NetId uint64 `json:"netId"` + NetMask uint64 `json:"netMask"` + NetType string `json:"netType"` + PCISlot uint64 `json:"pciSlot"` + QOS QOS `json:"qos"` + Target string `json:"target"` + Type string `json:"type"` + VNFS []uint64 `json:"vnfs"` +} + +type QOS struct { + ERate uint64 `json:"eRate"` + GUID string `json:"guid"` + InBurst uint64 `json:"inBurst"` + InRate uint64 `json:"inRate"` +} + +type VNFInterfaceList []VNFInterface + +type VINSCompute struct { + ID uint64 `json:"id"` + Name string `json:"name"` +} + +type VINSComputeList []VINSCompute + +type VNFS struct { + DHCP DHCP `json:"DHCP"` + GW GW `json:"GW"` + NAT NAT `json:"NAT"` +} + +type NAT struct { + CKey string `json:"_ckey"` + AccountId uint64 `json:"accountId"` + CreatedTime uint64 `json:"createdTime"` + Devices Devices `json:"devices"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + Milestones uint64 `json:"milestones"` + OwnerId uint64 `json:"ownerId"` + OwnerType string `json:"ownerType"` + PureVirtual bool `json:"pureVirtual"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` +} + +type NATConfig struct { + NetMask uint64 `json:"netmask"` + Network string `json:"network"` + Rules []interface{} `json:"rules"` +} + +type GW struct { + CKey string `json:"_ckey"` + AccountId uint64 `json:"accountId"` + Config GWConfig `json:"config"` + CreatedTime uint64 `json:"createdTime"` + Devices Devices `json:"devices"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + Milestones uint64 `json:"milestones"` + OwnerId uint64 `json:"ownerId"` + OwnerType string `json:"ownerType"` + PureVirtual bool `json:"pureVirtual"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` +} + +type GWConfig struct { + DefaultGW string `json:"default_gw"` + ExtNetId uint64 `json:"ext_net_id"` + ExtNetIp string `json:"ext_net_ip"` + ExtNetMask uint64 `json:"ext_netmask"` + QOS QOS `json:"qos"` +} + +type Devices struct { + Primary DevicePrimary `json:"primary"` +} + +type DevicePrimary struct { + DevId uint64 `json:"devId"` + IFace01 string `json:"iface01"` + IFace02 string `json:"iface02"` +} + +type DHCP struct { + CKey string `json:"_ckey"` + AccountId uint64 `json:"accountId"` + Config DHCPConfig `json:"config"` + CreatedTime uint64 `json:"createdTime"` + Devices Devices `json:"devices"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + Milestones uint64 `json:"milestones"` + OwnerId uint64 `json:"ownerId"` + OwnerType string `json:"ownerType"` + PureVirtual bool `json:"pureVirtual"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` +} + +type DHCPConfig struct { + DefaultGW string `json:"default_gw"` + DNS []string `json:"dns"` + IPEnd string `json:"ip_end"` + IPStart string `json:"ip_start"` + Lease uint64 `json:"lease"` + Netmask uint64 `json:"netmask"` + Network string `json:"network"` + Reservations ReservationList `json:"reservations"` +} + +type VinsDetailed struct { + VNFDev VNFDev `json:"VNFDev"` + CKey string `json:"_ckey"` + AccountId uint64 `json:"accountId"` + AccountName string `json:"accountName"` + Computes VINSComputeList `json:"computes"` + DefaultGW string `json:"defaultGW"` + DefaultQOS QOS `json:"defaultQos"` + Description string `json:"desc"` + GID uint64 `json:"gid"` + GUID uint64 `json:"guid"` + ID uint64 `json:"id"` + LockStatus string `json:"lockStatus"` + ManagerId uint64 `json:"managerId"` + ManagerType string `json:"managerType"` + Milestones uint64 `json:"milestones"` + Name string `json:"name"` + NetMask uint64 `json:"netMask"` + Network string `json:"network"` + PreReservaionsNum uint64 `json:"preReservationsNum"` + Redundant bool `json:"redundant"` + RGID uint64 `json:"rgId"` + RGName string `json:"rgName"` + SecVNFDevId uint64 `json:"secVnfDevId"` + Status string `json:"status"` + UserManaged bool `json:"userManaged"` + VNFS VNFS `json:"vnfs"` + VXLanId uint64 `json:"vxlanId"` +} + +type Reservation struct { + ClientType string `json:"clientType"` + Description string `json:"desc"` + DomainName string `json:"domainname"` + HostName string `json:"hostname"` + IP string `json:"ip"` + MAC string `json:"mac"` + Type string `json:"type"` + VMID int `json:"vmId"` +} + +type ReservationList []Reservation diff --git a/vins/nat_rule_add.go b/vins/nat_rule_add.go new file mode 100644 index 0000000..f731e6a --- /dev/null +++ b/vins/nat_rule_add.go @@ -0,0 +1,70 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type NatRuleAddRequest struct { + VinsId uint64 `url:"vinsId"` + IntIP string `url:"intIp "` + IntPort uint `url:"intPort"` + ExtPortStart uint `url:"extPortStart"` + ExtPortEnd uint `url:"extPortEnd,omitempty"` + Proto string `url:"proto"` +} + +func (vrq NatRuleAddRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + if vrq.IntIP == "" { + return errors.New("validation-error: field IntIP can not be empty") + } + + if vrq.IntPort == 0 { + return errors.New("validation-error: field IntPort can not be empty or equal to 0") + } + + if vrq.ExtPortStart == 0 { + return errors.New("validation-error: field ExtPortStart can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) NatRuleAdd(ctx context.Context, req NatRuleAddRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/natRuleAdd" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil + +} diff --git a/vins/nat_rule_del.go b/vins/nat_rule_del.go new file mode 100644 index 0000000..56b8bc6 --- /dev/null +++ b/vins/nat_rule_del.go @@ -0,0 +1,58 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type NatRuleDelRequest struct { + VinsId uint64 `url:"vinsId"` + RuleId uint64 `url:"ruleId"` +} + +func (vrq NatRuleDelRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + if vrq.RuleId == 0 { + return errors.New("validation-error: field RuleId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) NatRuleDel(ctx context.Context, req NatRuleDelRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/natRuleDel" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil + +} diff --git a/vins/nat_rule_list.go b/vins/nat_rule_list.go new file mode 100644 index 0000000..53a6c1f --- /dev/null +++ b/vins/nat_rule_list.go @@ -0,0 +1,47 @@ +package vins + +import ( + "context" + "errors" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type NatRuleListRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq NatRuleListRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) NatRuleList(ctx context.Context, req NatRuleListRequest, options ...opts.DecortOpts) (string, error) { + err := req.Validate() + if err != nil { + return "", err + } + + url := "/vins/natRuleList" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return "", err + } + + return string(res), nil + +} diff --git a/vins/restore.go b/vins/restore.go new file mode 100644 index 0000000..99cb8e0 --- /dev/null +++ b/vins/restore.go @@ -0,0 +1,53 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type RestoreRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq RestoreRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) Restore(ctx context.Context, req RestoreRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/restore" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil + +} diff --git a/vins/search.go b/vins/search.go new file mode 100644 index 0000000..2695710 --- /dev/null +++ b/vins/search.go @@ -0,0 +1,43 @@ +package vins + +import ( + "context" + "encoding/json" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type SearchRequest struct { + AccountId uint64 `url:"accountId,omitempty"` + RGID uint64 `url:"rgId,omitempty"` + Name string `url:"name,omitempty"` + ShowAll bool `url:"show_all,omitempty"` +} + +func (v Vins) Search(ctx context.Context, req SearchRequest, options ...opts.DecortOpts) (VinsList, error) { + url := "/vins/search" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + vinsListRaw, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return nil, err + } + + vinsList := VinsList{} + err = json.Unmarshal(vinsListRaw, &vinsList) + if err != nil { + return nil, err + } + + return vinsList, nil + +} diff --git a/vins/vins.go b/vins/vins.go new file mode 100644 index 0000000..8a639dc --- /dev/null +++ b/vins/vins.go @@ -0,0 +1,15 @@ +package vins + +import ( + "github.com/rudecs/decort-sdk/interfaces" +) + +type Vins struct { + client interfaces.Caller +} + +func New(client interfaces.Caller) *Vins { + return &Vins{ + client, + } +} diff --git a/vins/vnfdev_redeploy.go b/vins/vnfdev_redeploy.go new file mode 100644 index 0000000..518d027 --- /dev/null +++ b/vins/vnfdev_redeploy.go @@ -0,0 +1,53 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type VnfdevRedeployRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq VnfdevRedeployRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) VnfdevRedeploy(ctx context.Context, req VnfdevRedeployRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/vnfdevRedeploy" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil + +} diff --git a/vins/vnfdev_restart.go b/vins/vnfdev_restart.go new file mode 100644 index 0000000..9104ca8 --- /dev/null +++ b/vins/vnfdev_restart.go @@ -0,0 +1,53 @@ +package vins + +import ( + "context" + "errors" + "strconv" + + "github.com/rudecs/decort-sdk/opts" + "github.com/rudecs/decort-sdk/typed" +) + +type VnfdevRestartRequest struct { + VinsId uint64 `url:"vinsId"` +} + +func (vrq VnfdevRestartRequest) Validate() error { + if vrq.VinsId == 0 { + return errors.New("validation-error: field VinsId can not be empty or equal to 0") + } + + return nil +} + +func (v Vins) VnfdevRestart(ctx context.Context, req VnfdevRestartRequest, options ...opts.DecortOpts) (bool, error) { + err := req.Validate() + if err != nil { + return false, err + } + + url := "/vins/vnfdevRestart" + prefix := "/cloudapi" + + option := opts.New(options) + + if option != nil { + if option.IsAdmin { + prefix = "/" + option.AdminValue + } + } + url = prefix + url + res, err := v.client.DecortApiCall(ctx, typed.POST, url, req) + if err != nil { + return false, err + } + + result, err := strconv.ParseBool(string(res)) + if err != nil { + return false, nil + } + + return result, nil + +}