from copy import deepcopy import main from core.bot import IRCBotFactory from modules import alias from modules.chankeep import nukeNetwork from modules.provision import provisionRelay from modules.regproc import needToRegister from twisted.internet import reactor from twisted.internet.ssl import DefaultOpenSSLContextFactory from utils.deliver_relay_commands import deliverRelayCommands from utils.get import getRelay from utils.logging.log import log def migrate(): existing = deepcopy(main.network) log("Migrating network configuration") log(f"Existing network configuration: {existing}") for net, net_inst in existing.items(): log(f"Migrating network {net}") net = net_inst.net host = net_inst.host port = net_inst.port security = net_inst.security auth = net_inst.auth last = net_inst.last relays = net_inst.relays aliases = net_inst.aliases new_net = Network(net, host, port, security, auth) log(f"New network for {net}: {new_net}") new_net.last = last new_net.relays = relays new_net.aliases = aliases main.network[net] = new_net main.saveConf("network") log("Finished migrating network configuration") class Network: def __init__(self, net, host, port, security, auth): self.net = net self.host = host self.port = port self.security = security self.auth = auth self.chanlimit = None self.last = 1 self.relays = {} self.aliases = {} def add_relay(self, num=None): # Grrrrrrrrrr self.last = int(self.last) if not num: num = self.last self.last += 1 elif num == self.last: self.last += 1 registered = False if not needToRegister(self.net): registered = True # Don't need to register if it's been disabled in definitions, # so we'll pretend we already did self.relays[num] = { "enabled": main.config["ConnectOnCreate"], "net": self.net, "id": num, "registered": registered, } password = alias.generate_password() if num not in main.alias.keys(): main.alias[num] = alias.generate_alias() main.saveConf("alias") self.aliases[num] = {"password": password} # if main.config["ConnectOnCreate"]: -- Done in provision # self.start_bot(num) provisionRelay(num, self.net) return num, main.alias[num]["nick"] def enable_relay(self, num): """ Enable a relay for this network. Send a command to ZNC to connect. """ self.relays[num]["enabled"] = True user = main.alias[num]["nick"] commands = {"status": ["Connect"]} name = f"{self.net}{num}" deliverRelayCommands(num, commands, user=user + "/" + self.net) main.saveConf("network") if name not in main.IRCPool.keys(): self.start_bot(num) def disable_relay(self, num): """ Disable a relay for this network. Send a command to ZNC to disconnect. Stop trying to connect to the relay. """ self.relays[num]["enabled"] = False user = main.alias[num]["nick"] # relay = main.network[spl[1]].relays[relayNum] commands = {"status": ["Disconnect"]} name = f"{self.net}{num}" deliverRelayCommands(num, commands, user=user + "/" + self.net) main.saveConf("network") if name in main.ReactorPool.keys(): if name in main.FactoryPool.keys(): main.FactoryPool[name].stopTrying() main.ReactorPool[name].disconnect() if name in main.IRCPool.keys(): del main.IRCPool[name] del main.ReactorPool[name] del main.FactoryPool[name] def killAliases(self, aliasList): for i in aliasList: name = self.net + str(i) if name in main.ReactorPool.keys(): if name in main.FactoryPool.keys(): main.FactoryPool[name].stopTrying() main.ReactorPool[name].disconnect() if name in main.IRCPool.keys(): del main.IRCPool[name] del main.ReactorPool[name] del main.FactoryPool[name] def delete_relay(self, id): del self.relays[id] del self.aliases[id] # del main.alias[id] - Aliases are global per num, so don't delete them! self.killAliases([id]) def seppuku(self): # Removes all bots in preperation for deletion self.killAliases(self.relays.keys()) nukeNetwork(self.net) def start_bot(self, num): # a single name is given to relays in the backend # e.g. freenode1 for the first relay on freenode network keyFN = main.certPath + main.config["Key"] certFN = main.certPath + main.config["Certificate"] contextFactory = DefaultOpenSSLContextFactory( keyFN.encode("utf-8", "replace"), certFN.encode("utf-8", "replace") ) bot = IRCBotFactory(self.net, num) # host, port = self.relays[num]["host"], self.relays[num]["port"] host, port = getRelay(num) rct = reactor.connectSSL(host, port, bot, contextFactory) name = self.net + str(num) main.ReactorPool[name] = rct main.FactoryPool[name] = bot log("Started bot on relay %s on %s" % (num, self.host)) def start_bots(self): for num in self.relays.keys(): if self.relays[num]["enabled"]: self.start_bot(num)