Compare commits
10 Commits
1da7870720
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e1418fc8f | ||
|
|
0959988310 | ||
|
|
384218612a | ||
|
|
53e0f7a467 | ||
|
|
e0bad00f0d | ||
|
|
eaf0c775ac | ||
|
|
44a91358ff | ||
|
|
da325f0c79 | ||
|
|
b79dbe4708 | ||
|
|
00724077e1 |
@@ -7,8 +7,8 @@
|
|||||||
This module allows you to record and manage VPS servers for customers.
|
This module allows you to record and manage VPS servers for customers.
|
||||||
Customers can view their VPS server information in the portal.
|
Customers can view their VPS server information in the portal.
|
||||||
""",
|
""",
|
||||||
'author': 'Your Company',
|
'author': 'Openworx',
|
||||||
'website': 'https://www.yourcompany.com',
|
'website': 'https://www.openworx.nl',
|
||||||
'depends': [
|
'depends': [
|
||||||
'base',
|
'base',
|
||||||
'portal',
|
'portal',
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
],
|
],
|
||||||
'data': [
|
'data': [
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
|
'security/ir.rule.xml',
|
||||||
'views/vps_server_views.xml',
|
'views/vps_server_views.xml',
|
||||||
'views/res_partner_views.xml',
|
'views/res_partner_views.xml',
|
||||||
'views/portal_templates.xml',
|
'views/portal_templates.xml',
|
||||||
|
|||||||
Binary file not shown.
@@ -1,27 +1,30 @@
|
|||||||
from odoo import http, _
|
from odoo import http, _
|
||||||
from odoo.exceptions import AccessError, MissingError
|
from odoo.exceptions import AccessError
|
||||||
from odoo.http import request
|
from odoo.http import request
|
||||||
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
|
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
|
||||||
from odoo.osv.expression import OR
|
from odoo.osv.expression import OR
|
||||||
|
|
||||||
class CustomerPortalVPS(CustomerPortal):
|
class VPSPortal(CustomerPortal):
|
||||||
|
|
||||||
def _prepare_home_portal_values(self, counters):
|
def _prepare_home_portal_values(self, counters):
|
||||||
values = super()._prepare_home_portal_values(counters)
|
values = super()._prepare_home_portal_values(counters)
|
||||||
|
partner = request.env.user.partner_id
|
||||||
|
VPSServer = request.env['vps.server']
|
||||||
if 'vps_server_count' in counters:
|
if 'vps_server_count' in counters:
|
||||||
values['vps_server_count'] = request.env['vps.server'].search_count([('customer_id', '=', request.env.user.partner_id.id)])
|
values['vps_server_count'] = VPSServer.search_count([('customer_id', '=', partner.id)])
|
||||||
return values
|
return values
|
||||||
|
|
||||||
@http.route(['/my/vps-servers', '/my/vps-servers/page/<int:page>'], type='http', auth="user", website=True)
|
@http.route(['/my/vps-servers', '/my/vps-servers/page/<int:page>'], type='http', auth="user", website=True)
|
||||||
def portal_my_vps_servers(self, page=1, date_begin=None, date_end=None, sortby=None, **kw):
|
def portal_my_vps_servers(self, page=1, date_begin=None, date_end=None, sortby=None, **kw):
|
||||||
values = self._prepare_portal_layout_values()
|
values = self._prepare_portal_layout_values()
|
||||||
|
partner = request.env.user.partner_id
|
||||||
VPSServer = request.env['vps.server']
|
VPSServer = request.env['vps.server']
|
||||||
|
|
||||||
domain = [('customer_id', '=', request.env.user.partner_id.id)]
|
domain = [('customer_id', '=', partner.id)]
|
||||||
|
|
||||||
searchbar_sortings = {
|
searchbar_sortings = {
|
||||||
'name': {'label': _('Name'), 'order': 'name'},
|
'name': {'label': _('Name'), 'order': 'name'},
|
||||||
'ip_address': {'label': _('IP Address'), 'order': 'ip_address'},
|
'state': {'label': _('State'), 'order': 'state'},
|
||||||
}
|
}
|
||||||
|
|
||||||
if not sortby:
|
if not sortby:
|
||||||
@@ -62,19 +65,41 @@ class CustomerPortalVPS(CustomerPortal):
|
|||||||
})
|
})
|
||||||
return request.render("ow_vm_management.portal_my_vps_servers", values)
|
return request.render("ow_vm_management.portal_my_vps_servers", values)
|
||||||
|
|
||||||
@http.route(['/my/vps-servers/<int:vps_server_id>'], type='http', auth="user", website=True)
|
@http.route(['/my/vps-servers/<int:vps_id>'], type='http', auth="user", website=True)
|
||||||
def portal_my_vps_server(self, vps_server_id=None, access_token=None, **kw):
|
def portal_my_vps_server(self, vps_id, **kw):
|
||||||
try:
|
try:
|
||||||
vps_server_sudo = self._document_check_access('vps.server', vps_server_id, access_token)
|
vps_sudo = self._document_check_access('vps.server', vps_id)
|
||||||
except (AccessError, MissingError):
|
if vps_sudo.customer_id != request.env.user.partner_id:
|
||||||
return request.redirect('/my')
|
return request.redirect('/my/vps-servers')
|
||||||
|
values = self._vps_server_get_page_view_values(vps_sudo, **kw)
|
||||||
|
return request.render("ow_vm_management.portal_vps_server_page", values)
|
||||||
|
except AccessError:
|
||||||
|
return request.redirect('/my/vps-servers')
|
||||||
|
|
||||||
values = self._vps_server_get_page_view_values(vps_server_sudo, access_token, **kw)
|
def _vps_server_get_page_view_values(self, vps_server, access_token=None, **kwargs):
|
||||||
return request.render("ow_vm_management.portal_vps_server_page", values)
|
|
||||||
|
|
||||||
def _vps_server_get_page_view_values(self, vps_server, access_token, **kwargs):
|
|
||||||
values = {
|
values = {
|
||||||
'page_name': 'vps_server',
|
'page_name': 'vps_server',
|
||||||
'vps_server': vps_server,
|
'vps_server': vps_server,
|
||||||
}
|
}
|
||||||
return self._get_page_view_values(vps_server, access_token, values, 'my_vps_servers_history', False, **kwargs)
|
return self._get_page_view_values(vps_server, access_token, values, 'my_vps_servers_history', False, **kwargs)
|
||||||
|
|
||||||
|
@http.route(['/my/vps/<int:vps_id>/restart'], type='http', auth="user", website=True)
|
||||||
|
def portal_restart_vps(self, vps_id, **kw):
|
||||||
|
try:
|
||||||
|
vps_sudo = self._document_check_access('vps.server', vps_id)
|
||||||
|
if vps_sudo.customer_id != request.env.user.partner_id:
|
||||||
|
return request.redirect('/my/vps-servers')
|
||||||
|
vps_sudo.action_restart_from_portal()
|
||||||
|
return request.redirect(f'/my/vps-servers/{vps_id}')
|
||||||
|
except AccessError:
|
||||||
|
return request.redirect('/my/vps-servers')
|
||||||
|
|
||||||
|
def _document_check_access(self, model_name, document_id, access_token=None):
|
||||||
|
document = request.env[model_name].sudo().browse(document_id)
|
||||||
|
document_sudo = document.with_user(request.env.user).sudo()
|
||||||
|
try:
|
||||||
|
document_sudo.check_access_rights('read')
|
||||||
|
document_sudo.check_access_rule('read')
|
||||||
|
except AccessError:
|
||||||
|
raise
|
||||||
|
return document_sudo
|
||||||
265
ow_vm_management/i18n/nl.po
Normal file
265
ow_vm_management/i18n/nl.po
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
# Translation of Odoo Server.
|
||||||
|
# This file contains the translation of the following modules:
|
||||||
|
# * ow_vm_management
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: Odoo Server 16.0\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2023-08-06 20:10+0000\n"
|
||||||
|
"PO-Revision-Date: 2023-08-06 20:10+0000\n"
|
||||||
|
"Last-Translator: \n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: \n"
|
||||||
|
"Plural-Forms: \n"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__cpu
|
||||||
|
msgid "CPU Cores"
|
||||||
|
msgstr "CPU Kernen"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__customer_id
|
||||||
|
msgid "Customer"
|
||||||
|
msgstr "Klant"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__ipv4_address
|
||||||
|
msgid "IPv4 Addresses"
|
||||||
|
msgstr "IPv4 Adressen"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__ipv6_address
|
||||||
|
msgid "IPv6 Addresses"
|
||||||
|
msgstr "IPv6 Adressen"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__managed_server
|
||||||
|
msgid "Managed Server"
|
||||||
|
msgstr "Beheerde Server"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__name
|
||||||
|
msgid "Server Name"
|
||||||
|
msgstr "Servernaam"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__os
|
||||||
|
msgid "Operating System"
|
||||||
|
msgstr "Besturingssysteem"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__ram
|
||||||
|
msgid "RAM (GB)"
|
||||||
|
msgstr "RAM (GB)"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__storage
|
||||||
|
msgid "Storage (GB)"
|
||||||
|
msgstr "Opslag (GB)"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_vps_server__state
|
||||||
|
msgid "State"
|
||||||
|
msgstr "Status"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields.selection,name:ow_vm_management.selection__vps_server__state__running
|
||||||
|
msgid "Running"
|
||||||
|
msgstr "Actief"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields.selection,name:ow_vm_management.selection__vps_server__state__stopped
|
||||||
|
msgid "Stopped"
|
||||||
|
msgstr "Gestopt"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields.selection,name:ow_vm_management.selection__vps_server__state__unknown
|
||||||
|
msgid "Unknown"
|
||||||
|
msgstr "Onbekend"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.actions.act_window,name:ow_vm_management.action_vps_server
|
||||||
|
#: model:ir.ui.menu,name:ow_vm_management.menu_vps_server
|
||||||
|
msgid "VPS Servers"
|
||||||
|
msgstr "VPS Servers"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model,name:ow_vm_management.model_vps_server
|
||||||
|
msgid "VPS Server"
|
||||||
|
msgstr "VPS Server"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.view_vps_server_form
|
||||||
|
msgid "Start"
|
||||||
|
msgstr "Starten"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.view_vps_server_form
|
||||||
|
msgid "Shutdown"
|
||||||
|
msgstr "Afsluiten"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.view_vps_server_form
|
||||||
|
msgid "Stop"
|
||||||
|
msgstr "Stoppen"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.view_vps_server_form
|
||||||
|
msgid "Reboot"
|
||||||
|
msgstr "Herstarten"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.view_vps_server_form
|
||||||
|
msgid "Fetch Proxmox Data"
|
||||||
|
msgstr "Proxmox Gegevens Ophalen"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model,name:ow_vm_management.model_proxmox_server
|
||||||
|
msgid "Proxmox Server"
|
||||||
|
msgstr "Proxmox Server"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_proxmox_server__name
|
||||||
|
msgid "Server Name"
|
||||||
|
msgstr "Servernaam"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_proxmox_server__url
|
||||||
|
msgid "Proxmox URL"
|
||||||
|
msgstr "Proxmox URL"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_proxmox_server__api_token_id
|
||||||
|
msgid "API Token ID"
|
||||||
|
msgstr "API Token ID"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.model.fields,field_description:ow_vm_management.field_proxmox_server__api_token_secret
|
||||||
|
msgid "API Token Secret"
|
||||||
|
msgstr "API Token Geheim"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.view_proxmox_server_form
|
||||||
|
msgid "Test Connection"
|
||||||
|
msgstr "Verbinding Testen"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.actions.act_window,name:ow_vm_management.action_proxmox_server
|
||||||
|
#: model:ir.ui.menu,name:ow_vm_management.menu_proxmox_server
|
||||||
|
msgid "Proxmox Servers"
|
||||||
|
msgstr "Proxmox Servers"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model:ir.ui.menu,name:ow_vm_management.menu_ow_vm_management_root
|
||||||
|
#: model:ir.ui.menu,name:ow_vm_management.menu_ow_vm_management
|
||||||
|
msgid "VPS Management"
|
||||||
|
msgstr "VPS Beheer"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_my_home_vps_servers
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_my_vps_servers
|
||||||
|
msgid "VPS Servers"
|
||||||
|
msgstr "VPS Servers"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_my_vps_servers
|
||||||
|
msgid "Server Name"
|
||||||
|
msgstr "Servernaam"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_my_vps_servers
|
||||||
|
msgid "IPv4 Address"
|
||||||
|
msgstr "IPv4 Adres"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_my_vps_servers
|
||||||
|
msgid "IPv6 Address"
|
||||||
|
msgstr "IPv6 Adres"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_my_vps_servers
|
||||||
|
msgid "CPU"
|
||||||
|
msgstr "CPU"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_my_vps_servers
|
||||||
|
msgid "RAM (GB)"
|
||||||
|
msgstr "RAM (GB)"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_my_vps_servers
|
||||||
|
msgid "Storage (GB)"
|
||||||
|
msgstr "Opslag (GB)"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_vps_server_page
|
||||||
|
msgid "Restart VPS"
|
||||||
|
msgstr "VPS Herstarten"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: model_terms:ir.ui.view,arch_db:ow_vm_management.portal_vps_server_page
|
||||||
|
msgid "Are you sure you want to restart this VPS?"
|
||||||
|
msgstr "Weet u zeker dat u deze VPS wilt herstarten?"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/controllers/portal.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "You don't have access to this VPS server."
|
||||||
|
msgstr "U heeft geen toegang tot deze VPS server."
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/controllers/portal.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "You don't have permission to restart this VPS."
|
||||||
|
msgstr "U heeft geen toestemming om deze VPS te herstarten."
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/models/vps_server.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Please provide either CT ID or VM ID, not both."
|
||||||
|
msgstr "Geef alstublieft ofwel een CT ID of een VM ID op, niet beide."
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/models/vps_server.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Proxmox API request failed: %s"
|
||||||
|
msgstr "Proxmox API-verzoek mislukt: %s"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/models/vps_server.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Data Fetched"
|
||||||
|
msgstr "Gegevens Opgehaald"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/models/vps_server.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Successfully fetched data from Proxmox server."
|
||||||
|
msgstr "Gegevens succesvol opgehaald van Proxmox server."
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/models/vps_server.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Failed to fetch data from Proxmox server: %s"
|
||||||
|
msgstr "Ophalen van gegevens van Proxmox server mislukt: %s"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/models/proxmox_server.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Connection Successful"
|
||||||
|
msgstr "Verbinding Succesvol"
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/models/proxmox_server.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Successfully connected to the Proxmox server."
|
||||||
|
msgstr "Succesvol verbonden met de Proxmox server."
|
||||||
|
|
||||||
|
#. module: ow_vm_management
|
||||||
|
#: code:addons/ow_vm_management/models/proxmox_server.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Failed to connect to Proxmox server: %s"
|
||||||
|
msgstr "Verbinding maken met Proxmox server mislukt: %s"
|
||||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError, AccessError
|
||||||
import requests
|
import requests
|
||||||
import urllib3
|
import urllib3
|
||||||
import ipaddress
|
import ipaddress
|
||||||
@@ -20,6 +20,12 @@ class VPSServer(models.Model):
|
|||||||
proxmox_server_id = fields.Many2one('proxmox.server', string='Proxmox Server', tracking=True)
|
proxmox_server_id = fields.Many2one('proxmox.server', string='Proxmox Server', tracking=True)
|
||||||
ct_id = fields.Integer(string='CT ID (LXC)', tracking=True)
|
ct_id = fields.Integer(string='CT ID (LXC)', tracking=True)
|
||||||
vm_id = fields.Integer(string='VM ID (QEMU)', tracking=True)
|
vm_id = fields.Integer(string='VM ID (QEMU)', tracking=True)
|
||||||
|
state = fields.Selection([
|
||||||
|
('running', 'Running'),
|
||||||
|
('stopped', 'Stopped'),
|
||||||
|
('unknown', 'Unknown')
|
||||||
|
], string='State', default='unknown', tracking=True)
|
||||||
|
managed_server = fields.Boolean(string='Managed Server', default=False, tracking=True)
|
||||||
|
|
||||||
def _compute_access_url(self):
|
def _compute_access_url(self):
|
||||||
super()._compute_access_url()
|
super()._compute_access_url()
|
||||||
@@ -31,6 +37,71 @@ class VPSServer(models.Model):
|
|||||||
if self.ct_id and self.vm_id:
|
if self.ct_id and self.vm_id:
|
||||||
raise UserError(_("Please provide either CT ID or VM ID, not both."))
|
raise UserError(_("Please provide either CT ID or VM ID, not both."))
|
||||||
|
|
||||||
|
def _proxmox_request(self, method, endpoint, data=None):
|
||||||
|
self.ensure_one()
|
||||||
|
proxmox = self.proxmox_server_id
|
||||||
|
base_url = proxmox.url.rstrip('/')
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"PVEAPIToken={proxmox.api_token_id}={proxmox.api_token_secret}"
|
||||||
|
}
|
||||||
|
url = f"{base_url}/api2/json/{endpoint}"
|
||||||
|
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.request(method, url, headers=headers, json=data, verify=False)
|
||||||
|
response.raise_for_status()
|
||||||
|
return response.json()
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
raise UserError(_("Proxmox API request failed: %s") % str(e))
|
||||||
|
|
||||||
|
def action_start(self):
|
||||||
|
for server in self:
|
||||||
|
vm_type = 'lxc' if server.ct_id else 'qemu'
|
||||||
|
vm_id = server.ct_id or server.vm_id
|
||||||
|
self._proxmox_request('POST', f'nodes/pve/{vm_type}/{vm_id}/status/start')
|
||||||
|
self.fetch_state()
|
||||||
|
|
||||||
|
def action_shutdown(self):
|
||||||
|
for server in self:
|
||||||
|
vm_type = 'lxc' if server.ct_id else 'qemu'
|
||||||
|
vm_id = server.ct_id or server.vm_id
|
||||||
|
self._proxmox_request('POST', f'nodes/pve/{vm_type}/{vm_id}/status/shutdown')
|
||||||
|
self.fetch_state()
|
||||||
|
|
||||||
|
def action_stop(self):
|
||||||
|
for server in self:
|
||||||
|
vm_type = 'lxc' if server.ct_id else 'qemu'
|
||||||
|
vm_id = server.ct_id or server.vm_id
|
||||||
|
self._proxmox_request('POST', f'nodes/pve/{vm_type}/{vm_id}/status/stop')
|
||||||
|
self.fetch_state()
|
||||||
|
|
||||||
|
def action_reboot(self):
|
||||||
|
for server in self:
|
||||||
|
vm_type = 'lxc' if server.ct_id else 'qemu'
|
||||||
|
vm_id = server.ct_id or server.vm_id
|
||||||
|
self._proxmox_request('POST', f'nodes/pve/{vm_type}/{vm_id}/status/reboot')
|
||||||
|
self.fetch_state()
|
||||||
|
|
||||||
|
def fetch_state(self):
|
||||||
|
for server in self:
|
||||||
|
vm_type = 'lxc' if server.ct_id else 'qemu'
|
||||||
|
vm_id = server.ct_id or server.vm_id
|
||||||
|
status = self._proxmox_request('GET', f'nodes/pve/{vm_type}/{vm_id}/status/current')
|
||||||
|
server.state = 'running' if status['data']['status'] == 'running' else 'stopped'
|
||||||
|
|
||||||
|
def check_access_rule(self, operation):
|
||||||
|
if self.env.user.has_group('base.group_portal'):
|
||||||
|
if operation != 'read' or self.customer_id != self.env.user.partner_id:
|
||||||
|
raise AccessError(_("You don't have access to this VPS server."))
|
||||||
|
return super(VPSServer, self).check_access_rule(operation)
|
||||||
|
|
||||||
|
def action_restart_from_portal(self):
|
||||||
|
self.ensure_one()
|
||||||
|
if self.env.user.partner_id != self.customer_id:
|
||||||
|
raise AccessError(_("You don't have permission to restart this VPS."))
|
||||||
|
return self.action_reboot()
|
||||||
|
|
||||||
def action_fetch_proxmox_data(self):
|
def action_fetch_proxmox_data(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
if not self.proxmox_server_id:
|
if not self.proxmox_server_id:
|
||||||
@@ -75,10 +146,12 @@ class VPSServer(models.Model):
|
|||||||
config_data = config_response.json()['data']
|
config_data = config_response.json()['data']
|
||||||
|
|
||||||
# Update fields
|
# Update fields
|
||||||
self.name = config_data.get('name', f"{vm_type}-{vm_id}")
|
hostname = config_data.get('hostname', '')
|
||||||
|
vm_name = f"{vm_type}-{vm_id}"
|
||||||
|
self.name = f"{vm_name} ({hostname})" if hostname else vm_name
|
||||||
self.cpu = status_data.get('cpus', 0)
|
self.cpu = status_data.get('cpus', 0)
|
||||||
self.ram = status_data.get('maxmem', 0) / (1024 * 1024 * 1024) # Convert to GB
|
self.ram = status_data.get('maxmem', 0) / (1024 * 1024 * 1024) # Convert to GB
|
||||||
self.storage = status_data.get('maxdisk', 0) / (1024 * 1024 * 1024) # Convert to GB
|
self.storage = round(status_data.get('maxdisk', 0) / (1024 * 1024 * 1024)) # Convert to GB
|
||||||
|
|
||||||
# Try to get IP addresses
|
# Try to get IP addresses
|
||||||
ipv4_addresses = []
|
ipv4_addresses = []
|
||||||
@@ -127,6 +200,8 @@ class VPSServer(models.Model):
|
|||||||
else: # QEMU
|
else: # QEMU
|
||||||
self.os = config_data.get('ostype', 'Unknown')
|
self.os = config_data.get('ostype', 'Unknown')
|
||||||
|
|
||||||
|
self.fetch_state()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'type': 'ir.actions.client',
|
'type': 'ir.actions.client',
|
||||||
'tag': 'display_notification',
|
'tag': 'display_notification',
|
||||||
|
|||||||
15
ow_vm_management/security/ir.rule.xml
Normal file
15
ow_vm_management/security/ir.rule.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="vps_server_portal_rule" model="ir.rule">
|
||||||
|
<field name="name">Portal user can only see own VPS servers</field>
|
||||||
|
<field name="model_id" ref="model_vps_server"/>
|
||||||
|
<field name="domain_force">[('customer_id', '=', user.partner_id.id)]</field>
|
||||||
|
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
|
||||||
|
<field name="perm_read" eval="True"/>
|
||||||
|
<field name="perm_write" eval="False"/>
|
||||||
|
<field name="perm_create" eval="False"/>
|
||||||
|
<field name="perm_unlink" eval="False"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
<th class='d-none d-md-table-cell'>IPv6 Address</th>
|
<th class='d-none d-md-table-cell'>IPv6 Address</th>
|
||||||
<th class='text-right'>CPU</th>
|
<th class='text-right'>CPU</th>
|
||||||
<th class='text-right'>RAM (GB)</th>
|
<th class='text-right'>RAM (GB)</th>
|
||||||
|
<th class='text-right'>Storage (GB)</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -48,6 +49,9 @@
|
|||||||
<td class='text-right'>
|
<td class='text-right'>
|
||||||
<span t-field="server.ram"/>
|
<span t-field="server.ram"/>
|
||||||
</td>
|
</td>
|
||||||
|
<td class='text-right'>
|
||||||
|
<span t-field="server.storage"/>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</t>
|
</t>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -70,6 +74,15 @@
|
|||||||
</h5>
|
</h5>
|
||||||
</t>
|
</t>
|
||||||
<t t-set="card_body">
|
<t t-set="card_body">
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-12 text-right">
|
||||||
|
<a t-att-href="'/my/vps/%s/restart' % vps_server.id"
|
||||||
|
class="btn btn-primary"
|
||||||
|
onclick="return confirm('Are you sure you want to restart this VPS?');">
|
||||||
|
<i class="fa fa-refresh"/> Restart VPS
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
<strong>IPv4 Address:</strong> <span t-field="vps_server.ipv4_address"/>
|
<strong>IPv4 Address:</strong> <span t-field="vps_server.ipv4_address"/>
|
||||||
@@ -89,6 +102,9 @@
|
|||||||
<div class="col-12 col-md-6">
|
<div class="col-12 col-md-6">
|
||||||
<strong>Operating System:</strong> <span t-field="vps_server.os"/>
|
<strong>Operating System:</strong> <span t-field="vps_server.os"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<strong>State:</strong> <span t-field="vps_server.state"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
|
|||||||
@@ -6,7 +6,12 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form>
|
<form>
|
||||||
<header>
|
<header>
|
||||||
|
<button name="action_start" string="Start" type="object" icon="fa-play" attrs="{'invisible': [('state', '=', 'running')]}" class="oe_highlight"/>
|
||||||
|
<button name="action_shutdown" string="Shutdown" type="object" icon="fa-power-off" attrs="{'invisible': [('state', '!=', 'running')]}" class="oe_highlight"/>
|
||||||
|
<button name="action_stop" string="Stop" type="object" icon="fa-stop" attrs="{'invisible': [('state', '!=', 'running')]}" class="text-danger"/>
|
||||||
|
<button name="action_reboot" string="Reboot" type="object" icon="fa-refresh" attrs="{'invisible': [('state', '!=', 'running')]}" class="oe_highlight"/>
|
||||||
<button name="action_fetch_proxmox_data" string="Fetch Proxmox Data" type="object" class="oe_highlight"/>
|
<button name="action_fetch_proxmox_data" string="Fetch Proxmox Data" type="object" class="oe_highlight"/>
|
||||||
|
<field name="state" widget="statusbar"/>
|
||||||
</header>
|
</header>
|
||||||
<sheet>
|
<sheet>
|
||||||
<group>
|
<group>
|
||||||
@@ -24,6 +29,7 @@
|
|||||||
<field name="proxmox_server_id"/>
|
<field name="proxmox_server_id"/>
|
||||||
<field name="ct_id"/>
|
<field name="ct_id"/>
|
||||||
<field name="vm_id"/>
|
<field name="vm_id"/>
|
||||||
|
<field name="managed_server"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</sheet>
|
</sheet>
|
||||||
|
|||||||
Reference in New Issue
Block a user