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