def set(self, key, value): if key == 'ip': net = Network(id=self._json['network'].id, mongo_db=self._mongo_db) if self._json['ip']: net.release_ip(self._json['ip']) ip = net.reserve_ip(value) ret = super(Switch, self).set('ip', ip) return ret elif key == 'network': net = Network(id=self._json['network'].id, mongo_db=self._mongo_db) ip = self._json['ip'] new_net = Network(name=value, mongo_db=self._mongo_db) if net.DBRef == new_net.DBRef: return None new_ip = ip if not new_net.reserve_ip(new_ip): return None net.release_ip(ip) self.unlink(net) ret = super(Switch, self).set('network', new_net.DBRef) self.link(new_net) return ret else: return super(Switch, self).set(key, value)
def __init__(self, name=None, mongo_db=None, create=False, id=None, network=None, ip=None, comment=''): """ network - the network the device is connected to ip - device's ip """ self.log.debug("function args {}".format(self._debug_function())) # Define the schema used to represent otherdev objects self._collection_name = 'otherdev' self._keylist = {'comment': type('')} # Check if this device is already present in the datastore # Read it if that is the case dev = self._get_object(name, mongo_db, create, id) if create: cluster = Cluster(mongo_db=self._mongo_db) if not network: connected = {} elif not ip: err_msg = "IP needs to be specified" self.log.error(err_msg) raise RuntimeError, err_msg else: net = Network(name=network, mongo_db=self._mongo_db) ipnum = net.reserve_ip(ip, ignore_errors=False) if not ipnum: err_msg = "Unable to allocate IP in network" self.log.error(err_msg) raise RuntimeError, err_msg connected = {str(net.DBRef.id): ipnum} # Store the new device in the datastore dev = {'name': name, 'connected': connected, 'comment': comment} self.log.debug("Saving dev '{}' to the datastore".format(dev)) self.store(dev) # Link this device to its dependencies and the current cluster self.link(cluster) if connected and net: self.link(net) self.log = logging.getLogger('otherdev.' + self._name)
def set_ip(self, network=None, ip=None): if not network: self.log.error("Network needs to be specified") return None if not ip: return self.del_net(network=network) connected = self.get('connected') link = True net = Network(name=network, mongo_db=self._mongo_db) if str(net.id) in connected: net.release_ip(connected[str(net.id)]) link = False ip = net.reserve_ip(ip) if not ip: return None connected[str(net.id)] = ip res = self.set('connected', connected) if link: self.link(net) return res
def set(self, key, value): if not bool(key) or type(key) is not str : self._logger.error("Field should be specified") return None if not key in self._keylist: self._logger.error("Cannot change '{}' field".format(key)) return None obj_json = self._get_json() if key == 'ip': net_dbref = obj_json['network'] old_ip = obj_json['ip'] net = Network(id = net_dbref.id, mongo_db = self._mongo_db) if not net.ip_in_net(value): self._logger.error("This IP: '{}' does not belong to defined network.".format(value)) return None if old_ip: net.release_ip(old_ip) ip = net.reserve_ip(value) obj_json['ip'] = ip ret = self._mongo_collection.update({'_id': self._id}, {'$set': obj_json}, multi=False, upsert=False) return not ret['err'] if key == 'network': old_net_dbref = obj_json['network'] old_net = Network(id = old_net_dbref.id, mongo_db = self._mongo_db) old_ip_rel = obj_json['ip'] old_ip_human_readable = self.get('ip') new_net = Network(name = value, mongo_db = self._mongo_db) if old_net.DBRef == new_net.DBRef: return None new_ip_rel = old_ip_rel new_ip_human_readable = new_net.relnum_to_ip(new_ip_rel) if not new_net.reserve_ip(new_ip_human_readable): return None old_net.release_ip(old_ip_human_readable) obj_json['network'] = new_net.DBRef ret = self._mongo_collection.update({'_id': self._id}, {'$set': obj_json}, multi=False, upsert=False) self.link(new_net) self.unlink(old_net) return not ret['err'] return super(Switch, self).set(key, value)
def set(self, key, value): if not bool(key) or type(key) is not str : self._logger.error("Field should be specified") return None if not key in self._keylist: self._logger.error("Cannot change '{}' field".format(key)) return None obj_json = self._get_json() if key == 'ip': net_dbref = obj_json['network'] old_ip = obj_json['ip'] net = Network(id = net_dbref.id, mongo_db = self._mongo_db) if not utils.ip.ip_in_net(value, net._get_json['NETWORK'], net._get_json['PREFIX']): self._logger.error("This IP: '{}' does not belong to defined network.".format(value)) return None if old_ip: net.release_ip(old_ip) ip = net.reserve_ip(value) obj_json['ip'] = ip ret = self._mongo_collection.update({'_id': self._id}, {'$set': obj_json}, multi=False, upsert=False) return not ret['err'] if key == 'network': old_net_dbref = obj_json['network'] old_net = Network(id = old_net_dbref.id, mongo_db = self._mongo_db) old_ip_rel = obj_json['ip'] old_ip_human_readable = self.get('ip') new_net = Network(name = value, mongo_db = self._mongo_db) if old_net.DBRef == new_net.DBRef: return None new_ip_rel = old_ip_rel new_ip_human_readable = utils.ip.reltoa(new_net._get_json()['NETWORK'], new_ip_rel) if not new_net.reserve_ip(new_ip_human_readable): return None old_net.release_ip(old_ip_human_readable) obj_json['network'] = new_net.DBRef ret = self._mongo_collection.update({'_id': self._id}, {'$set': obj_json}, multi=False, upsert=False) self.link(new_net) self.unlink(old_net) return not ret['err'] return super(Switch, self).set(key, value)
def _reserve_bmc_ip(self, ip = None): if not self._id: self._logger.error("Was object deleted?") return None try: net_dbref = self._get_json()['bmcnetwork'] except: self._logger.error("No bmc network configured") return None if not bool(net_dbref): self._logger.warning("No network configured for BMC interface") return None net = Network(id = net_dbref.id, mongo_db = self._mongo_db) return net.reserve_ip(ip)
def makedhcp(self, netname, startip, endip, no_ha = False): from luna.network import Network from bson.objectid import ObjectId try: if bool(netname): objnet = Network(name = netname, mongo_db = self._mongo_db) except: ojbnet = None if not bool(objnet): self._logger.error("Proper DHCP network should be specified.") return None if not bool(startip) or not bool(endip): self._logger.error("First and last IPs of range should be specified.") return None if not bool(self.get_cluster_ips()): no_ha = True n = objnet._get_json() startip = utils.ip.atorel(startip, n['NETWORK'], n['PREFIX']) endip = utils.ip.atorel(endip, n['NETWORK'], n['PREFIX']) if not bool(startip) or not bool(endip): self._logger.error("Error in acquiring IPs.") return None obj_json = self._get_json() (oldnetid, oldstartip, oldendip) = (None, None, None) try: oldnetid = obj_json['dhcp_net'] oldstartip = obj_json['dhcp_range_start'] oldendip = obj_json['dhcp_range_end'] except: (oldnetid, oldstartip, oldendip) = (None, None, None) if str(oldnetid) == str(objnet.id): objnet.release_ip(oldstartip, oldendip) self.unlink(objnet) (oldnetid, oldstartip, oldendip) = (None, None, None) res = objnet.reserve_ip(startip, endip) if not bool(res): self._logger.error("Cannot reserve IP range for DHCP.") super(Cluster, self).set('dhcp_net', str(objnet.id)) super(Cluster, self).set('dhcp_range_start', startip) super(Cluster, self).set('dhcp_range_end', endip) self.link(objnet) if bool(oldnetid) and bool(oldstartip) and bool(oldendip): oldnet_obj = Network(id = ObjectId(oldnetid), mongo_db = self._mongo_db) self.unlink(oldnet_obj) oldnet_obj.release_ip(oldstartip, oldendip) self._create_dhcp_config(no_ha) return True
def _reserve_ip(self, interface = None, ip = None): if not bool(interface): self._logger.error("Interface needs to be specified") return None if not self._id: self._logger.error("Was object deleted?") return None try: net_dbref = self._get_json()['interfaces'][interface]['network'] except: self._logger.error("No such interface '{}'".format(interface)) return None if not bool(net_dbref): self._logger.warning("No network configured for interface '{}'".format(interface)) return None net = Network(id = net_dbref.id, mongo_db = self._mongo_db) return net.reserve_ip(ip)
def makedhcp(self, netname, startip, endip, no_ha = False): from luna.network import Network from bson.objectid import ObjectId try: if bool(netname): objnet = Network(name = netname, mongo_db = self._mongo_db) except: ojbnet = None if not bool(objnet): self._logger.error("Proper DHCP network should be specified.") return None if not bool(startip) or not bool(endip): self._logger.error("First and last IPs of range should be specified.") return None if not bool(self.get_cluster_ips()): no_ha = True startip = objnet.ip_to_relnum(startip) endip = objnet.ip_to_relnum(endip) if not bool(startip) or not bool(endip): self._logger.error("Error in acquiring IPs.") return None obj_json = self._get_json() (oldnetid, oldstartip, oldendip) = (None, None, None) try: oldnetid = obj_json['dhcp_net'] oldstartip = obj_json['dhcp_range_start'] oldendip = obj_json['dhcp_range_end'] except: (oldnetid, oldstartip, oldendip) = (None, None, None) if str(oldnetid) == str(objnet.id): objnet.release_ip(oldstartip, oldendip) self.unlink(objnet) (oldnetid, oldstartip, oldendip) = (None, None, None) res = objnet.reserve_ip(startip, endip) if not bool(res): self._logger.error("Cannot reserve IP range for DHCP.") super(Cluster, self).set('dhcp_net', str(objnet.id)) super(Cluster, self).set('dhcp_range_start', startip) super(Cluster, self).set('dhcp_range_end', endip) self.link(objnet) if bool(oldnetid) and bool(oldstartip) and bool(oldendip): oldnet_obj = Network(id = ObjectId(oldnetid), mongo_db = self._mongo_db) self.unlink(oldnet_obj) oldnet_obj.release_ip(oldstartip, oldendip) self._create_dhcp_config(no_ha) return True
def set_ip(self, network = None, ip = None): if not bool(network): self._logger.error("Network should be specified") return None if not bool(ip): return self.del_net(network = network) obj_json = self._get_json() net = Network(name = network, mongo_db = self._mongo_db) try: old_rel_ip = obj_json['connected'][str(net.DBRef.id)] except: old_rel_ip = None if old_rel_ip: net.release_ip(net.relnum_to_ip(old_rel_ip)) new_ip = net.reserve_ip(ip) if not new_ip: return None obj_json['connected'][str(net.DBRef.id)] = new_ip ret = self._mongo_collection.update({'_id': self._id}, {'$set': obj_json}, multi=False, upsert=False) if not old_rel_ip: self.link(net)
def set_ip(self, network = None, ip = None): if not bool(network): self._logger.error("Network should be specified") return None if not bool(ip): return self.del_net(network = network) obj_json = self._get_json() net = Network(name = network, mongo_db = self._mongo_db) try: old_rel_ip = obj_json['connected'][str(net.DBRef.id)] except: old_rel_ip = None if old_rel_ip: net.release_ip(utils.ip.reltoa(net._get_json()['NETWORK'], old_rel_ip)) new_ip = net.reserve_ip(ip) if not new_ip: return None obj_json['connected'][str(net.DBRef.id)] = new_ip ret = self._mongo_collection.update({'_id': self._id}, {'$set': obj_json}, multi=False, upsert=False) if not old_rel_ip: self.link(net)
def __init__(self, name = None, mongo_db = None, create = False, id = None, network = None, ip = None): """ netwwork - network device connected ip - ip of the switch """ self._logger.debug("Arguments to function '{}".format(self._debug_function())) self._collection_name = 'otherdev' mongo_doc = self._check_name(name, mongo_db, create, id) self._keylist = {} if create: cluster = Cluster(mongo_db = self._mongo_db) passed_vars = inspect.currentframe().f_locals for key in self._keylist: if type(passed_vars[key]) is not self._keylist[key]: self._logger.error("Argument '{}' should be '{}'".format(key, self._keylist[key])) raise RuntimeError if not bool(network): connected = {} else: if not bool(ip): self._logger.error("IP needs to be specified") raise RuntimeError net = Network(name = network, mongo_db = self._mongo_db) ip = net.reserve_ip(ip, ignore_errors = False) if not bool(ip): raise RuntimeError connected = {str(net.DBRef.id): ip} mongo_doc = { 'name': name, 'connected': connected} self._logger.debug("mongo_doc: '{}'".format(mongo_doc)) self._name = name self._id = self._mongo_collection.insert(mongo_doc) self._DBRef = DBRef(self._collection_name, self._id) self.link(cluster) if bool(connected): self.link(net) else: self._name = mongo_doc['name'] self._id = mongo_doc['_id'] self._DBRef = DBRef(self._collection_name, self._id)
def __init__(self, name = None, mongo_db = None, create = False, id = None, network = None, ip = None, read = 'public', rw = 'private', oid = None): """ ip - ip of the switch read - read community rw - rw community oid - could be, for instance .1.3.6.1.2.1.17.7.1.2.2.1.2 .1.3.6.1.2.1.17.4.3.1.2 .1.3.6.1.2.1.17.7.1.2.2 .1.3.6.1.2.1.17.4.3.1.2 """ self._logger.debug("Arguments to function '{}".format(self._debug_function())) self._collection_name = 'switch' mongo_doc = self._check_name(name, mongo_db, create, id) self._keylist = { 'ip': type(''), 'read': type(''), 'rw': type(''), 'oid': type(''), 'network': type('')} if create: cluster = Cluster(mongo_db = self._mongo_db) passed_vars = inspect.currentframe().f_locals for key in self._keylist: if type(passed_vars[key]) is not self._keylist[key]: self._logger.error("Argument '{}' should be '{}'".format(key, self._keylist[key])) raise RuntimeError net = Network(name = network, mongo_db = self._mongo_db) ip = net.reserve_ip(ip) if not bool(ip): self._logger.error("Could not acquire ip for switch.") raise RuntimeError mongo_doc = { 'name': name, 'network': net.DBRef, 'ip': ip, 'read': read, 'rw': rw, 'oid': oid} self._logger.debug("mongo_doc: '{}'".format(mongo_doc)) self._name = name self._id = self._mongo_collection.insert(mongo_doc) self._DBRef = DBRef(self._collection_name, self._id) self.link(cluster) self.link(net) else: self._name = mongo_doc['name'] self._id = mongo_doc['_id'] self._DBRef = DBRef(self._collection_name, self._id)
def __init__(self, name=None, mongo_db=None, create=False, id=None, network=None, ip=None, read='public', rw='private', oid=None, comment=''): """ ip - ip of the switch read - read community rw - rw community oid - could be, for instance .1.3.6.1.2.1.17.7.1.2.2.1.2 .1.3.6.1.2.1.17.4.3.1.2 .1.3.6.1.2.1.17.7.1.2.2 .1.3.6.1.2.1.17.4.3.1.2 """ self.log.debug("function args {}".format(self._debug_function())) # Define the schema used to represent switch objects self._collection_name = 'switch' self._keylist = { 'read': type(''), 'rw': type(''), 'oid': type(''), 'comment': type(''), } # Check if this switch is already present in the datastore # Read it if that is the case switch = self._get_object(name, mongo_db, create, id) if create: cluster = Cluster(mongo_db=self._mongo_db) if not network: err_msg = "Network must be provided" self.log.error(err_msg) raise RuntimeError, err_msg if not name: err_msg = "Name must be provided" self.log.error(err_msg) raise RuntimeError, err_msg net = Network(name=network, mongo_db=self._mongo_db) ip = net.reserve_ip(ip) if not ip: err_msg = "Could not acquire ip for switch" self.log.error(err_msg) raise RuntimeError, err_msg # Store the new switch in the datastore switch = { 'name': name, 'network': net.DBRef, 'ip': ip, 'read': read, 'rw': rw, 'oid': oid, 'comment': comment } self.log.debug( "Saving switch '{}' to the datastore".format(switch)) self.store(switch) # Link this switch to its dependencies and the current cluster self.link(cluster) self.link(net) self.log = logging.getLogger('switch.' + self._name)
def makedhcp_config(self, net_name=None, start_ip=None, end_ip=None): from luna.network import Network if net_name and not (start_ip and end_ip): self.log.error("IP range should be specified.") return {} old_net_name = self.get('dhcp_net') if not (old_net_name or net_name): self.log.error("DHCP network should be specified.") return {} frontend_address = self.get('frontend_address') if not frontend_address: self.log.error("Frontend address should be set.") return {} net_obj = None start_ip_num, end_ip_num = None, None if net_name: net_obj = Network(name=net_name, mongo_db=self._mongo_db) if net_obj.version != 4: self.log.error("Only IPv4 networks are supported.") return {} start_ip_num = None frontend_address_num = None end_ip_num = None try: start_ip_num = utils.ip.atorel( start_ip, net_obj._json['NETWORK'], net_obj._json['PREFIX']) frontend_address_num = utils.ip.atorel( frontend_address, net_obj._json['NETWORK'], net_obj._json['PREFIX']) end_ip_num = utils.ip.atorel( end_ip, net_obj._json['NETWORK'], net_obj._json['PREFIX']) except RuntimeError: # utils.ip will print error messages pass if not start_ip_num: self.log.error( 'Start of the range does not belong to network.') return {} if not start_ip_num: self.log.error( 'End of the range does not belong to network.') return {} if not frontend_address_num: self.log.error( 'Frontend IP does not belong to network.') return {} if end_ip_num < start_ip_num: self.log.error( 'End IP of the range should be larger than start.') return {} old_net_obj = None old_start_ip = None old_end_ip = None if old_net_name and net_name: # release old range old_net_obj = Network(name=old_net_name, mongo_db=self._mongo_db) old_start_ip = self.get('dhcp_range_start') old_end_ip = self.get('dhcp_range_end') res = old_net_obj.release_ip(old_start_ip, old_end_ip) if not res: self.log.error('Unable to release old range.') return {} self.unlink(old_net_obj) if net_name: # now try to reserve new range net_obj = Network(name=net_name, mongo_db=self._mongo_db) res = net_obj.reserve_ip(start_ip_num, end_ip_num) if not res: if old_net_obj: # need to rolback old_net_obj.reserve_ip(old_start_ip, old_end_ip) self.log.error('Unable to reserve new range.') return {} super(Cluster, self).set('dhcp_net', str(net_obj.id)) super(Cluster, self).set('dhcp_range_start', start_ip_num) super(Cluster, self).set('dhcp_range_end', end_ip_num) self.link(net_obj) # get actual options c = {} if self.get('frontend_https'): c['protocol'] = 'https' else: c['protocol'] = 'http' c['frontend_ip'] = self.get('frontend_address') c['dhcp_start'] = self.get('dhcp_range_start') c['dhcp_end'] = self.get('dhcp_range_end') c['frontend_port'] = self.get('frontend_port') netname = self.get('dhcp_net') objnet = Network(name=netname, mongo_db=self._mongo_db) c['netmask'] = objnet.get('NETMASK') c['network'] = objnet.get('NETWORK') c['hmac_key'] = str( base64.b64encode(bytearray(os.urandom(32))).decode() ) c['reservations'] = objnet.get_ip_macs() return c
def __init__(self, name=None, mongo_db=None, create=False, id=None, network=None, ip=None, read='public', rw='private', oid=None, comment=''): """ ip - ip of the switch read - read community rw - rw community oid - could be, for instance .1.3.6.1.2.1.17.7.1.2.2.1.2 .1.3.6.1.2.1.17.4.3.1.2 .1.3.6.1.2.1.17.7.1.2.2 .1.3.6.1.2.1.17.4.3.1.2 """ self.log.debug("function args {}".format(self._debug_function())) # Define the schema used to represent switch objects self._collection_name = 'switch' self._keylist = { 'read': type(''), 'rw': type(''), 'oid': type(''), 'comment': type(''), } # Check if this switch is already present in the datastore # Read it if that is the case switch = self._get_object(name, mongo_db, create, id) if create: cluster = Cluster(mongo_db=self._mongo_db) if not network: err_msg = "Network must be provided" self.log.error(err_msg) raise RuntimeError, err_msg if not name: err_msg = "Name must be provided" self.log.error(err_msg) raise RuntimeError, err_msg net = Network(name=network, mongo_db=self._mongo_db) ip = net.reserve_ip(ip) if not ip: err_msg = "Could not acquire ip for switch" self.log.error(err_msg) raise RuntimeError, err_msg # Store the new switch in the datastore switch = {'name': name, 'network': net.DBRef, 'ip': ip, 'read': read, 'rw': rw, 'oid': oid, 'comment': comment} self.log.debug("Saving switch '{}' to the datastore" .format(switch)) self.store(switch) # Link this switch to its dependencies and the current cluster self.link(cluster) self.link(net) self.log = logging.getLogger('switch.' + self._name)
def manage_ip(self, interface_uuid=None, ip=None, release=False, version=None): """ operations with IP: add/delete """ if version: version = str(version) if version and version not in ['4', '6']: self.log.error("Only IPv4 and IPv6 are supported") return False if interface_uuid not in self.get('interfaces'): self.log.error("Interface {} does not exixt" .format(interface_uuid)) return False interface_name = self.get('interfaces')[interface_uuid]['name'] net4_dbref = self.get('interfaces')[interface_uuid]['network']['4'] net6_dbref = self.get('interfaces')[interface_uuid]['network']['6'] if not version: if net4_dbref and net6_dbref: self.log.error( ("Both IPv4 and IPv6 " + "are configured for the interface {}. " + "Version needs to be specified.") .format(interface_name) ) return False if not version and not net4_dbref and not net6_dbref: self.log.warning("Network is not configured for the interface {}." .format(interface_name)) return False net_dbref = net4_dbref if not version: if net6_dbref: net_dbref = net6_dbref else: if int(version) == 6: net_dbref = net6_dbref if not net_dbref: self.log.warning( "Network IPv{} is not configured for the interface {}." .format(version, interface_name) ) return False net_obj = Network(id=net_dbref.id, mongo_db=self._mongo_db) self._invalidate_network(net_obj) if release and ip: return net_obj.release_ip(ip) else: return net_obj.reserve_ip(ip)