Tower: upload cetmix_tower_yaml 16.0.2.0.3 (via marketplace)

This commit is contained in:
2026-04-27 10:44:06 +00:00
parent 739fb53837
commit f810819876

View File

@@ -0,0 +1,347 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import yaml
from odoo.exceptions import ValidationError
from odoo.tests import TransactionCase
class TestTowerCommand(TransactionCase):
@classmethod
def setUpClass(cls, *args, **kwargs):
super().setUpClass(*args, **kwargs)
cls.Command = cls.env["cx.tower.command"]
# Expected YAML content of the test command
cls.command_test_yaml = """cetmix_tower_model: command
access_level: manager
reference: test_yaml_in_tests
name: Test YAML
action: ssh_command
allow_parallel_run: false
note: |-
Test YAML command conversion.
Ensure all fields are rendered properly.
os_ids: false
tag_ids: false
path: false
file_template_id: false
flight_plan_id: false
code: |-
cd /home/{{ tower.server.ssh_username }} \\
&& ls -lha
server_status: false
variable_ids: false
secret_ids: false
no_split_for_sudo: false
if_file_exists: skip
disconnect_file: false
"""
# YAML content translated into Python dict
cls.command_test_yaml_dict = yaml.safe_load(cls.command_test_yaml)
def test_yaml_from_command(self):
"""Test if YAML is generated properly from a command"""
# -- 0 --
# Create test command
# Test command
command_test = self.Command.create(
{
"name": "Test YAML",
"reference": "test_yaml_in_tests",
"action": "ssh_command",
"code": """cd /home/{{ tower.server.ssh_username }} \\
&& ls -lha""",
"note": """Test YAML command conversion.
Ensure all fields are rendered properly.""",
}
)
# -- 1 --
# Check it YAML generated by the command matches
# YAML from the template file
self.assertEqual(
command_test.yaml_code,
self.command_test_yaml,
"YAML generated from command doesn't match template file one",
)
# -- 2 --
# Check if YAML key values match Cetmix Tower ones
self.assertEqual(
command_test.access_level,
self.Command.TO_TOWER_ACCESS_LEVEL[
self.command_test_yaml_dict["access_level"]
],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.action,
self.command_test_yaml_dict["action"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.allow_parallel_run,
self.command_test_yaml_dict["allow_parallel_run"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.code,
self.command_test_yaml_dict["code"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.name,
self.command_test_yaml_dict["name"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.note,
self.command_test_yaml_dict["note"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.path,
self.command_test_yaml_dict["path"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.reference,
self.command_test_yaml_dict["reference"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.if_file_exists,
self.command_test_yaml_dict["if_file_exists"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command_test.disconnect_file,
self.command_test_yaml_dict["disconnect_file"],
"YAML value doesn't match Cetmix Tower one",
)
def test_command_from_yaml(self):
"""Test if YAML is generated properly from a command"""
def test_yaml(command):
"""Checks if yaml values are inserted correctly
Args:
command(cx.tower.command): _description_
"""
self.assertEqual(
command.access_level,
self.Command.TO_TOWER_ACCESS_LEVEL[
self.command_test_yaml_dict["access_level"]
],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.action,
self.command_test_yaml_dict["action"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.allow_parallel_run,
self.command_test_yaml_dict["allow_parallel_run"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.code,
self.command_test_yaml_dict["code"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.name,
self.command_test_yaml_dict["name"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.note,
self.command_test_yaml_dict["note"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.path,
self.command_test_yaml_dict["path"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.reference,
self.command_test_yaml_dict["reference"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.if_file_exists,
self.command_test_yaml_dict["if_file_exists"],
"YAML value doesn't match Cetmix Tower one",
)
self.assertEqual(
command.disconnect_file,
self.command_test_yaml_dict["disconnect_file"],
"YAML value doesn't match Cetmix Tower one",
)
# Create test command
command_test = self.Command.create(
{"name": "New Command", "action": "python_code"}
)
# -- 1 --
# Insert YAML into the command and
# check if YAML key values match Cetmix Tower ones
command_test.yaml_code = self.command_test_yaml
test_yaml(command_test)
# -- 2 --
# Insert some non supported keys and ensure nothing bad happens
yaml_with_non_supported_keys = """access_level: manager
action: ssh_command
doge: wow
memes: much nice!
allow_parallel_run: false
cetmix_tower_model: command
code: |-
cd /home/{{ tower.server.ssh_username }} \\
&& ls -lha
file_template_id: false
flight_plan_id: false
name: Test YAML
note: |-
Test YAML command conversion.
Ensure all fields are rendered properly.
path: false
reference: test_yaml_in_tests
tag_ids: false
"""
command_test.yaml_code = yaml_with_non_supported_keys
test_yaml(command_test)
# -- 3 --
# Insert non existing selection field value and exception is raised
yaml_with_non_supported_keys = """access_level: manager
action: non_existing_action
doge: wow
memes: much nice!
allow_parallel_run: false
cetmix_tower_model: command
code: |-
cd /home/{{ tower.server.ssh_username }} \\
&& ls -lha
file_template_id: false
flight_plan_id: false
name: Test YAML
note: |-
Test YAML command conversion.
Ensure all fields are rendered properly.
path: false
reference: test_yaml_in_tests
tag_ids: false
"""
with self.assertRaises(ValidationError) as e:
command_test.yaml_code = yaml_with_non_supported_keys
self.assertIn("non_existing_action", str(e.exception))
self.assertEqual(
str(e),
"Wrong value for cx.tower.command.action: 'non_existing_action'",
"Exception message doesn't match",
)
def test_command_with_action_file_template(self):
"""Test command with 'File from template' action"""
yaml_with_reference = """cetmix_tower_model: command
access_level: manager
reference: such_much_test_command
name: Such Much Command
action: file_using_template
allow_parallel_run: false
note: Just a note
os_ids: false
tag_ids: false
path: false
file_template_id: my_custom_test_template
flight_plan_id: false
code: false
server_status: false
variable_ids: false
secret_ids: false
no_split_for_sudo: false
if_file_exists: skip
disconnect_file: false
"""
# Add file template
file_template = self.env["cx.tower.file.template"].create(
{
"name": "Such much demo",
"reference": "my_custom_test_template",
"file_name": "much_logs.txt",
"server_dir": "/var/log/my/files",
"source": "tower",
"file_type": "text",
"note": "Hey!",
"keep_when_deleted": False,
}
)
command_with_template = self.Command.create(
{
"name": "Such Much Command",
"reference": "such_much_test_command",
"action": "file_using_template",
"note": "Just a note",
"file_template_id": file_template.id,
}
)
# -- 1 --
# Check if final YAML composed correctly
self.assertEqual(
command_with_template.yaml_code,
yaml_with_reference,
"YAML is not composed correctly",
)
# -- 2 --
# Explode related record and check the YAML
yaml_with_reference_exploded = """cetmix_tower_model: command
access_level: manager
reference: such_much_test_command
name: Such Much Command
action: file_using_template
allow_parallel_run: false
note: Just a note
os_ids: false
tag_ids: false
path: false
file_template_id:
reference: my_custom_test_template
name: Such much demo
source: tower
file_type: text
server_dir: /var/log/my/files
file_name: much_logs.txt
keep_when_deleted: false
tag_ids: false
note: Hey!
code: false
variable_ids: false
secret_ids: false
flight_plan_id: false
code: false
server_status: false
variable_ids: false
secret_ids: false
no_split_for_sudo: false
if_file_exists: skip
disconnect_file: false
"""
command_with_template.invalidate_recordset(["yaml_code"])
self.assertEqual(
command_with_template.with_context(explode_related_record=True).yaml_code,
yaml_with_reference_exploded,
"YAML is not composed correctly",
)