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