27
27
from melange.common import exception
28
28
from melange.common import utils
30
from sqlalchemy.orm import (relationship, backref,lazyload,joinedload,
31
exc , object_mapper, validates)
32
from sqlalchemy import Column, Integer, String, BigInteger
33
from sqlalchemy import ForeignKey, DateTime, Boolean, Text
34
from sqlalchemy import UniqueConstraint
35
from sqlalchemy.ext.declarative import declarative_base
37
30
from melange.common import exception
38
from melange.db import session
43
BASE = declarative_base()
31
from melange.db import api as db_api
45
33
class ModelBase(object):
46
"""Base class for Melange Models"""
47
__table_args__ = {'mysql_engine': 'InnoDB'}
48
__table_initialized__ = False
49
__protected_attributes__ = set([
50
"created_at", "updated_at", "deleted_at", "deleted"])
52
created_at = Column(DateTime, default=datetime.datetime.utcnow,
54
updated_at = Column(DateTime, onupdate=datetime.datetime.utcnow)
57
36
def create(cls, values, db_session=None):
59
38
instance.update(values)
60
return instance.save(db_session)
39
return db_api.save(instance)
62
def save(self, db_session=None):
63
"""Save this object"""
64
db_session = db_session or session.get_session()
66
self.db_session = db_session
43
return db_api.find(cls,id)
70
45
def update(self, values):
71
46
"""dict.update() behaviour."""
72
47
for k, v in values.iteritems():
76
def find(cls,id,db_session=None):
77
db_session = db_session or session.get_session()
78
x = db_session.query(cls).filter_by(id=id).first()
79
x.db_session = db_session
82
50
def __setitem__(self, key, value):
83
51
setattr(self, key, value)
105
73
def to_dict(self):
106
74
return self.__dict__.copy()
108
class IpBlock(BASE, ModelBase):
109
__tablename__ = 'ip_blocks'
111
id = Column(Integer, primary_key=True)
112
network_id = Column(String(255), nullable=True)
113
cidr = Column(String(255), nullable=False)
76
class IpBlock(ModelBase):
116
79
def find_by_network_id(cls, network_id):
117
return session.get_session().\
118
query(IpBlock).filter_by(network_id=network_id).first()
80
return db_api.ip_block_find_by_network_id(network_id)
120
82
def allocate_ip(self, port_id=None):
121
83
from IPy import IP
122
84
candidate_ip = None
85
allocated_addresses = [ip_addr.address
87
db_api.ip_address_find_all_by_ip_block(self.id)]
124
89
#TODO:very inefficient way to generate ips,
125
90
#will look at better algos for this
126
91
for ip in IP(self.cidr):
127
if str(ip) not in [ip_addr.address for ip_addr in self.ip_addresses]:
92
if str(ip) not in allocated_addresses:
128
93
candidate_ip = str(ip)
130
return IpAddress.create({'address':candidate_ip,
95
return db_api.save(IpAddress.create({'address':candidate_ip,
131
96
'port_id':port_id,'allocated':True,
132
'ip_block':self},self.db_session)
97
'ip_block_id':self.id}))
134
class IpAddress(BASE, ModelBase):
135
__tablename__ = 'ip_addresses'
137
id = Column(Integer, primary_key=True)
138
address = Column(String(255),nullable=False)
139
allocated = Column(String(255), nullable=False)
140
port_id = Column(String(255),nullable=True)
141
ip_block_id = Column(Integer(),ForeignKey('ip_blocks.id'),nullable=True)
142
ip_block = relationship(IpBlock, backref=backref('ip_addresses'))
99
class IpAddress(ModelBase):
102
def find_all_by_ip_block(cls,ip_block_id):
103
return db_api.ip_address_find_all_by_ip_block(ip_block_id)
107
return {'IpBlock':IpBlock,'IpAddress':IpAddress}