Skip to content

Commit f320932

Browse files
[IMP] server_environment: add possibility of auto creating records
1 parent 07d321d commit f320932

10 files changed

Lines changed: 164 additions & 3 deletions

File tree

server_environment/models/server_env_mixin.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
33

44
import logging
5+
from ast import literal_eval
56
from functools import partialmethod
67

78
from lxml import etree
@@ -424,3 +425,40 @@ def _setup_base(self):
424425
self._server_env_transform_field_to_read_from_env(field)
425426
self._server_env_add_is_editable_field(field)
426427
return
428+
429+
def _register_hook(self):
430+
super()._register_hook()
431+
for model_name in self.env:
432+
model = self.env[model_name]
433+
if hasattr(model, "_server_env_global_section_name"):
434+
global_section_name = model._server_env_global_section_name()
435+
for section in serv_config:
436+
if section.startswith(f"{global_section_name}."):
437+
if serv_config[section].get("__autocreate", None):
438+
name_value = section[len(global_section_name) + 1 :]
439+
domain = [
440+
(model._server_env_section_name_field, "=", name_value)
441+
]
442+
count = model.with_context(active_test=False).search_count(
443+
domain
444+
)
445+
if count == 0:
446+
_logger.debug("Automatic creation of %s", section)
447+
values = literal_eval(
448+
serv_config[section].get("__autocreate")
449+
)
450+
values[
451+
model._server_env_section_name_field
452+
] = name_value
453+
records = model.create([values])
454+
self.env["ir.model.data"].create(
455+
[
456+
{
457+
"name": section,
458+
"model": model_name,
459+
"module": "__server_environment__",
460+
"res_id": record.id,
461+
}
462+
for record in records
463+
]
464+
)

server_environment/readme/CONFIGURE.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,20 @@ Note: empty environment keys always take precedence over default fields
9898

9999
Read the documentation of the class
100100
[models/server_env_mixin.py](models/server_env_mixin.py).
101+
102+
## Auto creation of records
103+
104+
It is possible to indicate that records must be created automatically if not found in the database.
105+
106+
When specifying a section in the configuration file or environment variable, also define ``__autocreate = {}``.
107+
The value is a dictionary that will be passed when the record is created. This allows setting some non environment variables that are required.
108+
For example, when using fs_storage module, the name of the storage is required so the configuration would look like:
109+
110+
```ini
111+
[fs_storage.my_sftp]
112+
__autocreate = {"name": "My SFTP"}
113+
protocol=sftp
114+
options={"host": "10.10.10.10", "username": "foo", "password": "xxxxxxxxx"}
115+
```
116+
117+
When the module creates such a record, it will add an xml id in the form `__server_enironment__.<section name>`.

server_environment/readme/CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
- Thomas Binfeld \<<thomas.binsfeld@acsone.eu>\>
1111
- Stéphane Bidoul \<<stefane.bidoul@acsone.com>\>
1212
- Simone Orsi \<<simahawk@gmail.com>\>
13+
- Vincent Hatakeyama \<<vincent.hatakeyama@xcg-consulting.fr>\>

server_environment/readme/ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
- it is not possible to set the environment from the command line. A
2-
configuration file must be used.
2+
configuration file or environment variables must be used.
33
- the module does not allow to set low level attributes such as database
44
server, etc.
55
- server.env.techname.mixin's tech_name field could leverage the new
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
from . import test_server_environment_autocreate
12
from . import test_server_environment
23
from . import test_environment_variable

server_environment/tests/models.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2024 XCG Consulting
2+
# @author Vincent Hatakeyama
3+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
4+
from odoo import fields, models
5+
6+
7+
class ExternalService(models.Model):
8+
_name = "external_service"
9+
_description = "External Service"
10+
_inherit = "server.env.mixin"
11+
12+
name = fields.Char(required=True)
13+
description = fields.Char(required=True)
14+
host = fields.Char()
15+
user = fields.Char()
16+
password = fields.Char()
17+
18+
@property
19+
def _server_env_fields(self):
20+
return {
21+
"host": {},
22+
"user": {},
23+
"password": {},
24+
}

server_environment/tests/test_environment_variable.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66

77
from odoo.tools.config import config as odoo_config
88

9-
from odoo.addons.server_environment import server_env
10-
9+
from .. import server_env
1110
from .common import ServerEnvironmentCase
1211

1312

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright 2018 Camptocamp (https://www.camptocamp.com).
2+
# Copyright 2024 XCG Consulting (https://xcg-consulting.fr).
3+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
4+
from unittest.mock import patch
5+
6+
from odoo_test_helper import FakeModelLoader
7+
8+
from odoo.tests import tagged
9+
from odoo.tools.config import config as odoo_config
10+
11+
from .. import server_env
12+
from ..models import server_env_mixin
13+
from . import common
14+
15+
16+
# Test need to be run post install otherwise the _register_hook is not called yet
17+
@tagged("post_install", "-at_install")
18+
class TestEnv(common.ServerEnvironmentCase):
19+
@classmethod
20+
def setUpClass(cls):
21+
super().setUpClass()
22+
# Load fake models ->/
23+
cls.loader = FakeModelLoader(cls.env, cls.__module__)
24+
cls.loader.backup_registry()
25+
from .models import ExternalService
26+
27+
cls.loader.update_registry((ExternalService,))
28+
cls.env["external_service"].create([{"name": "ftp2", "description": "another"}])
29+
30+
@classmethod
31+
def tearDownClass(cls):
32+
cls.loader.restore_registry()
33+
super().tearDownClass()
34+
35+
@patch.dict(odoo_config.options, {"running_env": "autocreate"})
36+
def test_autocreate(self):
37+
original_serv_config = server_env_mixin.serv_config
38+
try:
39+
with self.set_config_dir("testfiles"):
40+
parser = server_env._load_config()
41+
server_env_mixin.serv_config = parser
42+
# Needed to force _register_hook with auto creation
43+
self.loader.update_registry(tuple())
44+
45+
# auto created record
46+
record = self.env.ref("__server_environment__.external_service.ftp")
47+
self.assertEqual(record.name, "ftp")
48+
self.assertEqual(record.description, "ftp server")
49+
self.assertEqual(record.host, "sftp.example.com")
50+
self.assertEqual(record.user, "foo")
51+
self.assertEqual(record.password, "bar")
52+
53+
# create record in setupClass
54+
# Test it has no xmlid
55+
record = self.env.ref(
56+
"__server_environment__.external_service.ftp2", False
57+
)
58+
self.assertFalse(record)
59+
# look for it
60+
record = self.env["external_service"].search([("name", "=", "ftp2")])
61+
self.assertEqual(len(record), 1)
62+
self.assertEqual(record.name, "ftp2")
63+
# different from __autocreate dict as it is created in setUpClass
64+
self.assertEqual(record.description, "another")
65+
self.assertEqual(record.host, "sftp2.example.com")
66+
self.assertEqual(record.user, "monty")
67+
self.assertEqual(record.password, "python")
68+
finally:
69+
server_env_mixin.serv_config = original_serv_config
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[external_service.ftp]
2+
__autocreate={"description": "ftp server"}
3+
; host=sftp.example.com
4+
; user=foo
5+
; password=bar
6+
7+
[external_service.ftp2]
8+
__autocreate={"description": "ftp2"}
9+
host=sftp2.example.com
10+
user=monty
11+
password=python

test-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
odoo-test-helper

0 commit comments

Comments
 (0)