mirror of
https://github.com/ansible/awx.git
synced 2026-01-12 10:30:03 -03:30
Include Tower configurations into activity stream
Relates #7386 of ansible-tower. Due to the uniqueness of Tower configuration datastore model, it is not fully compatible with activity stream workflow. This PR introduced setting field for activitystream model along with other changes to make Tower configuration a special case for activity streams. Signed-off-by: Aaron Tan <jangsutsr@gmail.com>
This commit is contained in:
parent
4fd190e4c8
commit
a11e33458f
@ -3797,6 +3797,11 @@ class ActivityStreamSerializer(BaseSerializer):
|
||||
|
||||
if fk == 'schedule':
|
||||
rel['unified_job_template'] = thisItem.unified_job_template.get_absolute_url(self.context.get('request'))
|
||||
if obj.setting and obj.setting.get('category', None):
|
||||
rel['setting'] = self.reverse(
|
||||
'api:setting_singleton_detail',
|
||||
kwargs={'category_slug': obj.setting['category']}
|
||||
)
|
||||
return rel
|
||||
|
||||
def _get_rel(self, obj, fk):
|
||||
@ -3848,6 +3853,8 @@ class ActivityStreamSerializer(BaseSerializer):
|
||||
username = obj.actor.username,
|
||||
first_name = obj.actor.first_name,
|
||||
last_name = obj.actor.last_name)
|
||||
if obj.setting:
|
||||
summary_fields['setting'] = [obj.setting]
|
||||
return summary_fields
|
||||
|
||||
|
||||
|
||||
@ -120,6 +120,9 @@ class SettingsRegistry(object):
|
||||
def is_setting_read_only(self, setting):
|
||||
return bool(self._registry.get(setting, {}).get('read_only', False))
|
||||
|
||||
def get_setting_category(self, setting):
|
||||
return self._registry.get(setting, {}).get('category_slug', None)
|
||||
|
||||
def get_setting_field(self, setting, mixin_class=None, for_user=False, **kwargs):
|
||||
from rest_framework.fields import empty
|
||||
field_kwargs = {}
|
||||
|
||||
@ -9,7 +9,10 @@ import shutil
|
||||
# RedBaron
|
||||
from redbaron import RedBaron, indent
|
||||
|
||||
__all__ = ['comment_assignments']
|
||||
# AWX
|
||||
from awx.conf.registry import settings_registry
|
||||
|
||||
__all__ = ['comment_assignments', 'conf_to_dict']
|
||||
|
||||
|
||||
def comment_assignments(patterns, assignment_names, dry_run=True, backup_suffix='.old'):
|
||||
@ -103,6 +106,13 @@ def comment_assignments_in_file(filename, assignment_names, dry_run=True, backup
|
||||
return '\n'.join(diff_lines)
|
||||
|
||||
|
||||
def conf_to_dict(obj):
|
||||
return {
|
||||
'category': settings_registry.get_setting_category(obj.key),
|
||||
'name': obj.key,
|
||||
}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pattern = os.path.join(os.path.dirname(__file__), '..', 'settings', 'local_*.py')
|
||||
diffs = comment_assignments(pattern, ['AUTH_LDAP_ORGANIZATION_MAP'])
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
import awx.main.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0009_v322_add_support_for_ovirt4_inventory'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='activitystream',
|
||||
name='setting',
|
||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
||||
),
|
||||
]
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
# Tower
|
||||
from awx.api.versioning import reverse
|
||||
from awx.main.fields import JSONField
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
@ -66,6 +67,8 @@ class ActivityStream(models.Model):
|
||||
role = models.ManyToManyField("Role", blank=True)
|
||||
instance_group = models.ManyToManyField("InstanceGroup", blank=True)
|
||||
|
||||
setting = JSONField(blank=True)
|
||||
|
||||
def get_absolute_url(self, request=None):
|
||||
return reverse('api:activity_stream_detail', kwargs={'pk': self.pk}, request=request)
|
||||
|
||||
|
||||
@ -26,6 +26,8 @@ from awx.main.fields import is_implicit_parent
|
||||
|
||||
from awx.main.consumers import emit_channel_notification
|
||||
|
||||
from awx.conf.utils import conf_to_dict
|
||||
|
||||
__all__ = []
|
||||
|
||||
logger = logging.getLogger('awx.main.signals')
|
||||
@ -402,12 +404,15 @@ def activity_stream_create(sender, instance, created, **kwargs):
|
||||
object1=object1,
|
||||
changes=json.dumps(changes),
|
||||
actor=get_current_user_or_none())
|
||||
activity_entry.save()
|
||||
#TODO: Weird situation where cascade SETNULL doesn't work
|
||||
# it might actually be a good idea to remove all of these FK references since
|
||||
# we don't really use them anyway.
|
||||
if instance._meta.model_name != 'setting': # Is not conf.Setting instance
|
||||
activity_entry.save()
|
||||
getattr(activity_entry, object1).add(instance)
|
||||
else:
|
||||
activity_entry.setting = conf_to_dict(instance)
|
||||
activity_entry.save()
|
||||
|
||||
|
||||
def activity_stream_update(sender, instance, **kwargs):
|
||||
@ -433,9 +438,12 @@ def activity_stream_update(sender, instance, **kwargs):
|
||||
object1=object1,
|
||||
changes=json.dumps(changes),
|
||||
actor=get_current_user_or_none())
|
||||
activity_entry.save()
|
||||
if instance._meta.model_name != 'setting': # Is not conf.Setting instance
|
||||
activity_entry.save()
|
||||
getattr(activity_entry, object1).add(instance)
|
||||
else:
|
||||
activity_entry.setting = conf_to_dict(instance)
|
||||
activity_entry.save()
|
||||
|
||||
|
||||
def activity_stream_delete(sender, instance, **kwargs):
|
||||
|
||||
@ -5,6 +5,7 @@ from awx.api.versioning import reverse
|
||||
from awx.main.middleware import ActivityStreamMiddleware
|
||||
from awx.main.models.activity_stream import ActivityStream
|
||||
from awx.main.access import ActivityStreamAccess
|
||||
from awx.conf.models import Setting
|
||||
|
||||
|
||||
def mock_feature_enabled(feature):
|
||||
@ -47,6 +48,26 @@ def test_basic_fields(monkeypatch, organization, get, user, settings):
|
||||
assert response.data['summary_fields']['organization'][0]['name'] == 'test-org'
|
||||
|
||||
|
||||
@mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled)
|
||||
@pytest.mark.django_db
|
||||
def test_ctint_activity_stream(monkeypatch, get, user, settings):
|
||||
Setting.objects.create(key="FOO", value="bar")
|
||||
settings.ACTIVITY_STREAM_ENABLED = True
|
||||
u = user('admin', True)
|
||||
activity_stream = ActivityStream.objects.filter(setting={'name': 'FOO', 'category': None}).latest('pk')
|
||||
activity_stream.actor = u
|
||||
activity_stream.save()
|
||||
|
||||
aspk = activity_stream.pk
|
||||
url = reverse('api:activity_stream_detail', kwargs={'pk': aspk})
|
||||
response = get(url, user('admin', True))
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'summary_fields' in response.data
|
||||
assert 'setting' in response.data['summary_fields']
|
||||
assert response.data['summary_fields']['setting'][0]['name'] == 'FOO'
|
||||
|
||||
|
||||
@mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled)
|
||||
@pytest.mark.django_db
|
||||
def test_middleware_actor_added(monkeypatch, post, get, user, settings):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user