def stop_forwarding(self): LOG.debug("Reverting changes needed for access to admin network") ssh = paramiko.client.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: ssh.connect(hostname=self.os_data["ips"]["controller"], username=self.os_data['auth']['controller_uname'], password=self.os_data['auth']['controller_pwd']) except Exception: LOG.critical("SSH is broken! Please revert port forwarding on your" " controller manually") LOG.debug(traceback.format_exc()) return ssh.exec_command("ps aux | grep '[s]sh -o Preferred' | " "awk '{ print $2 }'| xargs kill") ssh.exec_command("iptables -L -n --line-numbers | grep MCV_tunnel | " "awk '{print $1}' | xargs iptables -D INPUT") subprocess.call("sudo iptables -L -n -t nat --line-numbers | " "grep MCV_instance | awk '{print $1}' | tac | " "xargs -l sudo iptables -t nat -D PREROUTING", shell=True)
def check_and_fix_iptables_rule(self): # TODO(aovchinnikov): divide this some day # TODO(aovchinnikov): this might change so it is much wiser # to do actual check keystone_private_endpoint_ip = self.get_private_endpoint_ip() port_substitution = {"cnt_ip": self.os_data["ips"]["controller"], "kpeip": keystone_private_endpoint_ip, } mk_rule = ("iptables -I INPUT 1 -p tcp -m tcp --dport 7654 -j ACCEPT " "-m comment --comment \'MCV_tunnel\'") rkname = "remote_mcv_key" mk_port = "ssh -o PreferredAuthentications=publickey -o "\ "StrictHostKeyChecking=no -i " + rkname + " -f -N -L "\ "%(cnt_ip)s:7654:%(kpeip)s:35357 localhost" %\ port_substitution ssh = paramiko.client.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: ssh.connect(hostname=self.os_data["ips"]["controller"], username=self.os_data['auth']['controller_uname'], password=self.os_data['auth']['controller_pwd'], timeout=10) except paramiko.AuthenticationException: LOG.critical("Can not access controller via ssh " "with provided credentials!") return -1 except paramiko.SSHException as ssh_e: LOG.critical( "SSH error: can not access controller - %s" % str(ssh_e)) return -1 except socket.error as sock_e: LOG.critical( "Socket error: can not access controller via ssh - %s" % str( sock_e)) return -1 ssh.exec_command("ssh-keygen -f" + rkname + " -N '' > /dev/null 2>&1") # TODO(mcv-team): ok, this should not be done by sleeping time.sleep(3) ssh.exec_command("cat " + rkname + ".pub >> .ssh/authorized_keys") time.sleep(3) stdin, stdout, stderr = ssh.exec_command("iptables -L -n") if stdout.read().find("MCV_tunnel") == -1: LOG.debug("There is no rule in controller's iptables " "for proper forwarding! Have to add one") ssh.exec_command(mk_rule) else: LOG.debug("Controller's iptables rule seems to be in place") result = None while result is None: stdin, stdout, stderr = ssh.exec_command("ps aux") result = re.search("ssh.*35357", stdout.read()) if result is None: LOG.debug("Apparently port forwarding on the controller " "is not set up properly") time.sleep(3) ssh.exec_command(mk_port) time.sleep(5) else: LOG.debug("Apparently port forwarding on the " "controller is set") ssh.exec_command("rm " + rkname + "*") res = subprocess.Popen(["sudo", "iptables", "-t", "nat", "-L -n", ], shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=utils.ignore_sigint).stdout.read() if re.search("DNAT.*7654\n", res) is not None: # leave slowly, don't wake it up LOG.debug("Local iptables rule is set.") return cmd = "sudo iptables -L -n -t nat --line-numbers " \ "| grep MCV_instance 1>/dev/null && echo -n YES || echo -n NO" out = utils.run_cmd(cmd) if out == 'NO': destination = "%s:7654" % self.os_data["ips"]["controller"] # TODO(albartash): rewrite with run_cmd() res = subprocess.Popen(["sudo", "iptables", "-t", "nat", "-I", "PREROUTING", "1", "-d", self.get_private_endpoint_ip(), "-p", "tcp", "--dport", "35357", "-j", "DNAT", "--to-destination", destination, "-m", "comment", "--comment", "\'MCV_instance\'"], stdout=subprocess.PIPE, preexec_fn=utils.ignore_sigint ).stdout.read() LOG.debug("Now local iptables rule is set.")