Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / ui / static / snf / js / neutron.js @ fa5e1f54

History | View | Annotate | Download (16 kB)

1 fff8bd58 Kostas Papadimitriou
;(function(root){
2 fff8bd58 Kostas Papadimitriou
    // Neutron api models, collections, helpers
3 fff8bd58 Kostas Papadimitriou
  
4 fff8bd58 Kostas Papadimitriou
    // root
5 fff8bd58 Kostas Papadimitriou
    var root = root;
6 fff8bd58 Kostas Papadimitriou
    
7 fff8bd58 Kostas Papadimitriou
    // setup namepsaces
8 fff8bd58 Kostas Papadimitriou
    var snf = root.synnefo = root.synnefo || {};
9 fff8bd58 Kostas Papadimitriou
    var snfmodels = snf.models = snf.models || {}
10 fff8bd58 Kostas Papadimitriou
    var models = snfmodels.networks = snfmodels.networks || {};
11 fff8bd58 Kostas Papadimitriou
    var storage = snf.storage = snf.storage || {};
12 fff8bd58 Kostas Papadimitriou
    var util = snf.util = snf.util || {};
13 fff8bd58 Kostas Papadimitriou
14 fff8bd58 Kostas Papadimitriou
    // shortcuts
15 fff8bd58 Kostas Papadimitriou
    var bb = root.Backbone;
16 fff8bd58 Kostas Papadimitriou
    var slice = Array.prototype.slice
17 fff8bd58 Kostas Papadimitriou
18 fff8bd58 Kostas Papadimitriou
    // logging
19 fff8bd58 Kostas Papadimitriou
    var logger = new snf.logging.logger("SNF-MODELS");
20 fff8bd58 Kostas Papadimitriou
    var debug = _.bind(logger.debug, logger);
21 fff8bd58 Kostas Papadimitriou
    
22 fff8bd58 Kostas Papadimitriou
    // Neutron base model, extending existing synnefo model
23 fff8bd58 Kostas Papadimitriou
    models.NetworkModel = snfmodels.Model.extend({
24 e481c282 Kostas Papadimitriou
      api_type: 'network'
25 fff8bd58 Kostas Papadimitriou
    });
26 fff8bd58 Kostas Papadimitriou
    
27 fff8bd58 Kostas Papadimitriou
    // Neutron base collection, common neutron collection params are shared
28 fff8bd58 Kostas Papadimitriou
    models.NetworkCollection = snfmodels.Collection.extend({
29 e481c282 Kostas Papadimitriou
      api_type: 'network',
30 fff8bd58 Kostas Papadimitriou
      details: true,
31 fff8bd58 Kostas Papadimitriou
      noUpdate: true,
32 213a8396 Kostas Papadimitriou
      updateEntries: true,
33 213a8396 Kostas Papadimitriou
      add_on_create: true
34 fff8bd58 Kostas Papadimitriou
    });
35 fff8bd58 Kostas Papadimitriou
  
36 fff8bd58 Kostas Papadimitriou
    // Subnet model
37 fff8bd58 Kostas Papadimitriou
    models.Subnet = models.NetworkModel.extend();
38 fff8bd58 Kostas Papadimitriou
    
39 fff8bd58 Kostas Papadimitriou
    // Subnet collection
40 fff8bd58 Kostas Papadimitriou
    models.Subnets = models.NetworkCollection.extend({
41 fff8bd58 Kostas Papadimitriou
      model: models.Subnet,
42 fff8bd58 Kostas Papadimitriou
      details: false,
43 fff8bd58 Kostas Papadimitriou
      path: 'subnets',
44 fff8bd58 Kostas Papadimitriou
      parse: function(resp) {
45 fff8bd58 Kostas Papadimitriou
        return resp.subnets
46 fff8bd58 Kostas Papadimitriou
      }
47 fff8bd58 Kostas Papadimitriou
    });
48 fff8bd58 Kostas Papadimitriou
    
49 fff8bd58 Kostas Papadimitriou
    // Network 
50 fff8bd58 Kostas Papadimitriou
    models.Network = models.NetworkModel.extend({
51 fff8bd58 Kostas Papadimitriou
      path: 'networks',
52 fff8bd58 Kostas Papadimitriou
53 213a8396 Kostas Papadimitriou
      parse: function(obj) {
54 213a8396 Kostas Papadimitriou
        return obj.network;
55 213a8396 Kostas Papadimitriou
      },
56 213a8396 Kostas Papadimitriou
57 fff8bd58 Kostas Papadimitriou
      // Available network actions.
58 fff8bd58 Kostas Papadimitriou
      // connect: 
59 fff8bd58 Kostas Papadimitriou
      model_actions: {
60 fff8bd58 Kostas Papadimitriou
        'connect': [['status', 'is_public'], function() {
61 fff8bd58 Kostas Papadimitriou
          //TODO: Also check network status
62 fff8bd58 Kostas Papadimitriou
          return !this.is_public() && _.contains(['ACTIVE'], this.get('status'));
63 fff8bd58 Kostas Papadimitriou
        }],
64 c935b4ea Kostas Papadimitriou
        'remove': [['status', 'is_public', 'ports'], function() {
65 c935b4ea Kostas Papadimitriou
          if (this.ports && this.ports.length) {
66 c935b4ea Kostas Papadimitriou
            return false
67 c935b4ea Kostas Papadimitriou
          }
68 fff8bd58 Kostas Papadimitriou
          return !this.is_public() && _.contains(['ACTIVE'], this.get('status'));
69 fff8bd58 Kostas Papadimitriou
        }]
70 fff8bd58 Kostas Papadimitriou
      },
71 fff8bd58 Kostas Papadimitriou
72 fff8bd58 Kostas Papadimitriou
      proxy_attrs: {
73 fff8bd58 Kostas Papadimitriou
        'is_public': [
74 fff8bd58 Kostas Papadimitriou
          ['router:external', 'public'], function() {
75 fff8bd58 Kostas Papadimitriou
            return this.get('router:external') || this.get('public')
76 fff8bd58 Kostas Papadimitriou
          } 
77 fff8bd58 Kostas Papadimitriou
        ],
78 5e66fc73 Kostas Papadimitriou
        'is_floating': [
79 5e66fc73 Kostas Papadimitriou
          ['SNF:floating_ip_pool'], function() {
80 5e66fc73 Kostas Papadimitriou
            return this.get('SNF:floating_ip_pool')
81 5e66fc73 Kostas Papadimitriou
          }
82 5e66fc73 Kostas Papadimitriou
        ],
83 d233867a Kostas Papadimitriou
        'cidr': [
84 d233867a Kostas Papadimitriou
          ['subnet'], function() {
85 d233867a Kostas Papadimitriou
            var subnet = this.get('subnet');
86 d233867a Kostas Papadimitriou
            if (subnet && subnet.get('cidr')) {
87 d233867a Kostas Papadimitriou
              return subnet.get('cidr')
88 d233867a Kostas Papadimitriou
            } else {
89 d233867a Kostas Papadimitriou
              return undefined
90 d233867a Kostas Papadimitriou
            }
91 d233867a Kostas Papadimitriou
          }
92 d233867a Kostas Papadimitriou
        ],
93 fff8bd58 Kostas Papadimitriou
        'ext_status': [
94 d233867a Kostas Papadimitriou
          ['status', 'cidr'], function(st) {
95 a681ab44 Kostas Papadimitriou
            if (this.get('ext_status') == 'REMOVING') {
96 a681ab44 Kostas Papadimitriou
              return 'REMOVING'
97 a681ab44 Kostas Papadimitriou
            }
98 fff8bd58 Kostas Papadimitriou
            if (this.pending_connections) {
99 fff8bd58 Kostas Papadimitriou
              return 'CONNECTING'
100 fff8bd58 Kostas Papadimitriou
            } else if (this.pending_disconnects) {
101 fff8bd58 Kostas Papadimitriou
              return 'DISCONNECTING'
102 fff8bd58 Kostas Papadimitriou
            } else {
103 d233867a Kostas Papadimitriou
              return this.get('status')
104 fff8bd58 Kostas Papadimitriou
            }
105 fff8bd58 Kostas Papadimitriou
        }],
106 fff8bd58 Kostas Papadimitriou
        'in_progress': [
107 fff8bd58 Kostas Papadimitriou
          ['ext_status'], function() {
108 fff8bd58 Kostas Papadimitriou
            return _.contains(['CONNECTING', 
109 fff8bd58 Kostas Papadimitriou
                               'DISCONNECTING', 
110 fff8bd58 Kostas Papadimitriou
                               'REMOVING'], 
111 fff8bd58 Kostas Papadimitriou
                               this.get('ext_status'))
112 fff8bd58 Kostas Papadimitriou
          }  
113 fff8bd58 Kostas Papadimitriou
        ]
114 fff8bd58 Kostas Papadimitriou
      },
115 fff8bd58 Kostas Papadimitriou
      
116 d233867a Kostas Papadimitriou
      storage_attrs: {
117 d233867a Kostas Papadimitriou
        'subnets': ['subnets', 'subnet', function(model, attr) {
118 d233867a Kostas Papadimitriou
          var subnets = model.get(attr);
119 c68ad72e Kostas Papadimitriou
          if (subnets && subnets.length) { return subnets[0] }
120 d233867a Kostas Papadimitriou
        }]
121 d233867a Kostas Papadimitriou
      },
122 d233867a Kostas Papadimitriou
123 fff8bd58 Kostas Papadimitriou
      // call rename api
124 fff8bd58 Kostas Papadimitriou
      rename: function(new_name, cb) {
125 fff8bd58 Kostas Papadimitriou
          this.sync("update", this, {
126 fff8bd58 Kostas Papadimitriou
              critical: true,
127 fff8bd58 Kostas Papadimitriou
              data: {
128 fff8bd58 Kostas Papadimitriou
                  'network': {
129 fff8bd58 Kostas Papadimitriou
                      'name': new_name
130 fff8bd58 Kostas Papadimitriou
                  }
131 fff8bd58 Kostas Papadimitriou
              }, 
132 fff8bd58 Kostas Papadimitriou
              // do the rename after the method succeeds
133 fff8bd58 Kostas Papadimitriou
              success: _.bind(function(){
134 fff8bd58 Kostas Papadimitriou
                  //this.set({name: new_name});
135 fff8bd58 Kostas Papadimitriou
                  snf.api.trigger("call");
136 fff8bd58 Kostas Papadimitriou
              }, this),
137 fff8bd58 Kostas Papadimitriou
              complete: cb || function() {}
138 fff8bd58 Kostas Papadimitriou
          });
139 fff8bd58 Kostas Papadimitriou
      },
140 fff8bd58 Kostas Papadimitriou
141 fff8bd58 Kostas Papadimitriou
      pending_connections: 0,
142 fff8bd58 Kostas Papadimitriou
      pending_disconnects: 0,
143 fff8bd58 Kostas Papadimitriou
144 fff8bd58 Kostas Papadimitriou
      initialize: function() {
145 fff8bd58 Kostas Papadimitriou
        var self = this;
146 fff8bd58 Kostas Papadimitriou
        this.subnets = new Backbone.FilteredCollection(undefined, {
147 fff8bd58 Kostas Papadimitriou
          collection: synnefo.storage.subnets,
148 fff8bd58 Kostas Papadimitriou
          collectionFilter: function(m) {
149 fff8bd58 Kostas Papadimitriou
            return self.id == m.get('network_id')
150 d233867a Kostas Papadimitriou
        }});
151 fff8bd58 Kostas Papadimitriou
        this.ports = new Backbone.FilteredCollection(undefined, {
152 fff8bd58 Kostas Papadimitriou
          collection: synnefo.storage.ports,
153 fff8bd58 Kostas Papadimitriou
          collectionFilter: function(m) {
154 fff8bd58 Kostas Papadimitriou
            return self.id == m.get('network_id')
155 fff8bd58 Kostas Papadimitriou
          }
156 fff8bd58 Kostas Papadimitriou
        });
157 fff8bd58 Kostas Papadimitriou
        this.ports.network = this;
158 89dc40ca Kostas Papadimitriou
        this.ports.bind("reset", function() {
159 89dc40ca Kostas Papadimitriou
          this.pending_connections = 0;
160 89dc40ca Kostas Papadimitriou
          this.pending_disconnects = 0;
161 89dc40ca Kostas Papadimitriou
          this.update_connecting_status();
162 89dc40ca Kostas Papadimitriou
          this.update_actions();
163 89dc40ca Kostas Papadimitriou
        }, this);
164 fff8bd58 Kostas Papadimitriou
        this.ports.bind("add", function() {
165 fff8bd58 Kostas Papadimitriou
          this.pending_connections--;
166 fff8bd58 Kostas Papadimitriou
          this.update_connecting_status();
167 c935b4ea Kostas Papadimitriou
          this.update_actions();
168 fff8bd58 Kostas Papadimitriou
        }, this);
169 fff8bd58 Kostas Papadimitriou
        this.ports.bind("remove", function() {
170 fff8bd58 Kostas Papadimitriou
          this.pending_disconnects--;
171 fff8bd58 Kostas Papadimitriou
          this.update_connecting_status();
172 c935b4ea Kostas Papadimitriou
          this.update_actions();
173 fff8bd58 Kostas Papadimitriou
        }, this);
174 fff8bd58 Kostas Papadimitriou
        this.set({ports: this.ports});
175 a37c5497 Kostas Papadimitriou
176 a37c5497 Kostas Papadimitriou
        this.connectable_vms = new Backbone.FilteredCollection(undefined, {
177 a37c5497 Kostas Papadimitriou
          collection: synnefo.storage.vms,
178 a37c5497 Kostas Papadimitriou
          collectionFilter: function(m) {
179 a37c5497 Kostas Papadimitriou
            return m.can_connect();
180 a37c5497 Kostas Papadimitriou
          }
181 a37c5497 Kostas Papadimitriou
        });
182 89dc40ca Kostas Papadimitriou
        models.Network.__super__.initialize.apply(this, arguments);
183 c935b4ea Kostas Papadimitriou
        this.update_actions();
184 fff8bd58 Kostas Papadimitriou
      },
185 fff8bd58 Kostas Papadimitriou
      
186 c935b4ea Kostas Papadimitriou
      update_actions: function() {
187 c935b4ea Kostas Papadimitriou
        if (this.ports.length) {
188 c935b4ea Kostas Papadimitriou
          this.set({can_remove: false})
189 c935b4ea Kostas Papadimitriou
        } else {
190 c935b4ea Kostas Papadimitriou
          this.set({can_remove: true})
191 c935b4ea Kostas Papadimitriou
        }
192 c935b4ea Kostas Papadimitriou
      },
193 c935b4ea Kostas Papadimitriou
194 fff8bd58 Kostas Papadimitriou
      update_connecting_status: function() {
195 fff8bd58 Kostas Papadimitriou
        if (this.pending_connections <= 0) {
196 fff8bd58 Kostas Papadimitriou
          this.pending_connections = 0;
197 fff8bd58 Kostas Papadimitriou
        }
198 fff8bd58 Kostas Papadimitriou
        if (this.pending_disconnects <= 0) {
199 fff8bd58 Kostas Papadimitriou
          this.pending_disconnects = 0;
200 fff8bd58 Kostas Papadimitriou
        }
201 fff8bd58 Kostas Papadimitriou
        this.trigger('change:status', this.get('status'));
202 fff8bd58 Kostas Papadimitriou
      },
203 fff8bd58 Kostas Papadimitriou
204 fff8bd58 Kostas Papadimitriou
      get_nics: function() {
205 fff8bd58 Kostas Papadimitriou
        return this.nics.models
206 fff8bd58 Kostas Papadimitriou
      },
207 fff8bd58 Kostas Papadimitriou
208 fff8bd58 Kostas Papadimitriou
      is_public: function() {
209 fff8bd58 Kostas Papadimitriou
        return this.get('router:external')
210 fff8bd58 Kostas Papadimitriou
      },
211 fff8bd58 Kostas Papadimitriou
212 fff8bd58 Kostas Papadimitriou
      connect_vm: function(vm, cb) {
213 fff8bd58 Kostas Papadimitriou
        var self = this;
214 fff8bd58 Kostas Papadimitriou
        var data = {
215 fff8bd58 Kostas Papadimitriou
          port: {
216 fff8bd58 Kostas Papadimitriou
            network_id: this.id,
217 fff8bd58 Kostas Papadimitriou
            device_id: vm.id
218 fff8bd58 Kostas Papadimitriou
          }
219 fff8bd58 Kostas Papadimitriou
        }
220 fff8bd58 Kostas Papadimitriou
221 fff8bd58 Kostas Papadimitriou
        this.pending_connections++;
222 fff8bd58 Kostas Papadimitriou
        this.update_connecting_status();
223 fff8bd58 Kostas Papadimitriou
        synnefo.storage.ports.create(data, {complete: cb});
224 fff8bd58 Kostas Papadimitriou
      }
225 fff8bd58 Kostas Papadimitriou
    });
226 fff8bd58 Kostas Papadimitriou
227 fff8bd58 Kostas Papadimitriou
    models.CombinedPublicNetwork = models.Network.extend({
228 fff8bd58 Kostas Papadimitriou
      defaults: {
229 fff8bd58 Kostas Papadimitriou
        'admin_state_up': true,
230 fff8bd58 Kostas Papadimitriou
        'id': 'snf-combined-public-network',
231 213a8396 Kostas Papadimitriou
        'name': 'Internet',
232 fff8bd58 Kostas Papadimitriou
        'status': 'ACTIVE',
233 fff8bd58 Kostas Papadimitriou
        'router:external': true,
234 fff8bd58 Kostas Papadimitriou
        'shared': false,
235 d233867a Kostas Papadimitriou
        'rename_disabled': true,
236 d233867a Kostas Papadimitriou
        'subnets': []
237 fff8bd58 Kostas Papadimitriou
      },
238 fff8bd58 Kostas Papadimitriou
      
239 fff8bd58 Kostas Papadimitriou
      initialize: function() {
240 fff8bd58 Kostas Papadimitriou
        var self = this;
241 fff8bd58 Kostas Papadimitriou
        this.ports = new Backbone.FilteredCollection(undefined, {
242 fff8bd58 Kostas Papadimitriou
          collection: synnefo.storage.ports,
243 fff8bd58 Kostas Papadimitriou
          collectionFilter: function(m) {
244 fff8bd58 Kostas Papadimitriou
            return m.get('network') && m.get('network').get('is_public');
245 fff8bd58 Kostas Papadimitriou
          }
246 fff8bd58 Kostas Papadimitriou
        });
247 fff8bd58 Kostas Papadimitriou
        this.set({ports: this.ports});
248 c68ad72e Kostas Papadimitriou
        this.floating_ips = synnefo.storage.floating_ips;
249 c68ad72e Kostas Papadimitriou
        this.set({floating_ips: this.floating_ips});
250 c68ad72e Kostas Papadimitriou
251 c68ad72e Kostas Papadimitriou
        this.available_floating_ips = new Backbone.FilteredCollection(undefined, {
252 c68ad72e Kostas Papadimitriou
          collection: synnefo.storage.floating_ips,
253 c68ad72e Kostas Papadimitriou
          collectionFilter: function(m) {
254 c68ad72e Kostas Papadimitriou
            return !m.get('port_id');
255 c68ad72e Kostas Papadimitriou
          }
256 c68ad72e Kostas Papadimitriou
        });
257 c68ad72e Kostas Papadimitriou
        this.set({available_floating_ips: this.available_floating_ips});
258 89dc40ca Kostas Papadimitriou
        models.Network.__super__.initialize.apply(this, arguments);
259 fff8bd58 Kostas Papadimitriou
      },
260 fff8bd58 Kostas Papadimitriou
261 fff8bd58 Kostas Papadimitriou
    })
262 fff8bd58 Kostas Papadimitriou
263 fff8bd58 Kostas Papadimitriou
    models.Networks = models.NetworkCollection.extend({
264 fff8bd58 Kostas Papadimitriou
      model: models.Network,
265 fff8bd58 Kostas Papadimitriou
      path: 'networks',
266 fff8bd58 Kostas Papadimitriou
      details: true,
267 fff8bd58 Kostas Papadimitriou
      parse: function(resp) {
268 fff8bd58 Kostas Papadimitriou
        return resp.networks
269 fff8bd58 Kostas Papadimitriou
      },
270 fff8bd58 Kostas Papadimitriou
271 fff8bd58 Kostas Papadimitriou
      get_floating_ips_network: function() {
272 fff8bd58 Kostas Papadimitriou
        return this.filter(function(n) { return n.get('is_public')})[1]
273 fff8bd58 Kostas Papadimitriou
      },
274 fff8bd58 Kostas Papadimitriou
275 fff8bd58 Kostas Papadimitriou
      create: function (name, type, cidr, dhcp, callback) {
276 fff8bd58 Kostas Papadimitriou
        var quota = synnefo.storage.quotas;
277 e38e7fcf Kostas Papadimitriou
        var params = {network:{name:name}};
278 e38e7fcf Kostas Papadimitriou
        var subnet_params = {subnet:{network_id:undefined}};
279 fff8bd58 Kostas Papadimitriou
        if (!type) { throw "Network type cannot be empty"; }
280 fff8bd58 Kostas Papadimitriou
281 fff8bd58 Kostas Papadimitriou
        params.network.type = type;
282 e38e7fcf Kostas Papadimitriou
        if (cidr) { subnet_params.subnet.cidr = cidr; }
283 e38e7fcf Kostas Papadimitriou
        if (dhcp) { subnet_params.subnet.dhcp_enabled = dhcp; }
284 e38e7fcf Kostas Papadimitriou
        if (dhcp === false) { subnet_params.subnet.dhcp_enabled = false; }
285 fff8bd58 Kostas Papadimitriou
        
286 fff8bd58 Kostas Papadimitriou
        var cb = function() {
287 fff8bd58 Kostas Papadimitriou
          callback();
288 e38e7fcf Kostas Papadimitriou
        }
289 e38e7fcf Kostas Papadimitriou
        
290 e38e7fcf Kostas Papadimitriou
        var complete = function() {};
291 e38e7fcf Kostas Papadimitriou
        var error = function() { cb() };
292 e38e7fcf Kostas Papadimitriou
        // on network create success, try to create the requested 
293 e38e7fcf Kostas Papadimitriou
        // network subnet
294 e38e7fcf Kostas Papadimitriou
        var success = function(resp) {
295 e38e7fcf Kostas Papadimitriou
          var network = resp.network;
296 e38e7fcf Kostas Papadimitriou
          subnet_params.subnet.network_id = network.id;
297 e38e7fcf Kostas Papadimitriou
          synnefo.storage.subnets.create(subnet_params, {
298 e38e7fcf Kostas Papadimitriou
            complete: function () { cb && cb() }
299 e38e7fcf Kostas Papadimitriou
          });
300 fff8bd58 Kostas Papadimitriou
          quota.get('cyclades.network.private').increase();
301 fff8bd58 Kostas Papadimitriou
        }
302 e38e7fcf Kostas Papadimitriou
        return this.api_call(this.path, "create", params, complete, error, success);
303 fff8bd58 Kostas Papadimitriou
      }
304 fff8bd58 Kostas Papadimitriou
    });
305 365af933 Kostas Papadimitriou
    
306 365af933 Kostas Papadimitriou
    // dummy model/collection
307 365af933 Kostas Papadimitriou
    models.FixedIP = models.NetworkModel.extend({
308 365af933 Kostas Papadimitriou
      storage_attrs: {
309 365af933 Kostas Papadimitriou
        'subnet_id': ['subnets', 'subnet']
310 365af933 Kostas Papadimitriou
      }
311 365af933 Kostas Papadimitriou
    });
312 365af933 Kostas Papadimitriou
    models.FixedIPs = models.NetworkCollection.extend({
313 365af933 Kostas Papadimitriou
      model: models.FixedIP
314 365af933 Kostas Papadimitriou
    });
315 fff8bd58 Kostas Papadimitriou
316 fff8bd58 Kostas Papadimitriou
    models.Port = models.NetworkModel.extend({
317 fff8bd58 Kostas Papadimitriou
      path: 'ports',
318 213a8396 Kostas Papadimitriou
      parse: function(obj) {
319 213a8396 Kostas Papadimitriou
        return obj.port;
320 213a8396 Kostas Papadimitriou
      },
321 fff8bd58 Kostas Papadimitriou
      initialize: function() {
322 fff8bd58 Kostas Papadimitriou
        models.Port.__super__.initialize.apply(this, arguments);
323 365af933 Kostas Papadimitriou
        var ips = new models.FixedIPs();
324 365af933 Kostas Papadimitriou
        this.set({'ips': ips});
325 365af933 Kostas Papadimitriou
        this.bind('change:fixed_ips', function() {
326 365af933 Kostas Papadimitriou
          var ips = this.get('ips');
327 365af933 Kostas Papadimitriou
          //var ips = _.map(ips, function(ip) { ip.id = ip.a})
328 365af933 Kostas Papadimitriou
          this.update_ips()
329 365af933 Kostas Papadimitriou
        }, this);
330 365af933 Kostas Papadimitriou
        this.update_ips();
331 fff8bd58 Kostas Papadimitriou
        this.set({'pending_firewall': null});
332 fff8bd58 Kostas Papadimitriou
      },
333 fff8bd58 Kostas Papadimitriou
      
334 365af933 Kostas Papadimitriou
      update_ips: function() {
335 fa5e1f54 Kostas Papadimitriou
        var self = this;
336 32a58fdf Kostas Papadimitriou
        var ips = _.map(this.get('fixed_ips'), function(ip_obj) {
337 32a58fdf Kostas Papadimitriou
          var ip = _.clone(ip_obj);
338 365af933 Kostas Papadimitriou
          var type = "v4";
339 365af933 Kostas Papadimitriou
          if (ip.ip_address.indexOf(":") >= 0) {
340 365af933 Kostas Papadimitriou
            type = "v6";
341 365af933 Kostas Papadimitriou
          }
342 365af933 Kostas Papadimitriou
          ip.id = ip.ip_address;
343 365af933 Kostas Papadimitriou
          ip.type = type;
344 365af933 Kostas Papadimitriou
          ip.subnet_id = ip.subnet;
345 fa5e1f54 Kostas Papadimitriou
          ip.port_id = self.id;
346 365af933 Kostas Papadimitriou
          delete ip.subnet;
347 365af933 Kostas Papadimitriou
          return ip;
348 365af933 Kostas Papadimitriou
        });
349 365af933 Kostas Papadimitriou
        this.get('ips').update(ips, {removeMissing: true});
350 365af933 Kostas Papadimitriou
      },
351 365af933 Kostas Papadimitriou
352 fff8bd58 Kostas Papadimitriou
      model_actions: {
353 fff8bd58 Kostas Papadimitriou
        'disconnect': [['status', 'network', 'vm'], function() {
354 fff8bd58 Kostas Papadimitriou
          var network = this.get('network');
355 5e66fc73 Kostas Papadimitriou
          if ((!network || network.get('is_public')) && (network && !network.get('is_floating'))) {
356 fff8bd58 Kostas Papadimitriou
            return false
357 fff8bd58 Kostas Papadimitriou
          }
358 fff8bd58 Kostas Papadimitriou
          var status_ok = _.contains(['DOWN', 'ACTIVE', 'CONNECTED'], 
359 fff8bd58 Kostas Papadimitriou
                                     this.get('status'));
360 c935b4ea Kostas Papadimitriou
          var vm_status_ok = this.get('vm') && this.get('vm').can_connect();
361 fff8bd58 Kostas Papadimitriou
          return status_ok && vm_status_ok
362 fff8bd58 Kostas Papadimitriou
        }]
363 fff8bd58 Kostas Papadimitriou
      },
364 fff8bd58 Kostas Papadimitriou
365 fff8bd58 Kostas Papadimitriou
      storage_attrs: {
366 fff8bd58 Kostas Papadimitriou
        'device_id': ['vms', 'vm'],
367 32a58fdf Kostas Papadimitriou
        'network_id': ['networks', 'network']
368 fff8bd58 Kostas Papadimitriou
      },
369 fff8bd58 Kostas Papadimitriou
370 fff8bd58 Kostas Papadimitriou
      proxy_attrs: {
371 fff8bd58 Kostas Papadimitriou
        'firewall_status': [
372 fff8bd58 Kostas Papadimitriou
          ['vm'], function(vm) {
373 fff8bd58 Kostas Papadimitriou
            var attachment = vm && vm.get_attachment(this.id);
374 fff8bd58 Kostas Papadimitriou
            if (!attachment) { return "DISABLED" }
375 fff8bd58 Kostas Papadimitriou
            return attachment.firewallProfile
376 fff8bd58 Kostas Papadimitriou
          } 
377 fff8bd58 Kostas Papadimitriou
        ],
378 f8aa9fc3 Kostas Papadimitriou
        'ext_status': [
379 f8aa9fc3 Kostas Papadimitriou
          ['status'], function() {
380 f8aa9fc3 Kostas Papadimitriou
            if (_.contains(["DISCONNECTING"], this.get('ext_status'))) {
381 f8aa9fc3 Kostas Papadimitriou
              return this.get("ext_status")
382 f8aa9fc3 Kostas Papadimitriou
            }
383 f8aa9fc3 Kostas Papadimitriou
            return this.get("status")
384 f8aa9fc3 Kostas Papadimitriou
          }
385 f8aa9fc3 Kostas Papadimitriou
        ],
386 f8aa9fc3 Kostas Papadimitriou
        'in_progress': [
387 f8aa9fc3 Kostas Papadimitriou
          ['ext_status'], function() {
388 fa5e1f54 Kostas Papadimitriou
            return _.contains(["DISCONNECTING", "CONNECTING"], this.get("ext_status"))
389 f8aa9fc3 Kostas Papadimitriou
          }
390 f8aa9fc3 Kostas Papadimitriou
        ],
391 fff8bd58 Kostas Papadimitriou
        'firewall_running': [
392 fff8bd58 Kostas Papadimitriou
          ['firewall_status', 'pending_firewall'], function(status, pending) {
393 fff8bd58 Kostas Papadimitriou
              var pending = this.get('pending_firewall');
394 fff8bd58 Kostas Papadimitriou
              var status = this.get('firewall_status');
395 fff8bd58 Kostas Papadimitriou
              if (!pending) { return false }
396 fff8bd58 Kostas Papadimitriou
              if (status == pending) {
397 fff8bd58 Kostas Papadimitriou
                this.set({'pending_firewall': null});
398 fff8bd58 Kostas Papadimitriou
              }
399 fff8bd58 Kostas Papadimitriou
              return status != pending;
400 fff8bd58 Kostas Papadimitriou
          }
401 fff8bd58 Kostas Papadimitriou
        ],
402 fff8bd58 Kostas Papadimitriou
      },
403 fff8bd58 Kostas Papadimitriou
404 fff8bd58 Kostas Papadimitriou
      disconnect: function(cb) {
405 fff8bd58 Kostas Papadimitriou
        var network = this.get('network');
406 69dac1ba Kostas Papadimitriou
        var vm = this.get('vm');
407 fff8bd58 Kostas Papadimitriou
        network.pending_disconnects++;
408 fff8bd58 Kostas Papadimitriou
        network.update_connecting_status();
409 e6a4b75c Kostas Papadimitriou
        var success = _.bind(function() {
410 69dac1ba Kostas Papadimitriou
          if (vm) {
411 69dac1ba Kostas Papadimitriou
            vm.set({'status': 'DISCONNECTING'});
412 69dac1ba Kostas Papadimitriou
          }
413 f8aa9fc3 Kostas Papadimitriou
          this.set({'status': 'DISCONNECTING'});
414 f8aa9fc3 Kostas Papadimitriou
          cb();
415 f8aa9fc3 Kostas Papadimitriou
        }, this);
416 e6a4b75c Kostas Papadimitriou
        this.destroy({success: success, complete: cb, silent: true});
417 fff8bd58 Kostas Papadimitriou
      }
418 fff8bd58 Kostas Papadimitriou
    });
419 fff8bd58 Kostas Papadimitriou
420 fff8bd58 Kostas Papadimitriou
    models.Ports = models.NetworkCollection.extend({
421 fff8bd58 Kostas Papadimitriou
      model: models.Port,
422 fff8bd58 Kostas Papadimitriou
      path: 'ports',
423 fff8bd58 Kostas Papadimitriou
      details: true,
424 fff8bd58 Kostas Papadimitriou
      noUpdate: true,
425 fff8bd58 Kostas Papadimitriou
      updateEntries: true,
426 fff8bd58 Kostas Papadimitriou
427 fff8bd58 Kostas Papadimitriou
      parse: function(data) {
428 fff8bd58 Kostas Papadimitriou
        return data.ports;
429 fff8bd58 Kostas Papadimitriou
      },
430 fff8bd58 Kostas Papadimitriou
431 fff8bd58 Kostas Papadimitriou
      comparator: function(m) {
432 fff8bd58 Kostas Papadimitriou
        try {
433 fff8bd58 Kostas Papadimitriou
          return parseInt(m.get('device_id'));
434 fff8bd58 Kostas Papadimitriou
        } catch (err) {
435 fff8bd58 Kostas Papadimitriou
          return 0
436 fff8bd58 Kostas Papadimitriou
        }
437 fff8bd58 Kostas Papadimitriou
      }
438 fff8bd58 Kostas Papadimitriou
    });
439 fff8bd58 Kostas Papadimitriou
440 fff8bd58 Kostas Papadimitriou
    models.FloatingIP = models.NetworkModel.extend({
441 fff8bd58 Kostas Papadimitriou
      path: 'floatingips',
442 213a8396 Kostas Papadimitriou
443 213a8396 Kostas Papadimitriou
      parse: function(obj) {
444 213a8396 Kostas Papadimitriou
        return obj.floatingip;
445 213a8396 Kostas Papadimitriou
      },
446 213a8396 Kostas Papadimitriou
447 fff8bd58 Kostas Papadimitriou
      storage_attrs: {
448 fff8bd58 Kostas Papadimitriou
        'port_id': ['ports', 'port'],
449 fff8bd58 Kostas Papadimitriou
        'floating_network_id': ['networks', 'network'],
450 fff8bd58 Kostas Papadimitriou
      },
451 fff8bd58 Kostas Papadimitriou
452 fff8bd58 Kostas Papadimitriou
      model_actions: {
453 fff8bd58 Kostas Papadimitriou
        'remove': [['status'], function() {
454 fff8bd58 Kostas Papadimitriou
          var status_ok = _.contains(['DISCONNECTED'], this.get('status'))
455 fff8bd58 Kostas Papadimitriou
          return status_ok
456 fff8bd58 Kostas Papadimitriou
        }],
457 fff8bd58 Kostas Papadimitriou
        'connect': [['status'], function() {
458 fff8bd58 Kostas Papadimitriou
          var status_ok = _.contains(['DISCONNECTED'], this.get('status'))
459 fff8bd58 Kostas Papadimitriou
          return status_ok
460 fff8bd58 Kostas Papadimitriou
        }],
461 5475c563 Kostas Papadimitriou
        'disconnect': [['status', 'port_id', 'port'], function() {
462 5475c563 Kostas Papadimitriou
          var port = this.get('port');
463 5475c563 Kostas Papadimitriou
          var vm = port && port.get('vm');
464 e6a4b75c Kostas Papadimitriou
          if (!vm) { return false }
465 5475c563 Kostas Papadimitriou
          if (vm && vm.get("task_state")) { return false }
466 e6a4b75c Kostas Papadimitriou
          if (vm && vm.in_error_state()) { return false }
467 f8aa9fc3 Kostas Papadimitriou
          var status_ok = _.contains(['ACTIVE', 'CONNECTED'], this.get('status'))
468 69dac1ba Kostas Papadimitriou
          var vm_status_ok = vm.can_disconnect();
469 69dac1ba Kostas Papadimitriou
          return status_ok && vm_status_ok;
470 fff8bd58 Kostas Papadimitriou
        }]
471 fff8bd58 Kostas Papadimitriou
      },
472 fff8bd58 Kostas Papadimitriou
473 fff8bd58 Kostas Papadimitriou
      proxy_attrs: {
474 fff8bd58 Kostas Papadimitriou
        'ip': [
475 fff8bd58 Kostas Papadimitriou
          ['floating_ip_adress'], function() {
476 fff8bd58 Kostas Papadimitriou
            return this.get('floating_ip_address'); 
477 fff8bd58 Kostas Papadimitriou
        }],
478 fff8bd58 Kostas Papadimitriou
479 fff8bd58 Kostas Papadimitriou
        'in_progress': [
480 fff8bd58 Kostas Papadimitriou
          ['status'], function() {
481 fff8bd58 Kostas Papadimitriou
            return _.contains(['CONNECTING', 'DISCONNECTING', 'REMOVING'], 
482 fff8bd58 Kostas Papadimitriou
                              this.get('status'))
483 fff8bd58 Kostas Papadimitriou
          }  
484 fff8bd58 Kostas Papadimitriou
        ],
485 fff8bd58 Kostas Papadimitriou
486 fff8bd58 Kostas Papadimitriou
        'status': [
487 fff8bd58 Kostas Papadimitriou
          ['port_id', 'port'], function() {
488 176921aa Kostas Papadimitriou
            var port_id = this.get('port_id');
489 176921aa Kostas Papadimitriou
            if (!port_id) {
490 176921aa Kostas Papadimitriou
              return 'DISCONNECTED'
491 fff8bd58 Kostas Papadimitriou
            } else {
492 176921aa Kostas Papadimitriou
              var port = this.get('port');
493 176921aa Kostas Papadimitriou
              if (port) {
494 5475c563 Kostas Papadimitriou
                var port_status = port.get('ext_status');
495 176921aa Kostas Papadimitriou
                if (port_status == "DISCONNECTING") {
496 176921aa Kostas Papadimitriou
                  return port_status
497 176921aa Kostas Papadimitriou
                }
498 e6a4b75c Kostas Papadimitriou
                if (port_status == "CONNECTING") {
499 e6a4b75c Kostas Papadimitriou
                  return port_status
500 e6a4b75c Kostas Papadimitriou
                }
501 fff8bd58 Kostas Papadimitriou
                return 'CONNECTED'
502 fff8bd58 Kostas Papadimitriou
              }
503 5475c563 Kostas Papadimitriou
              return 'CONNECTING'  
504 fff8bd58 Kostas Papadimitriou
            }
505 fff8bd58 Kostas Papadimitriou
          }
506 fff8bd58 Kostas Papadimitriou
        ]
507 fff8bd58 Kostas Papadimitriou
      },
508 213a8396 Kostas Papadimitriou
      
509 fff8bd58 Kostas Papadimitriou
      disconnect: function(cb) {
510 27d628c4 Kostas Papadimitriou
        this.get('port').disconnect(cb);
511 fff8bd58 Kostas Papadimitriou
      }
512 fff8bd58 Kostas Papadimitriou
    });
513 fff8bd58 Kostas Papadimitriou
514 fff8bd58 Kostas Papadimitriou
    models.FloatingIPs = models.NetworkCollection.extend({
515 fff8bd58 Kostas Papadimitriou
      model: models.FloatingIP,
516 fff8bd58 Kostas Papadimitriou
      details: false,
517 fff8bd58 Kostas Papadimitriou
      path: 'floatingips',
518 fff8bd58 Kostas Papadimitriou
      parse: function(resp) {
519 fff8bd58 Kostas Papadimitriou
        return resp.floatingips;
520 fff8bd58 Kostas Papadimitriou
      }
521 fff8bd58 Kostas Papadimitriou
    });
522 fff8bd58 Kostas Papadimitriou
523 fff8bd58 Kostas Papadimitriou
    models.Router = models.NetworkModel.extend({
524 fff8bd58 Kostas Papadimitriou
    });
525 fff8bd58 Kostas Papadimitriou
526 fff8bd58 Kostas Papadimitriou
    models.Routers = models.NetworkCollection.extend({
527 fff8bd58 Kostas Papadimitriou
      model: models.Router,
528 fff8bd58 Kostas Papadimitriou
      path: 'routers',
529 fff8bd58 Kostas Papadimitriou
      parse: function(resp) {
530 fff8bd58 Kostas Papadimitriou
        return resp.routers
531 fff8bd58 Kostas Papadimitriou
      }
532 fff8bd58 Kostas Papadimitriou
    });
533 fff8bd58 Kostas Papadimitriou
534 fff8bd58 Kostas Papadimitriou
    snf.storage.floating_ips = new models.FloatingIPs();
535 fff8bd58 Kostas Papadimitriou
    snf.storage.routers = new models.Routers();
536 fff8bd58 Kostas Papadimitriou
    snf.storage.networks = new models.Networks();
537 fff8bd58 Kostas Papadimitriou
    snf.storage.ports = new models.Ports();
538 fff8bd58 Kostas Papadimitriou
    snf.storage.subnets = new models.Subnets();
539 fff8bd58 Kostas Papadimitriou
540 fff8bd58 Kostas Papadimitriou
})(this);