Skip to content

Commit

Permalink
[FIX] cetmix_tower_server: Server creation
Browse files Browse the repository at this point in the history
Fix incorrect creation of server variables when creating a server from a template

Task: 4253
  • Loading branch information
GabbasovDinar committed Jan 15, 2025
1 parent b1e01f1 commit d2b957d
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 68 deletions.
146 changes: 92 additions & 54 deletions cetmix_tower_server/models/cx_tower_server_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.exceptions import UserError, ValidationError


class CxTowerServerTemplate(models.Model):
Expand Down Expand Up @@ -171,6 +171,10 @@ def create_server_from_template(self, template_reference, server_name, **kwargs)
`variable_reference`: `variable_value_char`
eg:
{'branch': 'prod', 'odoo_version': '16.0'}
with_template_variables (bool): This parameter ensures that the server
being created considers existing variables from the template.
If enabled, the template variables will also be included in the server
variables. The default value is True.
Returns:
cx.tower.server: newly created server record
Expand Down Expand Up @@ -199,6 +203,10 @@ def _create_new_server(self, name, **kwargs):
`variable_reference`: `variable_value_char`
eg:
{'branch': 'prod', 'odoo_version': '16.0'}
with_template_variables (bool): This parameter ensures that the server
being created considers existing variables from the template.
If enabled, the template variables will also be included in the server
variables. The default value is True.
Returns:
cx.tower.server: newly created server record
Expand Down Expand Up @@ -251,7 +259,7 @@ def _get_fields_tower_server(self):
"server_log_ids",
]

def _prepare_server_values(self, **kwargs):
def _prepare_server_values(self, with_template_variables=True, **kwargs):
"""
Prepare the server values to create a new server based on
the current template. It reads all fields from the template, copies them,
Expand All @@ -260,6 +268,10 @@ def _prepare_server_values(self, **kwargs):
data.
Args:
with_template_variables (bool): This parameter ensures that the server
being created considers existing variables from the template.
If enabled, the template variables will also be included in the server
variables. The default value is True.
**kwargs: Additional values to update in the final server record.
Returns:
Expand Down Expand Up @@ -299,76 +311,102 @@ def _prepare_server_values(self, **kwargs):

values[field] = new_records

# custom specific variable values
# Handle configuration variables if provided.
configuration_variables = kwargs.pop("configuration_variables", None)
line_ids_variables = kwargs.pop("line_ids_variables", None)
configuration_variable_options = kwargs.pop(
"configuration_variable_options", {}
)

if configuration_variables:
# Validate required variables
self._validate_required_variables(configuration_variables)

variable_vals_list = []
# Search for existing variable options.
option_references = list(configuration_variable_options.values())
existing_options = option_references and self.env[
"cx.tower.variable.option"
].search([("reference", "in", option_references)])
missing_options = list(
set(option_references)
- {option.reference for option in existing_options}
)
if missing_options:
raise UserError(
_(
"Option with references '%(references)s' "
"is not found for variables.",
references=", ".join(missing_options),
)
)

# Map variable options to their IDs.
configuration_variable_options_dict = {
option.variable_id.id: option.id for option in existing_options
}

variable_obj = self.env["cx.tower.variable"]
variable_references = list(configuration_variables.keys())

for (
variable_reference,
variable_value,
) in configuration_variables.items():
variable = variable_obj.search(
[("reference", "=", variable_reference)]
# Search for existing variables or create new ones if missing.
exist_variables = variable_obj.search(
[("reference", "in", variable_references)]
)
missing_references = list(
set(variable_references)
- {variable.reference for variable in exist_variables}
)
variable_vals_list = [
{"name": reference} for reference in missing_references
]
new_variables = variable_obj.create(variable_vals_list)
all_variables = exist_variables | new_variables

# Build a dictionary {variable: variable_value}.
configuration_variable_dict = {
variable: configuration_variables[variable.reference]
for variable in all_variables
}

server_variable_vals_list = []
for variable, variable_value in configuration_variable_dict.items():
variable_option_id = configuration_variable_options_dict.get(
variable.id
)
if not variable:
variable = variable_obj.create(
{
"name": variable_reference,
}
)
variable_option_id = variable_id = False

if not variable_value and line_ids_variables:
val_found = next(
(
v
for v in line_ids_variables.values()
if v.get("variable_reference") == variable_reference
),
None,
)
if val_found:
variable_value = val_found.get("value_char")
variable_option_id = val_found.get("option_id", False)
variable_id = val_found.get("variable_id", False)

variable_vals_list.append(
server_variable_vals_list.append(
(
0,
0,
{
"variable_id": variable.id or variable_id,
"value_char": variable_value or "",
"variable_id": variable.id,
"value_char": variable_value,
"option_id": variable_option_id,
},
)
)

# update or add variable values
existing_variable_values = values.get("variable_value_ids", [])
variable_id_to_index = {
cmd[2]["variable_id"]: idx
for idx, cmd in enumerate(existing_variable_values)
if cmd[0] == 0 and "variable_id" in cmd[2]
}

for new_command in variable_vals_list:
variable_id = new_command[2]["variable_id"]
if variable_id in variable_id_to_index:
idx = variable_id_to_index[variable_id]
# update exist command
existing_variable_values[idx] = new_command
else:
# add new command
existing_variable_values.append(new_command)

values["variable_value_ids"] = existing_variable_values
if with_template_variables:
# update or add variable values
existing_variable_values = values.get("variable_value_ids", [])
variable_id_to_index = {
cmd[2]["variable_id"]: idx
for idx, cmd in enumerate(existing_variable_values)
if cmd[0] == 0 and "variable_id" in cmd[2]
}

for new_command in server_variable_vals_list:
variable_id = new_command[2]["variable_id"]
if variable_id in variable_id_to_index:
idx = variable_id_to_index[variable_id]
# update exist command
existing_variable_values[idx] = new_command
else:
# add new command
existing_variable_values.append(new_command)

values["variable_value_ids"] = existing_variable_values
else:
values["variable_value_ids"] = server_variable_vals_list

# remove the `id` field to ensure a new record is created
# instead of updating the existing one
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ def _prepare_server_parameters(self):
"configuration_variables": {
line.variable_reference: line.value_char
for line in self.line_ids
}
},
"configuration_variable_options": {
line.variable_reference: line.option_id.reference
for line in self.line_ids
},
}
)
return res
Expand All @@ -125,19 +129,9 @@ def action_confirm(self):
raise ValidationError(self.missing_required_variables_message)

kwargs = self._prepare_server_parameters()
kwargs["line_ids_variables"] = {
line.id: {
"variable_id": line.id,
"variable_reference": line.variable_reference,
"value_char": line.option_id.value_char
if line.option_id
else line.value_char,
"option_id": line.option_id.id if line.option_id else None,
"variable_type": line.variable_type,
}
for line in self.line_ids.wizard_id.line_ids
}
server = self.server_template_id._create_new_server(self.name, **kwargs)
server = self.server_template_id._create_new_server(
self.name, with_template_variables=False, **kwargs
)
action = self.env["ir.actions.actions"]._for_xml_id(
"cetmix_tower_server.action_cx_tower_server"
)
Expand Down

0 comments on commit d2b957d

Please sign in to comment.