mirror of
https://github.com/ansible/awx.git
synced 2026-01-12 10:30:03 -03:30
Initial implicit role / resource field additions into models
"Completes" #731 until we find out what I missed
This commit is contained in:
parent
68d8299689
commit
6dad0406b8
@ -45,7 +45,8 @@ class AutoOneToOneField(models.OneToOneField):
|
||||
|
||||
def resolve_field(obj, field):
|
||||
for f in field.split('.'):
|
||||
obj = getattr(obj, f)
|
||||
if obj:
|
||||
obj = getattr(obj, f)
|
||||
return obj
|
||||
|
||||
class ResourceFieldDescriptor(ReverseSingleRelatedObjectDescriptor):
|
||||
@ -61,7 +62,16 @@ class ResourceFieldDescriptor(ReverseSingleRelatedObjectDescriptor):
|
||||
return resource
|
||||
resource = Resource._default_manager.create()
|
||||
if self.parent_resource:
|
||||
resource.parent = resolve_field(instance, self.parent_resource)
|
||||
# Take first non null parent resource
|
||||
parent = None
|
||||
if type(self.parent_resource) is list:
|
||||
for path in self.parent_resource:
|
||||
parent = resolve_field(instance, path)
|
||||
if parent:
|
||||
break
|
||||
else:
|
||||
parent = resolve_field(instance, self.parent_resource)
|
||||
resource.parent = parent
|
||||
resource.save()
|
||||
setattr(instance, self.field.name, resource)
|
||||
instance.save(update_fields=[self.field.name,])
|
||||
@ -102,25 +112,43 @@ class ImplicitRoleDescriptor(ReverseSingleRelatedObjectDescriptor):
|
||||
|
||||
if not self.role_name:
|
||||
raise FieldError('Implicit role missing `role_name`')
|
||||
if not self.resource_field:
|
||||
raise FieldError('Implicit role missing `resource_field` specification')
|
||||
if not self.permissions:
|
||||
raise FieldError('Implicit role missing `permissions`')
|
||||
|
||||
role = Role._default_manager.create(name=self.role_name)
|
||||
role.save()
|
||||
if self.parent_role:
|
||||
role.parents.add(resolve_field(instance, self.parent_role))
|
||||
# Add all non-null parent roles as parents
|
||||
if type(self.parent_role) is list:
|
||||
for path in self.parent_role:
|
||||
parent = resolve_field(instance, path)
|
||||
if parent:
|
||||
role.parents.add(parent)
|
||||
else:
|
||||
parent = resolve_field(instance, self.parent_role)
|
||||
if parent:
|
||||
role.parents.add(parent)
|
||||
setattr(instance, self.field.name, role)
|
||||
instance.save(update_fields=[self.field.name,])
|
||||
|
||||
permissions = RolePermission(
|
||||
role=role,
|
||||
resource=getattr(instance, self.resource_field)
|
||||
)
|
||||
for k,v in self.permissions.items():
|
||||
setattr(permissions, k, v)
|
||||
permissions.save()
|
||||
if self.resource_field and self.permissions:
|
||||
permissions = RolePermission(
|
||||
role=role,
|
||||
resource=getattr(instance, self.resource_field)
|
||||
)
|
||||
|
||||
if 'all' in self.permissions and self.permissions['all']:
|
||||
del self.permissions['all']
|
||||
self.permissions['create'] = True
|
||||
self.permissions['read'] = True
|
||||
self.permissions['write'] = True
|
||||
self.permissions['update'] = True
|
||||
self.permissions['delete'] = True
|
||||
self.permissions['scm_update'] = True
|
||||
self.permissions['use'] = True
|
||||
self.permissions['execute'] = True
|
||||
|
||||
for k,v in self.permissions.items():
|
||||
setattr(permissions, k, v)
|
||||
permissions.save()
|
||||
|
||||
return role
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
# AWX
|
||||
from awx.main.fields import ImplicitResourceField, ImplicitRoleField
|
||||
from awx.main.constants import CLOUD_PROVIDERS
|
||||
from awx.main.utils import decrypt_field
|
||||
from awx.main.models.base import * # noqa
|
||||
@ -153,6 +154,27 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique):
|
||||
default='',
|
||||
help_text=_('Vault password (or "ASK" to prompt the user).'),
|
||||
)
|
||||
resource = ImplicitResourceField(
|
||||
parent_resource=[
|
||||
'user.resource',
|
||||
'team.resource'
|
||||
]
|
||||
)
|
||||
owner_role = ImplicitRoleField(
|
||||
role_name='Credential Owner',
|
||||
parent_role=[
|
||||
'user.user_role',
|
||||
'team.admin_role'
|
||||
],
|
||||
resource_field='resource',
|
||||
permissions = { 'all': True }
|
||||
)
|
||||
usage_role = ImplicitRoleField(
|
||||
role_name='Credential User',
|
||||
resource_field='resource',
|
||||
parent_role= 'team.member_role',
|
||||
permissions = { 'usage': True }
|
||||
)
|
||||
|
||||
@property
|
||||
def needs_ssh_password(self):
|
||||
|
||||
@ -18,7 +18,7 @@ from django.utils.timezone import now
|
||||
|
||||
# AWX
|
||||
from awx.main.constants import CLOUD_PROVIDERS
|
||||
from awx.main.fields import AutoOneToOneField
|
||||
from awx.main.fields import AutoOneToOneField, ImplicitResourceField, ImplicitRoleField
|
||||
from awx.main.managers import HostManager
|
||||
from awx.main.models.base import * # noqa
|
||||
from awx.main.models.jobs import Job
|
||||
@ -92,6 +92,21 @@ class Inventory(CommonModel):
|
||||
editable=False,
|
||||
help_text=_('Number of external inventory sources in this inventory with failures.'),
|
||||
)
|
||||
resource = ImplicitResourceField(
|
||||
parent_resource='organization.resource'
|
||||
)
|
||||
admin_role = ImplicitRoleField(
|
||||
role_name='Inventory Administrator',
|
||||
parent_role='organization.admin_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'all': True }
|
||||
)
|
||||
auditor_role = ImplicitRoleField(
|
||||
role_name='Inventory Auditor',
|
||||
parent_role='organization.auditor_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'read': True }
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('api:inventory_detail', args=(self.pk,))
|
||||
@ -523,6 +538,21 @@ class Group(CommonModelNameNotUnique):
|
||||
editable=False,
|
||||
help_text=_('Inventory source(s) that created or modified this group.'),
|
||||
)
|
||||
resource = ImplicitResourceField(
|
||||
parent_resource='inventory.resource'
|
||||
)
|
||||
admin_role = ImplicitRoleField(
|
||||
role_name='Inventory Group Administrator',
|
||||
parent_role='inventory.admin_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'all': True }
|
||||
)
|
||||
auditor_role = ImplicitRoleField(
|
||||
role_name='Inventory Group Auditor',
|
||||
parent_role='inventory.auditor_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'read': True }
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
@ -1093,6 +1123,30 @@ class InventorySource(UnifiedJobTemplate, InventorySourceOptions):
|
||||
update_cache_timeout = models.PositiveIntegerField(
|
||||
default=0,
|
||||
)
|
||||
resource = ImplicitResourceField(
|
||||
parent_resource=[
|
||||
'group.resource',
|
||||
'inventory.resource'
|
||||
]
|
||||
)
|
||||
admin_role = ImplicitRoleField(
|
||||
role_name='Inventory Group Administrator',
|
||||
parent_role=[
|
||||
'group.admin_role',
|
||||
'inventory.admin_role',
|
||||
],
|
||||
resource_field='resource',
|
||||
permissions = { 'all': True }
|
||||
)
|
||||
auditor_role = ImplicitRoleField(
|
||||
role_name='Inventory Group Auditor',
|
||||
parent_role=[
|
||||
'group.auditor_role',
|
||||
'inventory.auditor_role',
|
||||
],
|
||||
resource_field='resource',
|
||||
permissions = { 'read': True }
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _get_unified_job_class(cls):
|
||||
|
||||
@ -26,6 +26,7 @@ from awx.main.utils import decrypt_field, ignore_inventory_computed_fields
|
||||
from awx.main.utils import emit_websocket_notification
|
||||
from awx.main.redact import PlainTextCleaner
|
||||
from awx.main.conf import tower_settings
|
||||
from awx.main.fields import ImplicitResourceField, ImplicitRoleField
|
||||
|
||||
logger = logging.getLogger('awx.main.models.jobs')
|
||||
|
||||
@ -178,6 +179,25 @@ class JobTemplate(UnifiedJobTemplate, JobOptions):
|
||||
blank=True,
|
||||
default={},
|
||||
)
|
||||
resource = ImplicitResourceField()
|
||||
admin_role = ImplicitRoleField(
|
||||
role_name='Job Template Administrator',
|
||||
parent_role='project.admin_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'all': True }
|
||||
)
|
||||
auditor_role = ImplicitRoleField(
|
||||
role_name='Job Template Auditor',
|
||||
parent_role='project.auditor_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'read': True }
|
||||
)
|
||||
executor_role = ImplicitRoleField(
|
||||
role_name='Job Template Executor',
|
||||
parent_role='project.auditor_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'execute': True }
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _get_unified_job_class(cls):
|
||||
|
||||
@ -16,7 +16,7 @@ from django.utils.timezone import now as tz_now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# AWX
|
||||
from awx.main.fields import AutoOneToOneField
|
||||
from awx.main.fields import AutoOneToOneField, ImplicitResourceField, ImplicitRoleField
|
||||
from awx.main.models.base import * # noqa
|
||||
from awx.main.conf import tower_settings
|
||||
|
||||
@ -42,11 +42,27 @@ class Organization(CommonModel):
|
||||
blank=True,
|
||||
related_name='admin_of_organizations',
|
||||
)
|
||||
|
||||
# TODO: This field is deprecated. In 3.0 all projects will have exactly one
|
||||
# organization parent, the foreign key field representing that has been
|
||||
# moved to the Project model.
|
||||
projects = models.ManyToManyField(
|
||||
'Project',
|
||||
blank=True,
|
||||
related_name='organizations',
|
||||
)
|
||||
resource = ImplicitResourceField()
|
||||
admin_role = ImplicitRoleField(
|
||||
role_name='Organization Administrator',
|
||||
resource_field='resource',
|
||||
permissions = { 'all': True }
|
||||
)
|
||||
auditor_role = ImplicitRoleField(
|
||||
role_name='Organization Auditor',
|
||||
resource_field='resource',
|
||||
permissions = { 'read': True }
|
||||
)
|
||||
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('api:organization_detail', args=(self.pk,))
|
||||
@ -88,6 +104,23 @@ class Team(CommonModelNameNotUnique):
|
||||
blank=True,
|
||||
related_name='teams',
|
||||
)
|
||||
resource = ImplicitResourceField()
|
||||
admin_role = ImplicitRoleField(
|
||||
role_name='Team Administrator',
|
||||
parent_role='organization.admin_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'all': True }
|
||||
)
|
||||
auditor_role = ImplicitRoleField(
|
||||
role_name='Team Auditor',
|
||||
parent_role='organization.auditor_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'read': True }
|
||||
)
|
||||
member_role = ImplicitRoleField(
|
||||
role_name='Team Member',
|
||||
parent_role='admin_role',
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('api:team_detail', args=(self.pk,))
|
||||
@ -103,6 +136,10 @@ class Team(CommonModelNameNotUnique):
|
||||
class Permission(CommonModelNameNotUnique):
|
||||
'''
|
||||
A permission allows a user, project, or team to be able to use an inventory source.
|
||||
|
||||
NOTE: This class is deprecated, permissions and access is to be handled by
|
||||
our new RBAC system. This class should be able to be safely removed after a 3.0.0
|
||||
migration. - anoek 2016-01-28
|
||||
'''
|
||||
|
||||
class Meta:
|
||||
|
||||
@ -22,6 +22,7 @@ from awx.main.models.base import * # noqa
|
||||
from awx.main.models.jobs import Job
|
||||
from awx.main.models.unified_jobs import * # noqa
|
||||
from awx.main.utils import update_scm_url
|
||||
from awx.main.fields import ImplicitResourceField, ImplicitRoleField
|
||||
|
||||
__all__ = ['Project', 'ProjectUpdate']
|
||||
|
||||
@ -194,6 +195,14 @@ class Project(UnifiedJobTemplate, ProjectOptions):
|
||||
app_label = 'main'
|
||||
ordering = ('id',)
|
||||
|
||||
organization = models.ForeignKey(
|
||||
'Organization',
|
||||
blank=False,
|
||||
null=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='project_list', # TODO: this should eventually be refactored
|
||||
# back to 'projects' - anoek 2016-01-28
|
||||
)
|
||||
scm_delete_on_next_update = models.BooleanField(
|
||||
default=False,
|
||||
editable=False,
|
||||
@ -205,6 +214,31 @@ class Project(UnifiedJobTemplate, ProjectOptions):
|
||||
default=0,
|
||||
blank=True,
|
||||
)
|
||||
resource = ImplicitResourceField()
|
||||
admin_role = ImplicitRoleField(
|
||||
role_name='Project Administrator',
|
||||
parent_role='organization.admin_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'all': True }
|
||||
)
|
||||
auditor_role = ImplicitRoleField(
|
||||
role_name='Project Auditor',
|
||||
parent_role='organization.auditor_role',
|
||||
resource_field='resource',
|
||||
permissions = { 'read': True }
|
||||
)
|
||||
member_role = ImplicitRoleField(
|
||||
role_name='Project Member',
|
||||
parent_role='admin',
|
||||
resource_field='resource',
|
||||
permissions = { 'usage': True }
|
||||
)
|
||||
scm_update_role = ImplicitRoleField(
|
||||
role_name='Project Updater',
|
||||
parent_role='admin',
|
||||
resource_field='resource',
|
||||
permissions = { 'scm_update': True }
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _get_unified_job_class(cls):
|
||||
|
||||
@ -11,7 +11,6 @@ from django.db.models.signals import pre_save, post_save, pre_delete, post_delet
|
||||
|
||||
# AWX
|
||||
from awx.main.models.base import * # noqa
|
||||
from awx.main.fields import * # noqa
|
||||
|
||||
__all__ = ['Role', 'RolePermission', 'Resource', 'RoleHierarchy', 'ResourceHierarchy']
|
||||
|
||||
@ -158,6 +157,8 @@ class RolePermission(CreatedModifiedModel):
|
||||
write = models.IntegerField(default = 0)
|
||||
update = models.IntegerField(default = 0)
|
||||
delete = models.IntegerField(default = 0)
|
||||
execute = models.IntegerField(default = 0)
|
||||
scm_update = models.IntegerField(default = 0)
|
||||
use = models.IntegerField(default = 0)
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user