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
5b1f8225
Commit
5b1f8225
authored
Apr 08, 2013
by
Giorgos Korfiatis
Browse files
Cleanup obsolete quota code
parent
26416d10
Changes
4
Hide whitespace changes
Inline
Side-by-side
snf-astakos-app/astakos/im/endpoints/qh.py
deleted
100644 → 0
View file @
26416d10
# Copyright 2011, 2012, 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.
import
logging
import
itertools
from
functools
import
wraps
from
collections
import
namedtuple
from
django.utils.translation
import
ugettext
as
_
from
astakos.im.settings
import
(
QUOTAHOLDER_URL
,
QUOTAHOLDER_TOKEN
,
LOGGING_LEVEL
)
from
astakos.quotaholder.callpoint
import
QuotaholderDjangoDBCallpoint
from
synnefo.util.number
import
strbigdec
from
astakos.im.settings
import
QUOTAHOLDER_POOLSIZE
from
astakos.quotaholder.api
import
QH_PRACTICALLY_INFINITE
logger
=
logging
.
getLogger
(
__name__
)
inf
=
float
(
'inf'
)
clientkey
=
'astakos'
_client
=
None
def
get_client
():
global
_client
if
_client
:
return
_client
_client
=
QuotaholderDjangoDBCallpoint
()
return
_client
def
set_quota
(
payload
):
c
=
get_client
()
if
not
c
:
return
if
payload
==
[]:
return
[]
result
=
c
.
set_quota
(
context
=
{},
set_quota
=
payload
)
logger
.
debug
(
'set_quota: %s rejected: %s'
%
(
payload
,
result
))
return
result
def
quotas_per_user_from_get
(
lst
):
limits
=
{}
usage
=
{}
for
holder
,
resource
,
c
,
imp_min
,
imp_max
,
st_min
,
st_max
,
flags
in
lst
:
userlimits
=
limits
.
get
(
holder
,
{})
userlimits
[
resource
]
=
c
limits
[
holder
]
=
userlimits
user_usage
=
usage
.
get
(
holder
,
{})
user_usage
[
resource
]
=
imp_max
usage
[
holder
]
=
user_usage
return
limits
,
usage
def
qh_get_quota
(
users
,
resources
):
c
=
get_client
()
if
not
c
:
return
payload
=
[]
append
=
payload
.
append
for
user
in
users
:
for
resource
in
resources
:
append
((
user
.
uuid
,
str
(
resource
)),)
if
payload
==
[]:
return
[]
result
=
c
.
get_quota
(
context
=
{},
get_quota
=
payload
)
logger
.
debug
(
'get_quota: %s rejected: %s'
%
(
payload
,
result
))
return
result
def
qh_get_quotas
(
users
,
resources
):
result
=
qh_get_quota
(
users
,
resources
)
return
quotas_per_user_from_get
(
result
)
SetQuotaPayload
=
namedtuple
(
'SetQuotaPayload'
,
(
'holder'
,
'resource'
,
'capacity'
,
'flags'
))
QuotaLimits
=
namedtuple
(
'QuotaLimits'
,
(
'holder'
,
'resource'
,
'capacity'
,
))
def
register_quotas
(
quotas
):
if
not
quotas
:
return
payload
=
[]
append
=
payload
.
append
for
uuid
,
userquotas
in
quotas
.
iteritems
():
for
resource
,
capacity
in
userquotas
.
iteritems
():
append
(
SetQuotaPayload
(
holder
=
uuid
,
resource
=
str
(
resource
),
capacity
=
capacity
,
flags
=
0
))
return
set_quota
(
payload
)
def
send_quotas
(
userquotas
):
if
not
userquotas
:
return
payload
=
[]
append
=
payload
.
append
for
holder
,
quotas
in
userquotas
.
iteritems
():
for
resource
,
q
in
quotas
.
iteritems
():
append
(
SetQuotaPayload
(
holder
=
holder
,
resource
=
str
(
resource
),
capacity
=
q
.
capacity
,
flags
=
0
))
return
set_quota
(
payload
)
def
initial_commission
(
resources
):
c
=
get_client
()
if
not
c
:
return
for
resource
in
resources
:
s
=
c
.
issue_commission
(
clientkey
=
clientkey
,
target
=
str
(
resource
.
service
),
name
=
'initialization'
,
provisions
=
[(
None
,
str
(
resource
),
QH_PRACTICALLY_INFINITE
)])
c
.
accept_commission
(
clientkey
=
clientkey
,
serials
=
[
s
],
reason
=
''
)
def
register_resources
(
resources
):
payload
=
list
(
SetQuotaPayload
(
holder
=
str
(
resource
.
service
),
resource
=
str
(
resource
),
capacity
=
QH_PRACTICALLY_INFINITE
,
flags
=
0
)
for
resource
in
resources
)
set_quota
(
payload
)
initial_commission
(
resources
)
def
qh_add_quota
(
sub_list
,
add_list
):
context
=
{}
c
=
get_client
()
result
=
c
.
add_quota
(
context
=
context
,
sub_quota
=
sub_list
,
add_quota
=
add_list
)
return
result
from
datetime
import
datetime
strptime
=
datetime
.
strptime
timefmt
=
'%Y-%m-%dT%H:%M:%S.%f'
SECOND_RESOLUTION
=
1
def
total_seconds
(
timedelta_object
):
return
timedelta_object
.
seconds
+
timedelta_object
.
days
*
86400
def
iter_timeline
(
timeline
,
before
):
if
not
timeline
:
return
for
t
in
timeline
:
yield
t
t
=
dict
(
t
)
t
[
'issue_time'
]
=
before
yield
t
def
_usage_units
(
timeline
,
after
,
before
,
details
=
0
):
t_total
=
0
uu_total
=
0
t_after
=
strptime
(
after
,
timefmt
)
t_before
=
strptime
(
before
,
timefmt
)
t0
=
t_after
u0
=
0
for
point
in
iter_timeline
(
timeline
,
before
):
issue_time
=
point
[
'issue_time'
]
if
issue_time
<=
after
:
u0
=
point
[
'target_allocated_through'
]
continue
t
=
strptime
(
issue_time
,
timefmt
)
if
issue_time
<=
before
else
t_before
t_diff
=
int
(
total_seconds
(
t
-
t0
)
*
SECOND_RESOLUTION
)
t_total
+=
t_diff
uu_cost
=
u0
*
t_diff
uu_total
+=
uu_cost
t0
=
t
u0
=
point
[
'target_allocated_through'
]
target
=
point
[
'target'
]
if
details
:
yield
(
target
,
point
[
'resource'
],
point
[
'name'
],
issue_time
,
uu_cost
,
uu_total
)
if
not
t_total
:
return
yield
(
target
,
'total'
,
point
[
'resource'
],
issue_time
,
uu_total
/
t_total
,
uu_total
)
def
usage_units
(
timeline
,
after
,
before
,
details
=
0
):
return
list
(
_usage_units
(
timeline
,
after
,
before
,
details
=
details
))
def
traffic_units
(
timeline
,
after
,
before
,
details
=
0
):
tu_total
=
0
target
=
None
issue_time
=
None
for
point
in
timeline
:
issue_time
=
point
[
'issue_time'
]
if
issue_time
<=
after
:
continue
if
issue_time
>
before
:
break
target
=
point
[
'target'
]
tu
=
point
[
'target_allocated_through'
]
tu_total
+=
tu
if
details
:
yield
(
target
,
point
[
'resource'
],
point
[
'name'
],
issue_time
,
tu
,
tu_total
)
if
not
tu_total
:
return
yield
(
target
,
'total'
,
point
[
'resource'
],
issue_time
,
tu_total
//
len
(
timeline
),
tu_total
)
def
timeline_charge
(
entity
,
resource
,
after
,
before
,
details
,
charge_type
):
if
charge_type
==
'charge_usage'
:
charge_units
=
usage_units
elif
charge_type
==
'charge_traffic'
:
charge_units
=
traffic_units
else
:
m
=
'charge type %s not supported'
%
charge_type
raise
ValueError
(
m
)
quotaholder
=
QuotaholderClient
(
QUOTAHOLDER_URL
,
token
=
QUOTAHOLDER_TOKEN
,
poolsize
=
QUOTAHOLDER_POOLSIZE
)
timeline
=
quotaholder
.
get_timeline
(
context
=
{},
after
=
after
,
before
=
before
,
get_timeline
=
[[
entity
,
resource
]])
cu
=
charge_units
(
timeline
,
after
,
before
,
details
=
details
)
return
cu
snf-astakos-app/astakos/im/functions.py
View file @
5b1f8225
...
...
@@ -78,8 +78,6 @@ from astakos.im.project_notif import (
application_submit_notify
,
application_approve_notify
,
application_deny_notify
,
project_termination_notify
,
project_suspension_notify
)
from
astakos.im.endpoints.qh
import
(
register_quotas
,
qh_get_quota
,
qh_add_quota
)
import
astakos.im.messages
as
astakos_messages
...
...
@@ -376,8 +374,7 @@ class SendNotificationError(SendMailError):
def
get_quota
(
users
):
resources
=
get_resource_names
()
return
qh_get_quota
(
users
,
resources
)
pass
### PROJECT VIEWS ###
...
...
snf-astakos-app/astakos/im/models.py
View file @
5b1f8225
...
...
@@ -71,10 +71,6 @@ from astakos.im.settings import (
SITENAME
,
SERVICES
,
MODERATION_ENABLED
,
RESOURCES_PRESENTATION_DATA
,
PROJECT_MEMBER_JOIN_POLICIES
,
PROJECT_MEMBER_LEAVE_POLICIES
,
PROJECT_ADMINS
)
from
astakos.im
import
settings
as
astakos_settings
from
astakos.im.endpoints.qh
import
(
send_quotas
,
qh_get_quotas
,
register_resources
,
qh_add_quota
,
QuotaLimits
,
)
from
astakos.im
import
auth_providers
as
auth
import
astakos.im.messages
as
astakos_messages
...
...
snf-astakos-app/astakos/quotaholder/callpoint.py
View file @
5b1f8225
...
...
@@ -46,8 +46,6 @@ from astakos.quotaholder.commission import (
from
astakos.quotaholder.utils.newname
import
newname
from
astakos.quotaholder.api
import
QH_PRACTICALLY_INFINITE
from
django.db.models
import
Q
,
Count
from
django.db.models
import
Q
from
.models
import
(
Holding
,
Commission
,
Provision
,
ProvisionLog
,
now
,
...
...
@@ -57,117 +55,6 @@ from .models import (Holding,
class
QuotaholderDjangoDBCallpoint
(
object
):
def
_init_holding
(
self
,
holder
,
resource
,
limit
,
imported_min
,
imported_max
,
flags
):
try
:
h
=
db_get_holding
(
holder
=
holder
,
resource
=
resource
,
for_update
=
True
)
except
Holding
.
DoesNotExist
:
h
=
Holding
(
holder
=
holder
,
resource
=
resource
)
h
.
limit
=
limit
h
.
flags
=
flags
h
.
imported_min
=
imported_min
h
.
imported_max
=
imported_max
h
.
save
()
def
init_holding
(
self
,
context
=
None
,
init_holding
=
[]):
rejected
=
[]
append
=
rejected
.
append
for
idx
,
sfh
in
enumerate
(
init_holding
):
(
holder
,
resource
,
limit
,
imported_min
,
imported_max
,
flags
)
=
sfh
self
.
_init_holding
(
holder
,
resource
,
limit
,
imported_min
,
imported_max
,
flags
)
if
rejected
:
raise
QuotaholderError
(
rejected
)
return
rejected
def
reset_holding
(
self
,
context
=
None
,
reset_holding
=
[]):
rejected
=
[]
append
=
rejected
.
append
for
idx
,
tpl
in
enumerate
(
reset_holding
):
(
holder
,
source
,
resource
,
imported_min
,
imported_max
)
=
tpl
try
:
h
=
db_get_holding
(
holder
=
holder
,
source
=
source
,
resource
=
resource
,
for_update
=
True
)
h
.
imported_min
=
imported_min
h
.
imported_max
=
imported_max
h
.
save
()
except
Holding
.
DoesNotExist
:
append
(
idx
)
continue
if
rejected
:
raise
QuotaholderError
(
rejected
)
return
rejected
def
_check_pending
(
self
,
holding
):
ps
=
Provision
.
objects
.
filter
(
holding
=
holding
)
return
ps
.
count
()
def
release_holding
(
self
,
context
=
None
,
release_holding
=
[]):
rejected
=
[]
append
=
rejected
.
append
for
idx
,
(
holder
,
source
,
resource
)
in
enumerate
(
release_holding
):
try
:
h
=
db_get_holding
(
holder
=
holder
,
source
=
source
,
resource
=
resource
,
for_update
=
True
)
except
Holding
.
DoesNotExist
:
append
(
idx
)
continue
if
self
.
_check_pending
(
h
):
append
(
idx
)
continue
if
h
.
imported_max
>
0
:
append
(
idx
)
continue
h
.
delete
()
if
rejected
:
raise
QuotaholderError
(
rejected
)
return
rejected
def
list_resources
(
self
,
context
=
None
,
holder
=
None
):
holdings
=
Holding
.
objects
.
filter
(
holder
=
holder
)
resources
=
[
h
.
resource
for
h
in
holdings
]
return
resources
def
list_holdings
(
self
,
context
=
None
,
list_holdings
=
[]):
rejected
=
[]
reject
=
rejected
.
append
holdings_list
=
[]
append
=
holdings_list
.
append
for
holder
in
list_holdings
:
holdings
=
list
(
Holding
.
objects
.
filter
(
holder
=
holder
))
if
not
holdings
:
reject
(
holder
)
continue
append
([(
holder
,
h
.
source
,
h
.
resource
,
h
.
imported_min
,
h
.
imported_max
)
for
h
in
holdings
])
return
holdings_list
,
rejected
def
get_holder_quota
(
self
,
holders
=
None
,
sources
=
None
,
resources
=
None
):
holdings
=
Holding
.
objects
.
filter
(
holder__in
=
holders
)
...
...
@@ -185,28 +72,6 @@ class QuotaholderDjangoDBCallpoint(object):
return
quotas
def
get_quota
(
self
,
context
=
None
,
get_quota
=
[]):
quotas
=
[]
append
=
quotas
.
append
holders
=
set
(
holder
for
holder
,
r
in
get_quota
)
hs
=
Holding
.
objects
.
filter
(
holder__in
=
holders
)
holdings
=
{}
for
h
in
hs
:
holdings
[(
h
.
holder
,
h
.
source
,
h
.
resource
)]
=
h
for
holder
,
source
,
resource
in
get_quota
:
try
:
h
=
holdings
[(
holder
,
source
,
resource
)]
except
:
continue
append
((
h
.
holder
,
h
.
source
,
h
.
resource
,
h
.
limit
,
h
.
imported_min
,
h
.
imported_max
,
h
.
flags
))
return
quotas
def
set_holder_quota
(
self
,
quotas
):
holders
=
quotas
.
keys
()
hs
=
Holding
.
objects
.
filter
(
holder__in
=
holders
).
select_for_update
()
...
...
@@ -227,89 +92,6 @@ class QuotaholderDjangoDBCallpoint(object):
h
.
limit
=
limit
h
.
save
()
def
set_quota
(
self
,
context
=
None
,
set_quota
=
[]):
rejected
=
[]
append
=
rejected
.
append
q_holdings
=
Q
()
holders
=
[]
for
(
holder
,
source
,
resource
,
_
,
_
)
in
set_quota
:
holders
.
append
(
holder
)
hs
=
Holding
.
objects
.
filter
(
holder__in
=
holders
).
select_for_update
()
holdings
=
{}
for
h
in
hs
:
holdings
[(
h
.
holder
,
h
.
source
,
h
.
resource
)]
=
h
for
(
holder
,
source
,
resource
,
limit
,
flags
)
in
set_quota
:
try
:
h
=
holdings
[(
holder
,
source
,
resource
)]
h
.
flags
=
flags
except
KeyError
:
h
=
Holding
(
holder
=
holder
,
source
=
source
,
resource
=
resource
,
flags
=
flags
)
h
.
limit
=
limit
h
.
save
()
holdings
[(
holder
,
source
,
resource
)]
=
h
if
rejected
:
raise
QuotaholderError
(
rejected
)
return
rejected
def
add_quota
(
self
,
context
=
None
,
sub_quota
=
[],
add_quota
=
[]):
rejected
=
[]
append
=
rejected
.
append
sources
=
sub_quota
+
add_quota
q_holdings
=
Q
()
holders
=
[]
for
(
holder
,
resource
,
_
)
in
sources
:
holders
.
append
(
holder
)
hs
=
Holding
.
objects
.
filter
(
holder__in
=
holders
).
select_for_update
()
holdings
=
{}
for
h
in
hs
:
holdings
[(
h
.
holder
,
h
.
resource
)]
=
h
for
removing
,
source
in
[(
True
,
sub_quota
),
(
False
,
add_quota
)]:
for
(
holder
,
resource
,
limit
,
)
in
source
:
try
:
h
=
holdings
[(
holder
,
resource
)]
current_limit
=
h
.
limit
except
KeyError
:
if
removing
:
append
((
holder
,
resource
))
continue
h
=
Holding
(
holder
=
holder
,
resource
=
resource
,
flags
=
0
)
current_limit
=
0
h
.
limit
=
(
current_limit
-
limit
if
removing
else
current_limit
+
limit
)
if
h
.
limit
<
0
:
append
((
holder
,
resource
))
continue
h
.
save
()
holdings
[(
holder
,
resource
)]
=
h
if
rejected
:
raise
QuotaholderError
(
rejected
)
return
rejected
def
issue_commission
(
self
,
context
=
None
,
clientkey
=
None
,
...
...
@@ -524,76 +306,5 @@ class QuotaholderDjangoDBCallpoint(object):
failed
=
list
(
set
(
failed_ac
+
failed_re
))
return
accepted
,
rejected
,
failed
def
get_timeline
(
self
,
context
=
None
,
after
=
""
,
before
=
"Z"
,
get_timeline
=
[]):
holder_set
=
set
()
e_add
=
holder_set
.
add
resource_set
=
set
()
r_add
=
resource_set
.
add
for
holder
,
resource
in
get_timeline
:
if
holder
not
in
holder_set
: