Revision f7e51fc5
b/snf-cyclades-app/synnefo/ui/static/snf/js/quota.js | ||
---|---|---|
1 |
// Copyright 2013 GRNET S.A. All rights reserved. |
|
2 |
// |
|
3 |
// Redistribution and use in source and binary forms, with or |
|
4 |
// without modification, are permitted provided that the following |
|
5 |
// conditions are met: |
|
6 |
// |
|
7 |
// 1. Redistributions of source code must retain the above |
|
8 |
// copyright notice, this list of conditions and the following |
|
9 |
// disclaimer. |
|
10 |
// |
|
11 |
// 2. Redistributions in binary form must reproduce the above |
|
12 |
// copyright notice, this list of conditions and the following |
|
13 |
// disclaimer in the documentation and/or other materials |
|
14 |
// provided with the distribution. |
|
15 |
// |
|
16 |
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
// POSSIBILITY OF SUCH DAMAGE. |
|
28 |
// |
|
29 |
// The views and conclusions contained in the software and |
|
30 |
// documentation are those of the authors and should not be |
|
31 |
// interpreted as representing official policies, either expressed |
|
32 |
// or implied, of GRNET S.A. |
|
33 |
// |
|
34 |
|
|
35 |
;(function(root){ |
|
36 |
|
|
37 |
// Astakos quotas lib |
|
38 |
// Requires jquery and jquery.cookie javascript libs |
|
39 |
// |
|
40 |
// Usage |
|
41 |
// ----- |
|
42 |
// <script src="jquery.js"></script> |
|
43 |
// <script src="backbone.js"></script> |
|
44 |
// <script src="snf/quota.js"></script> |
|
45 |
// |
|
46 |
// var quotas = new snf.quota.Quota(); |
|
47 |
// var quotas = new snf.quota.Quota(); |
|
48 |
// $.ajax({ |
|
49 |
// url: '/userquota', |
|
50 |
// async: false, |
|
51 |
// method: 'POST', |
|
52 |
// success: function(data) { |
|
53 |
// quotas.load(data); |
|
54 |
// } |
|
55 |
// }) |
|
56 |
// |
|
57 |
// var vms_limit = quotas.get_limit("cyclades.vm"); |
|
58 |
// var networks_usage = quotas.get_usage("cyclades.network.private"); |
|
59 |
// |
|
60 |
|
|
61 |
var root = root; |
|
62 |
var snf = root.synnefo = root.synnefo || {}; |
|
63 |
var bb = root.Backbone; |
|
64 |
var _ = root._; |
|
65 |
|
|
66 |
// init quota namespace |
|
67 |
snf.quota = {}; |
|
68 |
|
|
69 |
snf.quota.Quota = function(defaultns) { |
|
70 |
if (defaultns == undefined) { defaultns = "" } |
|
71 |
this.ns = defaultns; |
|
72 |
} |
|
73 |
|
|
74 |
_.extend(snf.quota.Quota.prototype, bb.Events, { |
|
75 |
|
|
76 |
load: function(resp) { |
|
77 |
this.data = {}; |
|
78 |
_.each(resp, function(q) { |
|
79 |
if (this.data[q.name]) { |
|
80 |
_.extend(this.data[q.name], q) |
|
81 |
} else { |
|
82 |
this.data[q.name] = q; |
|
83 |
} |
|
84 |
q.maxValue = parseInt(q.maxValue); |
|
85 |
q.currValue = parseInt(q.currValue); |
|
86 |
this.update_exceeded(q.name, true); |
|
87 |
}, this); |
|
88 |
}, |
|
89 |
|
|
90 |
get_key: function(key) { |
|
91 |
if (key.indexOf(".") == -1) { |
|
92 |
return this.ns + "." + key; |
|
93 |
} |
|
94 |
return key; |
|
95 |
}, |
|
96 |
|
|
97 |
get: function(key) { |
|
98 |
if (this.get_key(key) in this.data) { |
|
99 |
return this.data[this.get_key(key)] |
|
100 |
} |
|
101 |
return {} |
|
102 |
}, |
|
103 |
|
|
104 |
update_exceeded: function(key, silent) { |
|
105 |
if (silent === undefined) { silent = false; } |
|
106 |
|
|
107 |
var q = this.get(key); |
|
108 |
var oldexceeded = q.exceeded; |
|
109 |
q.exceeded = this.exceeded(key); |
|
110 |
if (q.exceeded != oldexceeded) { |
|
111 |
key = this.get_key(key); |
|
112 |
this.trigger("quota.changed", key, this); |
|
113 |
this.trigger(key + ".quota.changed", this); |
|
114 |
if (q.exceeded) { this.trigger("quota.reached", this)} |
|
115 |
if (!q.exceeded) { this.trigger("quota.free", this)} |
|
116 |
if (q.exceeded) { this.trigger(key + ".quota.reached", this)} |
|
117 |
if (!q.exceeded) { this.trigger(key + ".quota.free", this)} |
|
118 |
} |
|
119 |
}, |
|
120 |
|
|
121 |
update_usage: function(key, value) { |
|
122 |
this.get(key).currValue = parseInt(value); |
|
123 |
this.update_exceeded(key); |
|
124 |
}, |
|
125 |
|
|
126 |
update_limit: function(key, value) { |
|
127 |
this.get(key).maxValue = parseInt(value); |
|
128 |
this.update_exceeded(key); |
|
129 |
}, |
|
130 |
|
|
131 |
get_usage: function(key) { |
|
132 |
return parseInt(this.get(key).currValue); |
|
133 |
}, |
|
134 |
|
|
135 |
get_limit: function(key) { |
|
136 |
return parseInt(this.get(key).maxValue); |
|
137 |
}, |
|
138 |
|
|
139 |
is_bytes: function(key) { |
|
140 |
return this.get(key).unit == "bytes"; |
|
141 |
}, |
|
142 |
|
|
143 |
get_available: function(key) { |
|
144 |
return this.get_limit(key) - this.get_usage(key) |
|
145 |
}, |
|
146 |
|
|
147 |
exceeded: function(key) { |
|
148 |
return this.get_usage(key) >= this.get_limit(key); |
|
149 |
}, |
|
150 |
|
|
151 |
can_consume: function(key, value) { |
|
152 |
return (this.get_available(key) - parseInt(value)) >= 0 |
|
153 |
} |
|
154 |
|
|
155 |
}); |
|
156 |
|
|
157 |
})(this); |
|
158 |
|
b/snf-cyclades-app/synnefo/ui/static/snf/js/ui/web/ui_main_view.js | ||
---|---|---|
773 | 773 |
|
774 | 774 |
load_user_quotas: function() { |
775 | 775 |
var main_view = this; |
776 |
if (!snf.user.quota) { |
|
777 |
snf.user.quota = new snf.quota.Quota("cyclades"); |
|
778 |
main_view.init_quotas_handlers(); |
|
779 |
} |
|
780 |
|
|
776 | 781 |
snf.api.sync('read', undefined, { |
777 | 782 |
url: synnefo.config.quota_url, |
778 | 783 |
success: function(d) { |
779 |
snf.user.quotas = {}; |
|
780 |
snf.user.quotas['vms'] = d.vms_quota; |
|
781 |
snf.user.quotas['networks'] = d.networks_quota; |
|
782 |
if (!main_view.quota_handlers_initialized) { |
|
783 |
main_view.init_quotas_handlers(['vms','networks']); |
|
784 |
main_view.quota_handlers_initialized = true; |
|
785 |
} |
|
786 |
try { |
|
787 |
main_view.check_quotas('vms'); |
|
788 |
main_view.check_quotas('networks'); |
|
789 |
} catch (err) { |
|
790 |
console.error(err); |
|
791 |
} |
|
784 |
snf.user.quota.load(d); |
|
792 | 785 |
}, |
793 | 786 |
complete: function() { |
794 | 787 |
setTimeout(function(){ |
... | ... | |
801 | 794 |
check_quotas: function(type) { |
802 | 795 |
var storage = synnefo.storage[type]; |
803 | 796 |
var consumed = storage.length; |
797 |
var quotakey = { |
|
798 |
'networks': 'cyclades.network.private', |
|
799 |
'vms': 'cyclades.vm' |
|
800 |
} |
|
804 | 801 |
if (type == "networks") { |
805 | 802 |
consumed = storage.filter(function(net){ |
806 | 803 |
return !net.is_public() && !net.is_deleted(); |
807 | 804 |
}).length; |
808 | 805 |
} |
809 |
if (snf.user.quotas && consumed >= snf.user.quotas[type]) { |
|
806 |
|
|
807 |
var limit = snf.user.quota.get_limit(quotakey[type]); |
|
808 |
if (snf.user.quota && snf.user.quota.data && consumed >= limit) { |
|
810 | 809 |
storage.trigger("quota_reached"); |
811 | 810 |
} else { |
812 | 811 |
storage.trigger("quota_free"); |
813 | 812 |
} |
814 | 813 |
}, |
815 | 814 |
|
816 |
init_quotas_handlers: function(types) { |
|
817 |
var self = this; |
|
818 |
_.each(types, function(type) { |
|
819 |
var storage = synnefo.storage[type]; |
|
820 |
if (!storage) { return }; |
|
821 |
var check_quotas = function() { |
|
822 |
self.check_quotas(type); |
|
823 |
} |
|
824 |
storage.bind("add", check_quotas); |
|
825 |
storage.bind("remove", check_quotas); |
|
826 |
check_quotas(); |
|
827 |
}) |
|
815 |
init_quotas_handlers: function() { |
|
816 |
var self = this, event; |
|
817 |
snf.user.quota.bind("cyclades.vm.quota.changed", function() { |
|
818 |
this.check_quotas("vms"); |
|
819 |
}, this); |
|
820 |
|
|
821 |
var event = "cyclades.network.private.quota.changed"; |
|
822 |
snf.user.quota.bind(event, function() { |
|
823 |
this.check_quotas("networks"); |
|
824 |
}, this); |
|
828 | 825 |
}, |
829 | 826 |
|
830 | 827 |
// initial view based on user cookie |
... | ... | |
862 | 859 |
$("#createcontainer #create").attr("title", ""); |
863 | 860 |
}); |
864 | 861 |
|
865 |
this.check_quotas('vms'); |
|
866 | 862 |
}, |
867 | 863 |
|
868 | 864 |
check_empty: function() { |
b/snf-cyclades-app/synnefo/ui/static/snf/js/ui/web/ui_networks_view.js | ||
---|---|---|
1290 | 1290 |
self.$("#networkscreate").removeClass("disabled").attr("title", |
1291 | 1291 |
""); |
1292 | 1292 |
}); |
1293 |
|
|
1294 |
synnefo.ui.main.check_quotas("networks"); |
|
1295 | 1293 |
}, |
1296 | 1294 |
|
1297 | 1295 |
update_networks: function(nets) { |
b/snf-cyclades-app/synnefo/ui/templates/home.html | ||
---|---|---|
55 | 55 |
|
56 | 56 |
<script src="{{ SYNNEFO_JS_URL }}utils.js"></script> |
57 | 57 |
<script src="{{ SYNNEFO_JS_URL }}auth.js"></script> |
58 |
<script src="{{ SYNNEFO_JS_URL }}quota.js"></script> |
|
58 | 59 |
<script src="{{ SYNNEFO_JS_URL }}sync.js"></script> |
59 | 60 |
<script src="{{ SYNNEFO_JS_URL }}models.js"></script> |
60 | 61 |
<script src="{{ SYNNEFO_JS_URL }}glance_models.js"></script> |
Also available in: Unified diff