Commit 37220498 authored by Giorgos Korfiatis's avatar Giorgos Korfiatis

astakos: Identify projects with a uuid

Introduce field `uuid'; use it to refer to projects in the API and the
management commands.
parent 8312c9ee
......@@ -128,7 +128,7 @@ def get_applications_details(applications):
for application in applications:
d = {
"id": application.id,
"project": application.chain_id,
"project": application.chain.uuid,
"state": APPLICATION_STATE_SHOW[application.state],
"comments": application.comments,
}
......@@ -151,7 +151,7 @@ def get_projects_details(projects, request_user=None):
for project in projects:
application = project.application
d = {
"id": project.id,
"id": project.uuid,
"application": application.id,
"state": PROJECT_STATE_SHOW[project.overall_state()],
"creation_date": project.creation_date,
......@@ -189,7 +189,7 @@ def get_memberships_details(memberships, request_user):
d = {
"id": membership.id,
"user": membership.person.uuid,
"project": membership.project_id,
"project": membership.project.uuid,
"state": MEMBERSHIP_STATE_SHOW[membership.state],
"allowed_actions": allowed_actions,
}
......@@ -332,7 +332,7 @@ def get_project(request, project_id):
def _get_project(project_id, request_user=None):
project = functions.get_project_by_id(project_id)
project = functions.get_project_by_uuid(project_id)
functions.project_check_allowed(
project, request_user, level=functions.ANY_LEVEL)
return project
......@@ -447,7 +447,7 @@ def submit_application(app_data, user, project_id=None):
request_user=user)
result = {"application": application.id,
"id": application.chain_id
"id": application.chain.uuid,
}
return json_response(result, status_code=201)
......@@ -501,9 +501,7 @@ def applications(request):
def make_application_query(input_data):
project_id = input_data.get("project")
if project_id is not None:
if not isinstance(project_id, (int, long)):
raise faults.BadRequest("'project' must be integer")
return Q(chain=project_id)
return Q(chain__uuid=project_id)
return Q()
......@@ -585,9 +583,7 @@ def memberships(request):
def make_membership_query(input_data):
project_id = input_data.get("project")
if project_id is not None:
if not isinstance(project_id, (int, long)):
raise faults.BadRequest("'project' must be integer")
return Q(project=project_id)
return Q(project__uuid=project_id)
return Q()
......
......@@ -60,9 +60,6 @@ astakos_account_v1_0 += patterns(
astakos_account_v1_0 += patterns(
'astakos.api.projects',
url(r'^projects/?$', 'projects', name='api_projects'),
url(r'^projects/(?P<project_id>\d+)/?$', 'project', name='api_project'),
url(r'^projects/(?P<project_id>\d+)/action/?$', 'project_action',
name='api_project_action'),
url(r'^projects/apps/?$', 'applications', name='api_applications'),
url(r'^projects/apps/(?P<app_id>\d+)/?$', 'application',
name='api_application'),
......@@ -73,6 +70,9 @@ astakos_account_v1_0 += patterns(
name='api_membership'),
url(r'^projects/memberships/(?P<memb_id>\d+)/action/?$',
'membership_action', name='api_membership_action'),
url(r'^projects/(?P<project_id>[^/]+)/?$', 'project', name='api_project'),
url(r'^projects/(?P<project_id>[^/]+)/action/?$', 'project_action',
name='api_project_action'),
)
urlpatterns = patterns(
......
......@@ -43,7 +43,8 @@ from synnefo_branding.utils import render_to_string
from synnefo.lib import join_urls
from astakos.im.models import AstakosUser, Invitation, ProjectMembership, \
ProjectApplication, Project, new_chain, Resource, ProjectLock
ProjectApplication, Project, new_chain, Resource, ProjectLock, \
create_project
from astakos.im import quotas
from astakos.im import project_notif
from astakos.im import settings
......@@ -283,9 +284,21 @@ def get_project_by_id(project_id):
raise ProjectNotFound(m)
def get_project_by_uuid(uuid):
try:
return Project.objects.get(uuid=uuid)
except Project.DoesNotExist:
m = _(astakos_messages.UNKNOWN_PROJECT_ID) % uuid
raise ProjectNotFound(m)
def get_project_for_update(project_id):
try:
return Project.objects.select_for_update().get(id=project_id)
try:
project_id = int(project_id)
return Project.objects.select_for_update().get(id=project_id)
except ValueError:
return Project.objects.select_for_update().get(uuid=project_id)
except Project.DoesNotExist:
m = _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id
raise ProjectNotFound(m)
......@@ -385,7 +398,7 @@ def app_check_allowed(application, request_user,
def checkAlive(project):
if not project.is_alive:
m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.id
m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.uuid
raise ProjectConflict(m)
......@@ -513,7 +526,7 @@ def enroll_member(project_id, user, request_user=None, reason=None):
accept_membership_project_checks(project, request_user)
try:
membership = get_membership(project_id, user.id)
membership = get_membership(project.id, user.id)
if not membership.check_action("enroll"):
m = _(astakos_messages.MEMBERSHIP_ACCEPTED)
raise ProjectConflict(m)
......@@ -708,7 +721,7 @@ def submit_application(owner=None,
chain = new_chain()
application.chain_id = chain.chain
application.save()
Project.objects.create(id=chain.chain, application=application)
create_project(id=chain.chain, application=application)
else:
application.chain = project
application.save()
......@@ -826,7 +839,7 @@ def check_conflicting_projects(application):
if (conflicting_project != project):
m = (_("cannot approve: project with name '%s' "
"already exists (id: %s)") %
(new_project_name, conflicting_project.id))
(new_project_name, conflicting_project.uuid))
raise ProjectConflict(m) # invalid argument
except Project.DoesNotExist:
pass
......@@ -905,7 +918,7 @@ def unsuspend(project_id, request_user=None, reason=None):
project_check_allowed(project, request_user, level=ADMIN_LEVEL)
if not project.is_suspended:
m = _(astakos_messages.NOT_SUSPENDED_PROJECT) % project.id
m = _(astakos_messages.NOT_SUSPENDED_PROJECT) % project.uuid
raise ProjectConflict(m)
project.resume(actor=request_user, reason=reason)
......@@ -920,7 +933,7 @@ def reinstate(project_id, request_user=None, reason=None):
project_check_allowed(project, request_user, level=ADMIN_LEVEL)
if not project.is_terminated:
m = _(astakos_messages.NOT_TERMINATED_PROJECT) % project.id
m = _(astakos_messages.NOT_TERMINATED_PROJECT) % project.uuid
raise ProjectConflict(m)
check_conflicting_projects(project.application)
......
......@@ -128,8 +128,7 @@ class Command(SynnefoCommand):
if preds:
chains = filter_preds(preds, chains)
labels = ('ProjID', 'Name', 'Owner', 'Email', 'Status',
'Pending AppID')
labels = ('ProjID', 'Name', 'Owner', 'Status', 'Pending AppID')
info = chain_info(chains)
utils.pprint_table(self.stdout, info, labels,
......@@ -160,9 +159,8 @@ def chain_info(chains):
pending_appid = pending_app.id if pending_app is not None else ""
application = project.application
t = (project.pk,
t = (project.uuid,
application.name,
application.owner.realname,
application.owner.email,
status,
pending_appid,
......
......@@ -84,11 +84,6 @@ class Command(SynnefoCommand):
self.output_format = options['output_format']
id_ = args[0]
try:
id_ = int(id_)
except ValueError:
raise CommandError("id should be an integer value.")
if search_apps:
app = get_app(id_)
self.print_app(app)
......@@ -131,6 +126,10 @@ class Command(SynnefoCommand):
def get_app(app_id):
try:
app_id = int(app_id)
except ValueError:
raise CommandError("id should be an integer value.")
try:
return ProjectApplication.objects.get(id=app_id)
except ProjectApplication.DoesNotExist:
......@@ -139,7 +138,7 @@ def get_app(app_id):
def get_chain_state(project_id):
try:
chain = Project.objects.get(id=project_id)
chain = Project.objects.get(uuid=project_id)
return chain, chain.last_pending_application()
except Project.DoesNotExist:
raise CommandError("Project with id %s not found." % project_id)
......@@ -163,7 +162,7 @@ def app_fields(app):
mem_limit_show = mem_limit if mem_limit is not None else "unlimited"
d = OrderedDict([
('project id', app.chain_id),
('project id', app.chain.uuid),
('application id', app.id),
('name', app.name),
('status', app.state_display()),
......@@ -187,7 +186,7 @@ def project_fields(project, pending_app):
app = project.application
d = OrderedDict([
('project id', project.id),
('project id', project.uuid),
('application id', app.id),
('name', app.name),
('status', project.state_display()),
......
......@@ -161,7 +161,7 @@ def memberships(user):
for m in ms:
project = m.project
print_data.append((project.id,
print_data.append((project.uuid,
project.application.name,
m.state_display(),
))
......@@ -181,7 +181,7 @@ def chain_info(chains):
pending_appid = pending_app.id if pending_app is not None else ""
application = project.application
t = (project.pk,
t = (project.uuid,
application.name,
status,
pending_appid,
......
This diff is collapsed.
......@@ -1585,6 +1585,7 @@ class Project(models.Model):
state = models.IntegerField(default=NORMAL,
db_index=True)
uuid = models.CharField(max_length=255, unique=True)
objects = ProjectManager()
......@@ -1766,6 +1767,12 @@ class Project(models.Model):
return [m.person for m in self.approved_memberships]
def create_project(**kwargs):
if "uuid" not in kwargs:
kwargs["uuid"] = str(uuid.uuid4())
return Project.objects.create(**kwargs)
class ProjectLogManager(models.Manager):
def last_deactivations(self, projects):
logs = self.filter(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment