def check_if_machine_accessible(self, machine): """Attempt to port knock and ping the machine""" assert machine.cloud.id == self.cloud.id hostname = machine.hostname or (machine.private_ips[0] if machine.private_ips else '') if not hostname: return False ports_list = [22, 80, 443, 3389] for port in (machine.ssh_port, machine.rdp_port): if port and port not in ports_list: ports_list.insert(0, port) socket_timeout = 3 # add timeout for socket for port in ports_list: log.info("Attempting to connect to %s:%d", hostname, port) try: s = socket.create_connection( dnat(self.cloud.owner, hostname, port), socket_timeout) s.shutdown(2) except: log.info("Failed to connect to %s:%d", hostname, port) continue log.info("Connected to %s:%d", hostname, port) return True try: log.info("Pinging %s", hostname) from mist.api.methods import ping ping_res = ping(owner=self.cloud.owner, host=hostname, pkts=1) if int(ping_res.get('packets_rx', 0)) > 0: log.info("Successfully pinged %s", hostname) return True except: log.info("Failed to ping %s", hostname) pass return False
def ping_probe(self, persist=True): if not self.machine.cloud.enabled: return False from mist.api.methods import ping from mist.api.machines.models import PingProbe def _get_probe_dict(): data = {} if self.machine.ping_probe is not None: data = self.machine.ping_probe.as_dict() return { '%s-%s' % (self.machine.id, self.machine.machine_id): { 'probe': { 'ping': data } } } try: host = self.machine.ctl.get_host() if host in ['localhost', '127.0.0.1']: return except RuntimeError: return old_probe_data = _get_probe_dict() task_key = 'machine:ping_probe:%s' % self.machine.id task = PeriodicTaskInfo.get_or_add(task_key) with task.task_runner(persist=persist): try: data = ping(self.machine.cloud.owner, self.get_host()) except: probe = self.machine.ping_probe if probe is not None: probe.unreachable_since = datetime.datetime.now() raise else: probe = PingProbe() probe.update_from_dict(data) finally: self.machine.ping_probe = probe self.machine.save() new_probe_data = _get_probe_dict() patch = jsonpatch.JsonPatch.from_diff(old_probe_data, new_probe_data).patch if patch: amqp_publish_user(self.machine.cloud.owner.id, routing_key='patch_machines', data={ 'cloud_id': self.machine.cloud.id, 'patch': patch }) probe_result = self.machine.ping_probe return probe_result and probe_result.as_dict()
def ping_probe(self, persist=True): from mist.api.methods import ping from mist.api.machines.models import PingProbe def _get_probe_dict(): data = {} if self.machine.ping_probe is not None: data = self.machine.ping_probe.as_dict() return { '%s-%s' % (self.machine.id, self.machine.machine_id): { 'probe': { 'ping': data } } } old_probe_data = _get_probe_dict() task_key = 'machine:ping_probe:%s' % self.machine.id task = PeriodicTaskInfo.get_or_add(task_key) with task.task_runner(persist=persist): data = ping(self.machine.cloud.owner, self.get_host()) probe = PingProbe() probe.update_from_dict(data) self.machine.ping_probe = probe self.machine.save() new_probe_data = _get_probe_dict() patch = jsonpatch.JsonPatch.from_diff(old_probe_data, new_probe_data).patch if patch: amqp_publish_user(self.machine.cloud.owner.id, routing_key='patch_machines', data={ 'cloud_id': self.machine.cloud.id, 'patch': patch }) return self.machine.ping_probe.as_dict()