mirror of
https://github.com/ansible/awx.git
synced 2024-10-30 05:25:29 +03:00
Start of group support.
This commit is contained in:
parent
2d3ff081c1
commit
3625039d47
@ -142,7 +142,7 @@ class PrimordialModel(models.Model):
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.name)
|
||||
return unicode("%s-%s"% (self.name, self.id))
|
||||
|
||||
@classmethod
|
||||
def can_user_administrate(cls, user, obj):
|
||||
@ -284,6 +284,7 @@ class Inventory(CommonModel):
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
verbose_name_plural = _('inventories')
|
||||
unique_together = (("name", "organization"),)
|
||||
|
||||
organization = models.ForeignKey(Organization, null=False, related_name='inventories')
|
||||
|
||||
@ -291,12 +292,6 @@ class Inventory(CommonModel):
|
||||
import lib.urls
|
||||
return reverse(lib.urls.views_InventoryDetail, args=(self.pk,))
|
||||
|
||||
def __unicode__(self):
|
||||
if self.organization:
|
||||
return u'%s (%s)' % (self.name, self.organization)
|
||||
else:
|
||||
return self.name
|
||||
|
||||
@classmethod
|
||||
def _has_permission_types(cls, user, obj, allowed):
|
||||
if user.is_superuser:
|
||||
@ -370,6 +365,7 @@ class Host(CommonModelNameNotUnique):
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
unique_together = (("name", "inventory"),)
|
||||
|
||||
inventory = models.ForeignKey('Inventory', null=False, related_name='hosts')
|
||||
|
||||
@ -395,6 +391,7 @@ class Group(CommonModelNameNotUnique):
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
unique_together = (("name", "inventory"),)
|
||||
|
||||
inventory = models.ForeignKey('Inventory', null=False, related_name='groups')
|
||||
parents = models.ManyToManyField('self', symmetrical=False, related_name='children', blank=True)
|
||||
@ -410,10 +407,14 @@ class Group(CommonModelNameNotUnique):
|
||||
inventory = Inventory.objects.get(pk=data['inventory'])
|
||||
return Inventory._has_permission_types(user, inventory, PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE)
|
||||
|
||||
def get_absolute_url(self):
|
||||
import lib.urls
|
||||
return reverse(lib.urls.views_GroupsDetail, args=(self.pk,))
|
||||
|
||||
# FIXME: audit nullables
|
||||
# FIXME: audit cascades
|
||||
|
||||
class VariableData(CommonModel):
|
||||
class VariableData(CommonModelNameNotUnique):
|
||||
'''
|
||||
A set of host or group variables
|
||||
'''
|
||||
@ -421,6 +422,7 @@ class VariableData(CommonModel):
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
verbose_name_plural = _('variable data')
|
||||
unique_together = (("host", "group"),)
|
||||
|
||||
host = models.ForeignKey('Host', null=True, default=None, blank=True, on_delete=SET_NULL, related_name='variable_data')
|
||||
group = models.ForeignKey('Group', null=True, default=None, blank=True, on_delete=SET_NULL, related_name='variable_data')
|
||||
@ -526,8 +528,16 @@ class Permission(CommonModelNameNotUnique):
|
||||
# the project parameter is not used when dealing with READ, WRITE, or ADMIN permissions.
|
||||
|
||||
permission_type = models.CharField(max_length=64, choices=PERMISSION_TYPE_CHOICES)
|
||||
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode("Permission(name=%s,ON(user=%s,team=%s),FOR(project=%s,inventory=%s,type=%s))" % (
|
||||
self.name,
|
||||
self.user,
|
||||
self.team,
|
||||
self.project,
|
||||
self.inventory,
|
||||
self.permission_type
|
||||
))
|
||||
|
||||
# TODO: other job types (later)
|
||||
|
||||
|
@ -129,13 +129,12 @@ class InventoryTest(BaseTest):
|
||||
new_host_b = dict(name='asdf1.example.com', inventory=inv.pk)
|
||||
new_host_c = dict(name='asdf2.example.com', inventory=inv.pk)
|
||||
new_host_d = dict(name='asdf3.example.com', inventory=inv.pk)
|
||||
# FIXME: should raise 400 not 201, look into required fields in rest_framework
|
||||
print hosts
|
||||
new_host_e = dict(name='asdf4.example.com', inventory=inv.pk)
|
||||
data0 = self.post(hosts, data=invalid, expect=400, auth=self.get_super_credentials())
|
||||
data0 = self.post(hosts, data=new_host_a, expect=201, auth=self.get_super_credentials())
|
||||
|
||||
# an org admin can add hosts
|
||||
data1 = self.post(hosts, data=new_host_a, expect=201, auth=self.get_normal_credentials())
|
||||
data1 = self.post(hosts, data=new_host_e, expect=201, auth=self.get_normal_credentials())
|
||||
|
||||
# a normal user cannot add hosts
|
||||
data2 = self.post(hosts, data=new_host_b, expect=403, auth=self.get_nobody_credentials())
|
||||
@ -143,24 +142,46 @@ class InventoryTest(BaseTest):
|
||||
# a normal user with inventory edit permissions (on any inventory) can create hosts
|
||||
edit_perm = Permission.objects.create(
|
||||
user = self.other_django_user,
|
||||
inventory = Inventory.objects.get(pk=1),
|
||||
inventory = Inventory.objects.get(pk=inv.pk),
|
||||
permission_type = PERM_INVENTORY_WRITE
|
||||
)
|
||||
data3 = self.post(hosts, data=new_host_c, expect=201, auth=self.get_other_credentials())
|
||||
|
||||
# hostnames must be unique -- posting a duplicate just returns the previous
|
||||
data4 = self.post(hosts, data=new_host_c, expect=200, auth=self.get_other_credentials())
|
||||
self.assertEqual(data1['id'], data4['id'])
|
||||
# hostnames must be unique inside an organization
|
||||
data4 = self.post(hosts, data=new_host_c, expect=400, auth=self.get_other_credentials())
|
||||
|
||||
# a super user can add groups
|
||||
###########################################
|
||||
# GROUPS
|
||||
|
||||
# an org admin can create groups
|
||||
invalid = dict(name='web1')
|
||||
new_group_a = dict(name='web2', inventory=inv.pk)
|
||||
new_group_b = dict(name='web3', inventory=inv.pk)
|
||||
new_group_c = dict(name='web4', inventory=inv.pk)
|
||||
new_group_d = dict(name='web5', inventory=inv.pk)
|
||||
new_group_e = dict(name='web6', inventory=inv.pk)
|
||||
data0 = self.post(groups, data=invalid, expect=400, auth=self.get_super_credentials())
|
||||
data0 = self.post(groups, data=new_group_a, expect=201, auth=self.get_super_credentials())
|
||||
|
||||
# a normal user cannot create groups
|
||||
# an org admin can add hosts
|
||||
data1 = self.post(groups, data=new_group_e, expect=201, auth=self.get_normal_credentials())
|
||||
|
||||
# a normal user with inventory edit permissions can create groups
|
||||
|
||||
# group names must be unique for each inventory record
|
||||
# a normal user cannot add hosts
|
||||
data2 = self.post(groups, data=new_group_b, expect=403, auth=self.get_nobody_credentials())
|
||||
|
||||
# a normal user with inventory edit permissions (on any inventory) can create hosts
|
||||
# already done!
|
||||
#edit_perm = Permission.objects.create(
|
||||
# user = self.other_django_user,
|
||||
# inventory = Inventory.objects.get(pk=inv.pk),
|
||||
# permission_type = PERM_INVENTORY_WRITE
|
||||
#)
|
||||
data3 = self.post(groups, data=new_group_c, expect=201, auth=self.get_other_credentials())
|
||||
|
||||
# hostnames must be unique inside an organization
|
||||
data4 = self.post(groups, data=new_group_c, expect=400, auth=self.get_other_credentials())
|
||||
|
||||
#################################################
|
||||
# HOSTS->inventories
|
||||
|
||||
# a super user can associate hosts with inventories
|
||||
|
||||
@ -170,13 +191,19 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# a normal user with edit permission on the inventory can associate hosts with inventories
|
||||
|
||||
##################################################
|
||||
# GROUPS->inventories
|
||||
|
||||
# a super user can associate groups with inventories
|
||||
|
||||
# an org admin can associate groups with inventories
|
||||
|
||||
# a normal user cannot associate hosts with inventories
|
||||
# a normal user cannot associate groups with inventories
|
||||
|
||||
# a normal user with edit permissions on the inventory can associate hosts with inventories
|
||||
# a normal user with edit permissions on the inventory can associate groups with inventories
|
||||
|
||||
###################################################
|
||||
# VARIABLES
|
||||
|
||||
# a super user can create variable objects
|
||||
|
||||
@ -186,6 +213,9 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# a normal user with at least one inventory edit permission can create variable objects
|
||||
|
||||
###################################################
|
||||
# VARIABLES -> GROUPS
|
||||
|
||||
# a super user can associate variable objects with groups
|
||||
|
||||
# an org admin can associate variable objects with groups
|
||||
@ -194,6 +224,9 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# a normal user with inventory edit permissions can associate variable objects with groups
|
||||
|
||||
####################################################
|
||||
# VARIABLES -> HOSTS
|
||||
|
||||
# a super user can associate variable objects with hosts
|
||||
|
||||
# an org admin can associate variable objects with hosts
|
||||
@ -202,6 +235,9 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# a normal user with inventory edit permissions can associate variable objects with hosts
|
||||
|
||||
####################################################
|
||||
# SUBGROUPS
|
||||
|
||||
# a super user can set subgroups
|
||||
|
||||
# an org admin can set subgroups
|
||||
@ -210,6 +246,9 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# a normal user with inventory edit permissions can associate subgroups
|
||||
|
||||
######################################################
|
||||
# GROUP ACCESS
|
||||
|
||||
# a super user can get a group record
|
||||
|
||||
# an org admin can get a group record
|
||||
@ -218,6 +257,9 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# a regular user cannot read any group records
|
||||
|
||||
########################################################
|
||||
# HOST ACCESS
|
||||
|
||||
# a super user can get a host record
|
||||
|
||||
# an org admin can get a host record
|
||||
@ -226,13 +268,19 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# a regular user cannot get a host record
|
||||
|
||||
#########################################################
|
||||
# GROUP VARIABLE ACCESS
|
||||
|
||||
# a super user can see the variables attached to a group
|
||||
|
||||
# a org admin can see the variables attached to a group
|
||||
|
||||
# a user who is on a team who has read permissions on an inventory can see the variables attached to a group
|
||||
|
||||
# a regular user cannot get a host record
|
||||
# a regular user cannot get a group variable record
|
||||
|
||||
#########################################################
|
||||
# HOST VARIABLE ACCESS
|
||||
|
||||
# a super user can see the variables attached to a host
|
||||
|
||||
@ -241,6 +289,9 @@ class InventoryTest(BaseTest):
|
||||
# a user who is on a team who has read permissions on an inventory can see the variables attached to a host
|
||||
|
||||
# a regular user cannot see variables attached to a host
|
||||
|
||||
#########################################################
|
||||
# GROUP CHILDREN ACCESS
|
||||
|
||||
# a super user can see the children attached to a group
|
||||
|
||||
@ -249,6 +300,9 @@ class InventoryTest(BaseTest):
|
||||
# a user who is on a team who has read permissions on an inventory can see the children attached to a group
|
||||
|
||||
# a regular user cannot see children attached to a group
|
||||
|
||||
#########################################################
|
||||
# VARIABLE RESOURCE ACCESS
|
||||
|
||||
# a super user can see a variable record
|
||||
|
||||
@ -257,6 +311,9 @@ class InventoryTest(BaseTest):
|
||||
# a user who is on a team who has read permissions on an inventory can see the variable record
|
||||
|
||||
# a regular user cannot see a variable record
|
||||
|
||||
#########################################################
|
||||
# SUPER USER DISASSOCIATION
|
||||
|
||||
# a super user can disassociate...
|
||||
|
||||
@ -267,6 +324,9 @@ class InventoryTest(BaseTest):
|
||||
# subgroups from groups
|
||||
|
||||
# the inventory task code returns valid inventory JSON.
|
||||
|
||||
#########################################################
|
||||
# ORG ADMIN DISASSOCIATION
|
||||
|
||||
# an org admin user can disassociate...
|
||||
|
||||
@ -276,6 +336,9 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# subgroups from groups
|
||||
|
||||
#########################################################
|
||||
# USER DISASSOCIATION
|
||||
|
||||
# a user with inventory edit permission disassociate...
|
||||
|
||||
# hosts from inventory
|
||||
@ -283,6 +346,9 @@ class InventoryTest(BaseTest):
|
||||
# groups from inventory
|
||||
|
||||
# subgroups from groups
|
||||
|
||||
#########################################################
|
||||
# USER DISASSOCIATION (2)
|
||||
|
||||
# a regular user cannot disassociate....
|
||||
|
||||
@ -292,6 +358,9 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# subgroups from inventory
|
||||
|
||||
#########################################################
|
||||
# TAGS
|
||||
|
||||
# the following objects can be tagged
|
||||
|
||||
# inventory
|
||||
@ -322,6 +391,9 @@ class InventoryTest(BaseTest):
|
||||
|
||||
# variable records
|
||||
|
||||
#########################################################
|
||||
# RELATED FIELDS
|
||||
|
||||
# on an inventory resource, I can see related resources for hosts and groups and permissions
|
||||
# and these work
|
||||
|
||||
|
@ -315,4 +315,37 @@ class HostsDetail(BaseDetail):
|
||||
serializer_class = HostSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
|
||||
class GroupsList(BaseList):
|
||||
|
||||
model = Group
|
||||
serializer_class = GroupSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
|
||||
def _get_queryset(self):
|
||||
'''
|
||||
I can see groups when:
|
||||
I'm a superuser,
|
||||
or an organization admin of an inventory they are in
|
||||
or when I have allowing read permissions via a user or team on an inventory they are in
|
||||
'''
|
||||
base = Groups.objects
|
||||
if self.request.user.is_superuser:
|
||||
return base.all()
|
||||
admin_of = base.filter(inventory__organization__admins__in = [ self.request.user ]).distinct()
|
||||
has_user_perms = base.filter(
|
||||
inventory__permissions__user__in = [ self.request.user ],
|
||||
inventory__permissions__permission_type__in = PERMISSION_TYPES_ALLOWING_INVENTORY_READ,
|
||||
).distinct()
|
||||
has_team_perms = base.filter(
|
||||
inventory__permissions__team__in = self.request.user.teams.all(),
|
||||
inventory__permissions__permission_type__in = PERMISSION_TYPES_ALLOWING_INVENTORY_READ,
|
||||
).distinct()
|
||||
return admin_of | has_user_perms | has_team_perms
|
||||
|
||||
class GroupsDetail(BaseDetail):
|
||||
|
||||
model = Group
|
||||
serializer_class = GroupSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
|
||||
|
||||
|
@ -48,6 +48,8 @@ views_InventoryList = views.InventoryList.as_view()
|
||||
views_InventoryDetail = views.InventoryDetail.as_view()
|
||||
|
||||
# group service
|
||||
views_GroupsList = views.GroupsList.as_view()
|
||||
views_GroupsDetail = views.GroupsDetail.as_view()
|
||||
|
||||
# host service
|
||||
views_HostsList = views.HostsList.as_view()
|
||||
@ -99,6 +101,8 @@ urlpatterns = patterns('',
|
||||
url(r'^api/v1/hosts/(?P<pk>[0-9]+)/$', views_HostsDetail),
|
||||
|
||||
# group service
|
||||
url(r'^api/v1/groups/$', views_GroupsList),
|
||||
url(r'^api/v1/groups/(?P<pk>[0-9]+)/$', views_GroupsDetail),
|
||||
|
||||
# inventory variable service
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user