mirror of https://github.com/jumpserver/jumpserver
feat: 记录网关可连接性
parent
d93f3aca51
commit
4085df913b
|
@ -33,7 +33,7 @@ class GatewayViewSet(OrgBulkModelViewSet):
|
|||
model = Gateway
|
||||
filterset_fields = ("domain__name", "name", "username", "ip", "domain")
|
||||
search_fields = ("domain__name", "name", "username", "ip")
|
||||
permission_classes = (IsOrgAdmin,)
|
||||
permission_classes = (IsOrgAdminOrAppUser,)
|
||||
serializer_class = serializers.GatewaySerializer
|
||||
|
||||
|
||||
|
|
|
@ -3,16 +3,19 @@
|
|||
import socket
|
||||
import uuid
|
||||
import random
|
||||
import re
|
||||
|
||||
from django.core.cache import cache
|
||||
import paramiko
|
||||
from django.db import models
|
||||
from django.db.models import TextChoices
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from common.utils import get_logger
|
||||
from orgs.mixins.models import OrgModelMixin
|
||||
from .base import BaseUser
|
||||
|
||||
logger = get_logger(__file__)
|
||||
|
||||
__all__ = ['Domain', 'Gateway']
|
||||
|
||||
|
||||
|
@ -39,10 +42,19 @@ class Domain(OrgModelMixin):
|
|||
return self.gateway_set.filter(is_active=True)
|
||||
|
||||
def random_gateway(self):
|
||||
gateways = [gw for gw in self.gateways if gw.is_connective]
|
||||
if gateways:
|
||||
return random.choice(gateways)
|
||||
else:
|
||||
logger.warn(f'Gateway all bad. domain={self}, gateway_num={len(self.gateways)}.')
|
||||
return random.choice(self.gateways)
|
||||
|
||||
|
||||
class Gateway(BaseUser):
|
||||
UNCONNECTIVE_KEY_TMPL = 'asset_unconnective_gateway_{}'
|
||||
UNCONNECTIVE_SILENCE_PERIOD_KEY_TMPL = 'asset_unconnective_gateway_silence_period_{}'
|
||||
UNCONNECTIVE_SILENCE_PERIOD_BEGIN_VALUE = 60 * 5
|
||||
|
||||
class Protocol(TextChoices):
|
||||
ssh = 'ssh', 'SSH'
|
||||
|
||||
|
@ -60,6 +72,37 @@ class Gateway(BaseUser):
|
|||
unique_together = [('name', 'org_id')]
|
||||
verbose_name = _("Gateway")
|
||||
|
||||
def set_unconnective(self):
|
||||
unconnective_key = self.UNCONNECTIVE_KEY_TMPL.format(self.id)
|
||||
unconnective_silence_period_key = self.UNCONNECTIVE_SILENCE_PERIOD_KEY_TMPL.format(self.id)
|
||||
|
||||
unconnective_silence_period = cache.get(unconnective_silence_period_key,
|
||||
self.UNCONNECTIVE_SILENCE_PERIOD_BEGIN_VALUE)
|
||||
cache.set(unconnective_silence_period_key, unconnective_silence_period * 2)
|
||||
cache.set(unconnective_key, unconnective_silence_period, unconnective_silence_period)
|
||||
|
||||
def set_connective(self):
|
||||
unconnective_key = self.UNCONNECTIVE_KEY_TMPL.format(self.id)
|
||||
unconnective_silence_period_key = self.UNCONNECTIVE_SILENCE_PERIOD_KEY_TMPL.format(self.id)
|
||||
|
||||
cache.delete(unconnective_key)
|
||||
cache.delete(unconnective_silence_period_key)
|
||||
|
||||
def get_is_unconnective(self):
|
||||
unconnective_key = self.UNCONNECTIVE_KEY_TMPL.format(self.id)
|
||||
return cache.get(unconnective_key, False)
|
||||
|
||||
@property
|
||||
def is_connective(self):
|
||||
return not self.get_is_unconnective()
|
||||
|
||||
@is_connective.setter
|
||||
def is_connective(self, value):
|
||||
if value:
|
||||
self.set_connective()
|
||||
else:
|
||||
self.set_unconnective()
|
||||
|
||||
def test_connective(self, local_port=None):
|
||||
if local_port is None:
|
||||
local_port = self.port
|
||||
|
@ -85,6 +128,7 @@ class Gateway(BaseUser):
|
|||
err = err.format(port=self.port, ip=self.ip)
|
||||
elif err == 'Authentication failed.':
|
||||
err = _('Authentication failed')
|
||||
self.is_connective = False
|
||||
return False, err
|
||||
|
||||
try:
|
||||
|
@ -99,7 +143,9 @@ class Gateway(BaseUser):
|
|||
timeout=5)
|
||||
except (paramiko.SSHException, paramiko.ssh_exception.SSHException,
|
||||
paramiko.AuthenticationException, TimeoutError) as e:
|
||||
self.is_connective = False
|
||||
return False, str(e)
|
||||
finally:
|
||||
client.close()
|
||||
self.is_connective = True
|
||||
return True, None
|
||||
|
|
|
@ -42,6 +42,8 @@ class DomainSerializer(BulkOrgResourceModelSerializer):
|
|||
|
||||
|
||||
class GatewaySerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||
is_connective = serializers.BooleanField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Gateway
|
||||
fields_mini = ['id', 'name']
|
||||
|
@ -50,7 +52,7 @@ class GatewaySerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
|||
]
|
||||
fields_small = fields_mini + fields_write_only + [
|
||||
'username', 'ip', 'port', 'protocol',
|
||||
'is_active',
|
||||
'is_active', 'is_connective',
|
||||
'date_created', 'date_updated',
|
||||
'created_by', 'comment',
|
||||
]
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
from django.http.request import HttpRequest
|
||||
from django.http.response import HttpResponse
|
||||
|
||||
from orgs.utils import current_org
|
||||
|
||||
|
||||
class RequestLogMiddleware:
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request: HttpRequest):
|
||||
print(f'Request {request.method} --> ', request.get_raw_uri())
|
||||
response: HttpResponse = self.get_response(request)
|
||||
print(f'Response {current_org.name} {request.method} {response.status_code} --> ', request.get_raw_uri())
|
||||
return response
|
Loading…
Reference in New Issue