Skip to content
Snippets Groups Projects
Commit 5e6d93a6 authored by Florent Gluck's avatar Florent Gluck
Browse files

- REST API doc is now up-to-date

- VM routes and template routes now behave similarily without any exception
parent d765b6e6
Branches
No related tags found
No related merge requests found
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
| `/users/{email}/resetpwd` | reset a user's pwd | PUT | - | `USER_RESETPWD` | common.params.UserSetPwd | | `/users/{email}/resetpwd` | reset a user's pwd | PUT | - | `USER_RESETPWD` | common.params.UserSetPwd |
| `/users/pwd` | set current user's pwd | PUT | common.params.UserSetPwd | - | - | | `/users/pwd` | set current user's pwd | PUT | common.params.UserSetPwd | - | - |
| `/users` | list users | GET | - | `USER_LIST` | []common.params.UserWithoutPwd | | `/users` | list users | GET | - | `USER_LIST` | []common.params.UserWithoutPwd |
| `/users/whoami` | list current user | GET | - | | common.params.UserWithoutPwd | | `/users/whoami` | list current user | GET | - | - | common.params.UserWithoutPwd |
- Open question: shall we forbid the deletion of a user if they still own templates or VMs? - Open question: shall we forbid the deletion of a user if they still own templates or VMs?
...@@ -27,45 +27,50 @@ ...@@ -27,45 +27,50 @@
| Route | Description | Method | Input | Req. user cap. | Op. | Req. VM access cap. | Output | | Route | Description | Method | Input | Req. user cap. | Op. | Req. VM access cap. | Output |
|--- |--- |--- |--- |--- |--- |--- |--- | |--- |--- |--- |--- |--- |--- |--- |--- |
| `/vms` | returns VMs that can be listed | GET | | `VM_LIST_ANY` | OR | `VM_LIST` | | | `/vms` | returns VMs that can be listed | GET | - | `VM_LIST_ANY` | OR | `VM_LIST` | []common.vm.VMNetworkSerialized |
| `/vms/{id}` | returns the specified VM | GET | | `VM_LIST_ANY` | OR | `VM_LIST` | | | `/vms/{id}` | returns the specified VM | GET | - | `VM_LIST_ANY` | OR | `VM_LIST` | common.vm.VMNetworkSerialized |
| `/vms/start` | returns VMs that can be started | GET | | `VM_START_ANY` | OR | `VM_START` | | | `/vms/start` | returns VM creds info for VMs that can be started | GET | - | `VM_START_ANY` | OR | `VM_START` | []common.vm.VMCredentialsSerialized |
| `/vms/attach` | returns VM creds info for VMs that can be attached to | GET | | `VM_ATTACH_ANY` | OR | `VM_ATTACH` | | | `/vms/attach` | returns VM creds info for VMs that can be attached to | GET | - | `VM_ATTACH_ANY` | OR | `VM_ATTACH` | []common.vm.VMCredentialsSerialized |
| `/vms/{id}/attach` | returns VM creds info for the specified VM | GET | | `VM_ATTACH_ANY` | OR | `VM_ATTACH` | | | `/vms/{id}/attach` | returns VM creds info for the specified VM | GET | - | `VM_ATTACH_ANY` | OR | `VM_ATTACH` | common.vm.VMCredentialsSerialized |
| `/vms/stop` | returns VMs that can be killed/shutdown | GET | | `VM_STOP_ANY` | OR | `VM_STOP` | | | `/vms/stop` | returns VM creds info for VMs that can be killed/shutdown | GET | - | `VM_STOP_ANY` | OR | `VM_STOP` | []common.vm.VMCredentialsSerialized |
| `/vms/reboot` | returns VMs that can be rebooted | GET | | `VM_REBOOT_ANY` | OR | `VM_REBOOT` | | | `/vms/reboot` | returns VM creds info for VMs that can be rebooted | GET | - | `VM_REBOOT_ANY` | OR | `VM_REBOOT` | []common.vm.VMCredentialsSerialized |
| `/vms/edit` | returns VMs that can be edited | GET | | `VM_EDIT_ANY` | OR | `VM_EDIT` | | | `/vms/edit` | returns VM creds info for VMs that can be edited | GET | - | `VM_EDIT_ANY` | OR | `VM_EDIT` | []common.vm.VMCredentialsSerialized |
| `/vms/editaccess` | returns VMs that can have their access changed | GET | | `VM_SET_ACCESS` | AND | `VM_SET_ACCESS` | | | `/vms/editaccess` | returns VM creds info for VMs that can have their access changed | GET | - | `VM_SET_ACCESS` | AND | `VM_SET_ACCESS` | []common.vm.VMCredentialsSerialized |
| `/vms/del` | returns VMs that can be deleted | GET | | `VM_DESTROY_ANY` | OR | `VM_DESTROY` | | | `/vms/del` | returns VM creds info for VMs that can be deleted | GET | - | `VM_DESTROY_ANY` | OR | `VM_DESTROY` | []common.vm.VMCredentialsSerialized |
| `/vms/exportdir` | returns VMs that can have a dir downloaded | GET | | `VM_READFS_ANY` | OR | `VM_READFS` | | | `/vms/exportdir` | returns VM creds info for VMs that can have a dir downloaded | GET | - | `VM_READFS_ANY` | OR | `VM_READFS` | []common.vm.VMCredentialsSerialized |
| `/vms/importfiles` | returns VMs allowing files upload | GET | | `VM_WRITEFS_ANY` | OR | `VM_WRITEFS` | | | `/vms/importfiles` | returns VM creds info for VMs allowing files upload | GET | - | `VM_WRITEFS_ANY` | OR | `VM_WRITEFS` | []common.vm.VMCredentialsSerialized |
| Route | Description | Method | Input | Req. user cap. | Op. | Req. VM access cap. | Output | | Route | Description | Method | Input | Req. user cap. | Op. | Req. VM access cap. | Output |
|--- |--- |--- |--- |--- |--- |--- |--- | |--- |--- |--- |--- |--- |--- |--- |--- |
| `/vms` | create a VM | POST | name,cpus,ram,nic,usb,template | `VM_CREATE` | | | | | `/vms` | create a VM | POST | commmon.params.VMCreate | `VM_CREATE` | - | - | common.vm.VMNetworkSerialized |
| `/vms/{id}` | delete a VM | DELETE | | `VM_DESTROY_ANY` | OR | `VM_DESTROY` | | | `/vms/{id}` | delete a VM | DELETE | - | `VM_DESTROY_ANY` | OR | `VM_DESTROY` | - |
| `/vms/{id}` | edit a VM | PUT | name,cpus,ram,nic,usb | `VM_EDIT_ANY` | OR | `VM_EDIT` | | | `/vms/{id}` | edit a VM | PUT | common.params.VMEdit | `VM_EDIT_ANY` | OR | `VM_EDIT` | common.vm.VMNetworkSerialized |
| `/vms/{id}/start` | start a VM | PUT | | `VM_START_ANY` | OR | `VM_START` | | | `/vms/{id}/start` | start a VM | PUT | - | `VM_START_ANY` | OR | `VM_START` | - |
| `/vms/{id}/startwithcreds` | start a VM with credentials | PUT | port,pwd | `VM_START_ANY` | OR | `VM_START` | | | `/vms/{id}/startwithcreds` | start a VM with credentials | PUT | common.params.VMStartWithCreds | `VM_START_ANY` | OR | `VM_START` | - |
| `/vms/{id}/stop` | kill a VM | PUT | | `VM_STOP_ANY` | OR | `VM_STOP` | | | `/vms/{id}/stop` | kill a VM | PUT | - | `VM_STOP_ANY` | OR | `VM_STOP` | - |
| `/vms/{id}/reboot` | reboot a VM | PUT | | `VM_REBOOT_ANY` | OR | `VM_REBOOT` | | | `/vms/{id}/reboot` | reboot a VM | PUT | - | `VM_REBOOT_ANY` | OR | `VM_REBOOT` | - |
| `/vms/{id}/shutdown` | gracefully shutdown a VM | PUT | | `VM_STOP_ANY` | OR | `VM_STOP` | | | `/vms/{id}/shutdown` | gracefully shutdown a VM | PUT | - | `VM_STOP_ANY` | OR | `VM_STOP` | - |
| `/vms/{id}/access/{email}` | set VM access for a user | PUT | caps | `VM_SET_ACCESS` | AND | `VM_SET_ACCESS` | | | `/vms/{id}/access/{email}` | set VM access for a user | PUT | common.params.VMAddAccess | `VM_SET_ACCESS` | AND | `VM_SET_ACCESS` | - |
| `/vms/{id}/access/{email}` | del VM access for a user | DELETE | | `VM_SET_ACCESS` | AND | `VM_SET_ACCESS` | | | `/vms/{id}/access/{email}` | del VM access for a user | DELETE | - | `VM_SET_ACCESS` | AND | `VM_SET_ACCESS` | - |
| `/vms/{id}/exportdir` | download a VM's dir | GET | dir | `VM_READFS_ANY` | OR | `VM_READFS` | | | `/vms/{id}/exportdir` | download a VM's dir | GET | common.params.VMExportDir | `VM_READFS_ANY` | OR | `VM_READFS` | .tar.gz archive |
| `/vms/{id}/importfiles` | upload files into a VM's dir | POST | files (.tar archive),dir | `VM_WRITEFS_ANY` | OR | `VM_WRITEFS` | | | `/vms/{id}/importfiles` | upload files into a VM's dir | POST | multipart form: { "vmDir" (path), | `VM_WRITEFS_ANY` | OR | `VM_WRITEFS` | |
| | | | "file" (.tar.gz archive) } | | | | |
### Template management ### Template management
| Route | Description | Method | Input | Req. user cap. | Output | | Route | Description | Method | Input | Req. user cap. | Output |
|--- |--- |--- |--- |--- |--- | |--- |--- |--- |--- |--- |--- |
| `/templates` | returns templates that can be listed | GET | | `TPL_LIST_ANY` OR `TPL_LIST` | | | `/templates` | returns templates that can be listed | GET | - | `TPL_LIST_ANY` OR `TPL_LIST` | common.template.TemplateSerialized |
| `/templates/{id}` | returns a template | GET | | `TPL_LIST_ANY` OR `TPL_LIST` | | | `/templates/{id}` | returns a template | GET | - | `TPL_LIST_ANY` OR `TPL_LIST` | []common.template.TemplateSerialized |
| `/templates/vm` | create a template | POST | vmID,name,access | `TPL_CREATE` | | | `/templates/vm` | create a template | POST | common.params.TplCreate | `TPL_CREATE` | common.template.TemplateSerialized |
| `/templates/qcow` | create a template | POST | qcow,name,access | `TPL_CREATE` | | | `/templates/{id}` | edit a template | PUT | common.params.TplEdit | `TPL_EDIT_ANY` OR `TPL_EDIT` | common.template.TemplateSerialized |
| `/templates/{id}` | edit a template | PUT | name,access | `TPL_EDIT_ANY` OR `TPL_EDIT` | | | `/templates/{id}` | delete a template | DELETE | - | `TPL_DESTROY_ANY` OR `TPL_DESTROY` | - |
| `/templates/{id}` | delete a template | DELETE | | `TPL_DESTROY_ANY` OR `TPL_DESTROY` | | | `/templates/{id}/disk` | download a template's disk image | GET | - | `TPL_READFS_ANY` OR `TPL_READFS` | qcow file |
| `/templates/{id}/disk` | download a template's disk | GET | | `TPL_READFS_ANY` OR `TPL_READFS` | |
<!--
| `/templates/qcow` | create a template | POST | multipart form: { "name", "access", | `TPL_CREATE` | common.template.TemplateSerialized |
| | | | "qcow" (.qcow file) } | | |
-->
Remarks: Remarks:
......
...@@ -65,7 +65,8 @@ func (cmd *Edit)Run(args []string) int { ...@@ -65,7 +65,8 @@ func (cmd *Edit)Run(args []string) int {
statusCode = 1 statusCode = 1
} else { } else {
if resp.IsSuccess() { if resp.IsSuccess() {
u.Println("Successfully edited template \""+tplID+"\"") u.Println("Successfully edited template \""+tplID+"\":")
u.Println(resp.String())
} else { } else {
u.PrintlnErr("Failed editing template \""+tplID+"\": "+resp.Status()+": "+resp.String()) u.PrintlnErr("Failed editing template \""+tplID+"\": "+resp.Status()+": "+resp.String())
statusCode = 1 statusCode = 1
......
...@@ -105,7 +105,8 @@ func (router *Router)Start(port int) { ...@@ -105,7 +105,8 @@ func (router *Router)Start(port int) {
templatesGroup.GET("/:id", router.tpl.GetTemplate) templatesGroup.GET("/:id", router.tpl.GetTemplate)
templatesGroup.GET("", router.tpl.GetTemplates) templatesGroup.GET("", router.tpl.GetTemplates)
templatesGroup.POST("/vm", router.tpl.CreateTemplateFromVM) templatesGroup.POST("/vm", router.tpl.CreateTemplateFromVM)
templatesGroup.POST("/qcow", router.tpl.CreateTemplateFromQCOW) // Disabled route: uses huge amount of memory due to a bug in the Echo framework
// templatesGroup.POST("/qcow", router.tpl.CreateTemplateFromQCOW)
templatesGroup.GET("/:id/disk", router.tpl.ExportDisk) templatesGroup.GET("/:id/disk", router.tpl.ExportDisk)
templatesGroup.DELETE("/:id", router.tpl.DeleteTemplate) templatesGroup.DELETE("/:id", router.tpl.DeleteTemplate)
templatesGroup.PUT("/:id", router.tpl.EditTemplate) templatesGroup.PUT("/:id", router.tpl.EditTemplate)
......
...@@ -272,32 +272,34 @@ func (r *RouterTemplates)EditTemplate(c echo.Context) error { ...@@ -272,32 +272,34 @@ func (r *RouterTemplates)EditTemplate(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
} }
editTemplate := func(c echo.Context, tplID uuid.UUID) error {
// Deserializes and validates client's parameters. // Deserializes and validates client's parameters.
// Given these parameters are optional, we can't use a validator on them. // Given these parameters are optional, we can't use a validator on them.
// Validation is performed in templates.EditTemplate() instead. // Validation is performed in templates.EditTemplate() instead.
p := new(params.TplEdit) p := new(params.TplEdit)
if user.HasCapability(caps.CAP_TPL_EDIT_ANY) {
if err := decodeJson(c, &p); err != nil { if err := decodeJson(c, &p); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
} }
if err := r.tpl.EditTemplate(tplID, p.Name, p.Access); err != nil { if err := r.tpl.EditTemplate(tplID, p.Name, p.Access); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
} }
return c.JSON(http.StatusOK, "")
editedTpl, err := r.tpl.GetTemplate(tplID)
if err != nil {
return echo.NewHTTPError(http.StatusNotFound, err.Error())
}
return c.JSONPretty(http.StatusOK, editedTpl.SerializeToNetwork(), " ")
}
if user.HasCapability(caps.CAP_TPL_EDIT_ANY) {
return editTemplate(c, tplID)
} else if user.HasCapability(caps.CAP_TPL_EDIT) { } else if user.HasCapability(caps.CAP_TPL_EDIT) {
template, err := r.tpl.GetTemplate(tplID) template, err := r.tpl.GetTemplate(tplID)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusNotFound, err.Error()) return echo.NewHTTPError(http.StatusNotFound, err.Error())
} }
if template.GetOwner() == user.Email { if template.GetOwner() == user.Email {
if err := decodeJson(c, &p); err != nil { return editTemplate(c, tplID)
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
if err := r.tpl.EditTemplate(tplID, p.Name, p.Access); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
return c.JSON(http.StatusOK, "")
} }
} }
......
...@@ -518,7 +518,7 @@ func (r *RouterVMs)ExportVMDir(c echo.Context) error { ...@@ -518,7 +518,7 @@ func (r *RouterVMs)ExportVMDir(c echo.Context) error {
// Requires to be the VM's owner, or either capability: // Requires to be the VM's owner, or either capability:
// User cap: VM_WRITEFS_ANY: any VM can import the file tree. // User cap: VM_WRITEFS_ANY: any VM can import the file tree.
// VM access cap: VM_WRITEFS: any of the VMs with this cap for the logged user can import the file tree. // VM access cap: VM_WRITEFS: any of the VMs with this cap for the logged user can import the file tree.
// curl --cacert ca.pem -X POST https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/importfiles -H 'Content-Type: multipart/form-data' -F dir="/home/nexus" -F file=@files.tar -H "Authorization: Bearer <AccessToken>" // curl --cacert ca.pem -X POST https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/importfiles -H 'Content-Type: multipart/form-data' -F vmDir="/home/nexus" -F file=@files.tar.gz -H "Authorization: Bearer <AccessToken>"
func (r *RouterVMs)ImportFilesToVM(c echo.Context) error { func (r *RouterVMs)ImportFilesToVM(c echo.Context) error {
return r.applyOnFilteredVMs(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(c echo.Context, vm *vms.VM) error { return r.applyOnFilteredVMs(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(c echo.Context, vm *vms.VM) error {
// Retrieves the various client arguments. // Retrieves the various client arguments.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment