Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.4.1 #758

Merged
merged 6 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# 2.4.1 2023-12-18

## Fix

- Fix duplicate fields after sync AWX
- Fix requirement for k8s deployment

# 2.4.0 2023-12-15

⚠ Please do not use this version, as the survey fields may be duplicated during AWX sync.
This error is fixed in the 2.4.1 version and a database cleanup is performed during migration.

## Breaking changes ⚠

- Rename "NEED INFO" state into "ON HOLD", related urls changed
Expand Down
2 changes: 1 addition & 1 deletion Squest/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = "2.4.0"
__version__ = "2.4.1"
VERSION = __version__
5 changes: 5 additions & 0 deletions docs/configuration/squest_settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,13 @@ Comma separated list of allowed FQDN. Refer to the complete [documentation](http

**Default:** `http://127.0.0.1:8080,http://localhost:8080`

Comma separated list of trusted origin.
Refer to the complete [documentation](https://docs.djangoproject.com/en/4.2/ref/settings/#csrf-trusted-origins).

!!! note

If you deploy with `http://1.2.3.4:8080`, please add `CSRF_TRUSTED_ORIGINS=http://127.0.0.1:8080,http://localhost:8080,http://1.2.3.4:8080` in your variables.

### CELERY_BROKER_URL

**Default:** `amqp://rabbitmq:rabbitmq@localhost:5672/squest`
Expand Down
2 changes: 1 addition & 1 deletion k8s/requirements.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
collections:
- name: kubernetes.core
version: 2.3.2
version: 2.4.0
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "squest"
version = "2.4.0"
version = "2.4.1"
description = "Service catalog on top of Red Hat Ansible Automation Platform(RHAAP)/AWX (formerly known as Ansible Tower)"
authors = ["Nicolas Marcq <[email protected]>", "Elias Boulharts <[email protected]", "Anthony Belhadj <[email protected]>"]
license = "MIT"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 4.2.6 on 2023-12-18 10:18

from django.db import migrations

def clean_tower_survey_fields(apps, schema_editor):
Operation = apps.get_model("service_catalog", "Operation")
for operation in Operation.objects.all():
if operation.tower_survey_fields.filter(position=0).count() > 1:
operation.tower_survey_fields.exclude(position=0).delete()

class Migration(migrations.Migration):

dependencies = [
('service_catalog', '0039_alter_request_options_alter_request_state_and_more'),
]

operations = [
migrations.RunPython(clean_tower_survey_fields),
migrations.AlterUniqueTogether(
name='towersurveyfield',
unique_together={('operation', 'variable')},
),
migrations.AlterModelOptions(
name='towersurveyfield',
options={'default_permissions': ('add', 'change', 'delete', 'view', 'list'), 'ordering': ('position',)},
),
]
2 changes: 1 addition & 1 deletion service_catalog/models/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ def update_survey(self):
for field in spec_list:
squest_field, created = TowerSurveyField.objects.get_or_create(
variable=field['variable'],
position=position,
operation=self,
defaults={
'is_customer_field': True,
'position': position,
'name': field['question_name'],
'description': field['question_description'],
'type': field['type'],
Expand Down
3 changes: 2 additions & 1 deletion service_catalog/models/tower_survey_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def __init__(self, quota=None, *args, **kwargs):

class TowerSurveyField(SquestModel):
class Meta(SquestModel.Meta):
unique_together = ('operation', 'position', 'variable',)
unique_together = ('operation', 'variable')
ordering = ('position',)

variable = CharField(null=False, blank=False, max_length=200)
position = IntegerField(default=0)
Expand Down
52 changes: 45 additions & 7 deletions tests/test_service_catalog/test_models/test_operations.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
from service_catalog.models import Operation
from copy import deepcopy

from service_catalog.models import Operation, OperationType
from tests.test_service_catalog.base import BaseTest


class TestOperation(BaseTest):

def assertSurveyIsValid(self):
self.job_template_test.refresh_from_db()
position = 0
for field in self.job_template_test.survey["spec"]:
self.assertTrue(
self.new_operation.tower_survey_fields.filter(variable=field["variable"],
is_customer_field=True, position=position).exists())
position += 1
self.assertEqual(len(self.job_template_test.survey["spec"]), self.new_operation.tower_survey_fields.count())

def setUp(self):
super(TestOperation, self).setUp()
self.new_operation = Operation.objects.create(name="new test",
type=OperationType.UPDATE,
service=self.service_test,
job_template=self.job_template_test,
process_timeout_second=20)

def test_survey_from_job_template_is_copied_on_create(self):
new_operation = Operation.objects.create(name="new test",
service=self.service_test,
job_template=self.job_template_test,
process_timeout_second=20)
for field in self.job_template_test.survey["spec"]:
self.assertTrue(new_operation.tower_survey_fields.filter(variable=field["variable"], is_customer_field=True).exists())
self.assertSurveyIsValid()

def test_service_is_disabled_when_the_create_operation_disabled(self):
self.assertTrue(self.create_operation_test.service.enabled)
Expand All @@ -22,3 +34,29 @@ def test_service_is_disabled_when_the_create_operation_disabled(self):
self.create_operation_test.save()
self.assertFalse(self.create_operation_test.service.enabled)
self.assertFalse(self.create_operation_test.enabled)

def test_update_survey_when_position_is_default(self):
self.new_operation.tower_survey_fields.update(position=0)
self.assertFalse(self.new_operation.tower_survey_fields.exclude(position=0).exists())
self.new_operation.update_survey()
self.assertSurveyIsValid()

def test_update_survey_when_field_is_removed_from_awx(self):
previous_count = len(self.job_template_test.survey["spec"])
self.job_template_test.survey["spec"].pop(1)
self.job_template_test.save()
current_count = len(self.job_template_test.survey["spec"])
self.assertEqual(previous_count - 1, current_count)
self.new_operation.update_survey()
self.assertSurveyIsValid()

def test_update_survey_when_field_is_added_from_awx(self):
previous_count = len(self.job_template_test.survey["spec"])
tmp = deepcopy(self.job_template_test.survey["spec"][1])
self.job_template_test.survey["spec"][1]["variable"] = "test_swapped"
self.job_template_test.survey["spec"].append(tmp)
self.job_template_test.save()
current_count = len(self.job_template_test.survey["spec"])
self.assertEqual(previous_count + 1, current_count)
self.new_operation.update_survey()
self.assertSurveyIsValid()
Loading