Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
itminedu
synnefo
Commits
7ee2acd3
Commit
7ee2acd3
authored
Sep 19, 2013
by
Giorgos Korfiatis
Browse files
astakos: Add command project-modify
Add a management command that directly modifies an initialized project.
parent
d8075556
Changes
4
Hide whitespace changes
Inline
Side-by-side
snf-astakos-app/astakos/im/functions.py
View file @
7ee2acd3
...
...
@@ -721,6 +721,76 @@ def enable_base_project(user):
quotas
.
qh_sync_project
(
project
)
MODIFY_KEYS_MAIN
=
[
"owner"
,
"realname"
,
"homepage"
,
"description"
]
MODIFY_KEYS_EXTRA
=
[
"end_date"
,
"member_join_policy"
,
"member_leave_policy"
,
"limit_on_members_number"
,
"private"
]
MODIFY_KEYS
=
MODIFY_KEYS_MAIN
+
MODIFY_KEYS_EXTRA
def
modifies_main_fields
(
request
):
return
set
(
request
.
keys
()).
intersection
(
MODIFY_KEYS_MAIN
)
def
modify_project
(
project_id
,
request
):
project
=
get_project_for_update
(
project_id
)
if
project
.
state
not
in
Project
.
INITIALIZED_STATES
:
m
=
_
(
astakos_messages
.
UNINITIALIZED_NO_MODIFY
)
%
project
.
uuid
raise
ProjectConflict
(
m
)
if
project
.
is_base
:
main_fields
=
modifies_main_fields
(
request
)
if
main_fields
:
m
=
(
_
(
astakos_messages
.
BASE_NO_MODIFY_FIELDS
)
%
", "
.
join
(
map
(
str
,
main_fields
)))
raise
ProjectBadRequest
(
m
)
new_name
=
request
.
get
(
"realname"
)
if
new_name
is
not
None
and
project
.
is_alive
:
check_conflicting_projects
(
project
,
new_name
)
project
.
realname
=
new_name
project
.
name
=
new_name
project
.
save
()
_modify_projects
(
Project
.
objects
.
filter
(
id
=
project
.
id
),
request
)
def
modify_projects_in_bulk
(
flt
,
request
):
main_fields
=
modifies_main_fields
(
request
)
if
main_fields
:
raise
ProjectBadRequest
(
"Cannot modify field(s) '%s' in bulk"
%
", "
.
join
(
map
(
str
,
main_fields
)))
projects
=
Project
.
objects
.
initialized
(
flt
).
select_for_update
()
_modify_projects
(
projects
,
request
)
def
_modify_projects
(
projects
,
request
):
upds
=
{}
for
key
in
MODIFY_KEYS
:
value
=
request
.
get
(
key
)
if
value
is
not
None
:
upds
[
key
]
=
value
projects
.
update
(
**
upds
)
changed_resources
=
set
()
pquotas
=
[]
req_policies
=
request
.
get
(
"resources"
,
{})
req_policies
=
validate_resource_policies
(
req_policies
,
admin
=
True
)
for
project
in
projects
:
for
resource
,
m_capacity
,
p_capacity
in
req_policies
:
changed_resources
.
add
(
resource
)
pquotas
.
append
(
ProjectResourceQuota
(
project
=
project
,
resource
=
resource
,
member_capacity
=
m_capacity
,
project_capacity
=
p_capacity
))
ProjectResourceQuota
.
objects
.
\
filter
(
project__in
=
projects
,
resource__in
=
changed_resources
).
delete
()
ProjectResourceQuota
.
objects
.
bulk_create
(
pquotas
)
quotas
.
qh_sync_projects
(
projects
)
def
submit_application
(
owner
=
None
,
name
=
None
,
project_id
=
None
,
...
...
@@ -798,13 +868,15 @@ def submit_application(owner=None,
return
application
def
validate_resource_policies
(
policies
):
def
validate_resource_policies
(
policies
,
admin
=
False
):
if
not
isinstance
(
policies
,
dict
):
raise
ProjectBadRequest
(
"Malformed resource policies"
)
resource_names
=
policies
.
keys
()
resources
=
Resource
.
objects
.
filter
(
name__in
=
resource_names
,
api_visible
=
True
)
resources
=
Resource
.
objects
.
filter
(
name__in
=
resource_names
)
if
not
admin
:
resources
=
resources
.
filter
(
api_visible
=
True
)
resource_d
=
{}
for
resource
in
resources
:
resource_d
[
resource
.
name
]
=
resource
...
...
snf-astakos-app/astakos/im/management/commands/project-modify.py
0 → 100644
View file @
7ee2acd3
# Copyright 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from
optparse
import
make_option
from
django.db.models
import
Q
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.db
import
transaction
from
synnefo.util
import
units
from
astakos.im
import
functions
from
astakos.im
import
models
import
astakos.api.projects
as
api
import
synnefo.util.date
as
date_util
from
snf_django.management
import
utils
from
astakos.im.management.commands
import
_common
def
make_policies
(
limits
):
policies
=
{}
for
(
name
,
member_capacity
,
project_capacity
)
in
limits
:
try
:
member_capacity
=
units
.
parse
(
member_capacity
)
project_capacity
=
units
.
parse
(
project_capacity
)
except
units
.
ParseError
:
m
=
"Please specify capacity as a decimal integer"
raise
CommandError
(
m
)
policies
[
name
]
=
{
"member_capacity"
:
member_capacity
,
"project_capacity"
:
project_capacity
}
return
policies
Simple
=
type
(
'Simple'
,
(),
{})
class
Param
(
object
):
def
__init__
(
self
,
key
=
Simple
,
mod
=
Simple
,
action
=
Simple
,
nargs
=
Simple
,
is_main
=
False
,
help
=
""
):
self
.
key
=
key
self
.
mod
=
mod
self
.
action
=
action
self
.
nargs
=
nargs
self
.
is_main
=
is_main
self
.
help
=
help
PARAMS
=
{
"name"
:
Param
(
key
=
"realname"
,
help
=
"Set project name"
),
"owner"
:
Param
(
mod
=
_common
.
get_accepted_user
,
help
=
"Set project owner"
),
"homepage"
:
Param
(
help
=
"Set project homepage"
),
"description"
:
Param
(
help
=
"Set project description"
),
"end_date"
:
Param
(
mod
=
date_util
.
isoparse
,
is_main
=
True
,
help
=
(
"Set project end date in ISO format "
"(e.g. 2014-01-01T00:00Z)"
)),
"join_policy"
:
Param
(
key
=
"member_join_policy"
,
is_main
=
True
,
mod
=
(
lambda
x
:
api
.
MEMBERSHIP_POLICY
[
x
]),
help
=
"Set join policy (auto, moderated, or closed)"
),
"leave_policy"
:
Param
(
key
=
"member_leave_policy"
,
is_main
=
True
,
mod
=
(
lambda
x
:
api
.
MEMBERSHIP_POLICY
[
x
]),
help
=
(
"Set leave policy "
"(auto, moderated, or closed)"
)),
"max_members"
:
Param
(
key
=
"limit_on_members_number"
,
mod
=
int
,
is_main
=
True
,
help
=
"Set maximum members limit"
),
"private"
:
Param
(
mod
=
utils
.
parse_bool
,
is_main
=
True
,
help
=
"Set project private"
),
"limit"
:
Param
(
key
=
"resources"
,
mod
=
make_policies
,
is_main
=
True
,
nargs
=
3
,
action
=
"append"
,
help
=
(
"Set resource limits: "
"resource_name member_capacity project_capacity"
)),
}
def
make_options
():
options
=
[]
for
key
,
param
in
PARAMS
.
iteritems
():
opt
=
"--"
+
key
.
replace
(
'_'
,
'-'
)
kwargs
=
{}
if
param
.
action
is
not
Simple
:
kwargs
[
"action"
]
=
param
.
action
if
param
.
nargs
is
not
Simple
:
kwargs
[
"nargs"
]
=
param
.
nargs
kwargs
[
"help"
]
=
param
.
help
options
.
append
(
make_option
(
opt
,
**
kwargs
))
return
tuple
(
options
)
class
Command
(
BaseCommand
):
args
=
"<project id> (or --all-base-projects)"
help
=
"Modify an already initialized project"
option_list
=
BaseCommand
.
option_list
+
make_options
()
+
(
make_option
(
'--all-base-projects'
,
action
=
'store_true'
,
default
=
False
,
help
=
"Modify in bulk all initialized base projects"
),
make_option
(
'--exclude'
,
help
=
(
"If `--all-base-projects' is given, exclude projects"
" given as a list of uuids: uuid1,uuid2,uuid3"
)),
)
def
check_args
(
self
,
args
,
all_base
,
exclude
):
if
all_base
and
args
or
not
all_base
and
len
(
args
)
!=
1
:
m
=
"Please provide a project ID or --all-base-projects"
raise
CommandError
(
m
)
if
not
all_base
and
exclude
:
m
=
(
"Option --exclude is meaningful only combined with "
" --all-base-projects."
)
raise
CommandError
(
m
)
def
mk_all_base_filter
(
self
,
all_base
,
exclude
):
flt
=
Q
(
state__in
=
models
.
Project
.
INITIALIZED_STATES
,
is_base
=
True
)
if
exclude
:
exclude
=
exclude
.
split
(
','
)
flt
&=
~
Q
(
uuid__in
=
exclude
)
return
flt
@
transaction
.
commit_on_success
def
handle
(
self
,
*
args
,
**
options
):
all_base
=
options
[
"all_base_projects"
]
exclude
=
options
[
"exclude"
]
self
.
check_args
(
args
,
all_base
,
exclude
)
try
:
changes
=
{}
for
key
,
value
in
options
.
iteritems
():
param
=
PARAMS
.
get
(
key
)
if
param
is
None
or
value
is
None
:
continue
if
all_base
and
not
param
.
is_main
:
m
=
"Cannot modify field '%s' in bulk"
%
key
raise
CommandError
(
m
)
k
=
key
if
param
.
key
is
Simple
else
param
.
key
v
=
value
if
param
.
mod
is
Simple
else
param
.
mod
(
value
)
changes
[
k
]
=
v
if
all_base
:
flt
=
self
.
mk_all_base_filter
(
all_base
,
exclude
)
functions
.
modify_projects_in_bulk
(
flt
,
changes
)
else
:
functions
.
modify_project
(
args
[
0
],
changes
)
except
BaseException
as
e
:
raise
CommandError
(
e
)
snf-astakos-app/astakos/im/messages.py
View file @
7ee2acd3
...
...
@@ -273,6 +273,8 @@ APPLICATION_CANNOT_CANCEL = "Cannot cancel application %s in state '%s'"
APPLICATION_CANCELLED
=
"Your project application has been cancelled."
REACHED_PENDING_APPLICATION_LIMIT
=
(
"You have reached the maximum number "
"of pending project applications: %s."
)
UNINITIALIZED_NO_MODIFY
=
"Cannot modify: project %s is not initialized."
BASE_NO_MODIFY_FIELDS
=
"Cannot modify field(s) '%s' of base projects."
PENDING_APPLICATION_LIMIT_ADD
=
\
(
"You are not allowed to create a new project "
...
...
snf-deploy/snfdeploy/components.py
View file @
7ee2acd3
...
...
@@ -658,18 +658,18 @@ class Astakos(SynnefoComponent):
]
def
modify_all_quota
(
self
):
cmd
=
"snf-manage
user
-modify
-f
--all
-
-base-
quota
"
return
[
"%s pithos.diskspace 40G"
%
cmd
,
"%s astakos.pending_app 2"
%
cmd
,
"%s cyclades.vm 4"
%
cmd
,
"%s cyclades.disk 40G"
%
cmd
,
"%s cyclades.total_ram 16G"
%
cmd
,
"%s cyclades.ram 8G"
%
cmd
,
"%s cyclades.total_cpu 32"
%
cmd
,
"%s cyclades.cpu 16"
%
cmd
,
"%s cyclades.network.private 4"
%
cmd
,
"%s cyclades.floating_ip 4"
%
cmd
,
cmd
=
"snf-manage
project
-modify --all-base-
projects --limit
"
return
[
"%s pithos.diskspace
40G
40G"
%
cmd
,
"%s astakos.pending_app
2
2"
%
cmd
,
"%s cyclades.vm
4
4"
%
cmd
,
"%s cyclades.disk
40G
40G"
%
cmd
,
"%s cyclades.total_ram
16G
16G"
%
cmd
,
"%s cyclades.ram
8G
8G"
%
cmd
,
"%s cyclades.total_cpu
32
32"
%
cmd
,
"%s cyclades.cpu
16
16"
%
cmd
,
"%s cyclades.network.private
4
4"
%
cmd
,
"%s cyclades.floating_ip
4
4"
%
cmd
,
]
def
get_services
(
self
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment