Statistics
| Branch: | Tag: | Revision:

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

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