def remove_from_olt(self, extra_data: Dict): dev = self.dev_instance if not dev: return False if not dev.parent_dev or not dev.snmp_extra: return False telnet = extra_data.get("telnet") if not telnet: return False fiber_num, onu_num = str(dev.snmp_extra).split(".") fiber_num, onu_num = safe_int(fiber_num), safe_int(onu_num) fiber_addr = "%d.%d" % (fiber_num, onu_num) sn = self.get_item_plain(".1.3.6.1.4.1.3902.1012.3.28.1.1.5.%s" % fiber_addr) if sn is not None: if isinstance(sn, str): sn = "ZTEG%s" % "".join("%.2X" % ord(x) for x in sn[-4:]) else: sn = "ZTEG%s" % "".join("%.2X" % x for x in sn[-4:]) sn_mac = zte_utils.sn_to_mac(sn) if str(dev.mac_addr) != sn_mac: raise expect_util.ExpectValidationError(_("Mac of device not equal mac by snmp")) return _remove_zte_onu_from_olt( zte_ip_addr=str(dev.parent_dev.ip_address), telnet_login=telnet.get("login"), telnet_passw=telnet.get("password"), telnet_prompt=telnet.get("prompt"), snmp_info=str(dev.snmp_extra), ) raise DeviceConsoleError(_("Could not fetch serial for onu"))
def _make_pay(self, data: dict) -> Response: trade_point = safe_int(data.get("TRADE_POINT")) receipt_num = safe_int(data.get("RECEIPT_NUM")) pay_account = data.get("PAY_ACCOUNT") pay_id = data.get("PAY_ID") pay_amount = safe_float(data.get("PAY_AMOUNT")) customer = Customer.objects.get(username=pay_account, sites__in=[self.request.site]) pays = AllTimePayLog.objects.filter(pay_id=pay_id) if pays.exists(): return self._bad_ret(-100, "Pay already exists") with transaction.atomic(): customer.add_balance( profile=None, cost=pay_amount, comment=f"{self._lazy_object.title} {pay_amount:.2f}") customer.save(update_fields=("balance", )) AllTimePayLog.objects.create( customer=customer, pay_id=pay_id, sum=pay_amount, trade_point=trade_point, receipt_num=receipt_num, pay_gw=self._lazy_object, ) customer_check_service_for_expiration(customer_id=customer.pk) return Response({ "pay_id": pay_id, "service_id": data.get("SERVICE_ID"), "amount": round(pay_amount, 2), "status_code": 22, "time_stamp": self.current_date, })
def new_task_initial(self, request, group_id: str, customer_id: str): customer_id = safe_int(customer_id) if customer_id == 0: return Response("bad customer_id", status=status.HTTP_400_BAD_REQUEST) exists_task = models.Task.objects.filter( customer__id=customer_id, task_state=models.Task.TASK_STATE_NEW) if exists_task.exists(): # Task with this customer already exists return Response({ "status": 0, "text": gettext("New task with this customer already exists."), "task_id": exists_task.first().pk, }) group_id = safe_int(group_id) if group_id > 0: recipients = (UserProfile.objects.get_profiles_by_group( group_id=group_id).only("pk").values_list("pk", flat=True)) return Response({"status": 1, "recipients": recipients}) return Response('"group_id" parameter is required', status=status.HTTP_400_BAD_REQUEST)
def read_mac_address_vlan(self, vid: int) -> Macs: vid = safe_int(vid) if vid > 4095 or vid < 1: raise DeviceImplementationError("VID must be in range 1-%d" % 4095) fdb = self.get_list_with_oid(".1.3.6.1.2.1.17.7.1.2.2.1.2.%d" % vid) vid_name = self._get_vid_name(vid) for port_num, oid in fdb: fdb_mac = ":".join("%.2x" % int(i) for i in oid[-6:]) yield MacItem(vid=vid, name=vid_name, mac=fdb_mac, port=safe_int(port_num))
def scan_onu_list(self) -> Generator[ONUdevPort, None, None]: """ If fast operation then just return tuple. If long operation then return the generator of ports count first, then max chunk size, and ports in next in generations """ # numbers # fiber_nums = (safe_int(i) for i in self.get_list('.1.3.6.1.4.1.3320.101.6.1.1.1')) # numbers fiber_onu_counts = self.get_list(".1.3.6.1.4.1.3320.101.6.1.1.2") # comma separated strings, remember to remove empty elements fiber_onu_id_nums = self.get_list_keyval( ".1.3.6.1.4.1.3320.101.6.1.1.23") # All onu's count yield sum(safe_int(i) for i in fiber_onu_counts) # chunk max size yield 200 try: for fiber_onu_num, fiber_id in fiber_onu_id_nums: for onu_num in fiber_onu_num.split(b","): if not onu_num: continue onu_num = safe_int(onu_num) if onu_num == 0: continue status = safe_int( self.get_item(".1.3.6.1.4.1.3320.101.10.1.1.26.%d" % onu_num)) signal = safe_float( self.get_item(".1.3.6.1.4.1.3320.101.10.5.1.5.%d" % onu_num)) mac = self.get(".1.3.6.1.4.1.3320.101.10.1.1.3.%d" % onu_num) yield ONUdevPort( num=onu_num, name=self.get_item(".1.3.6.1.2.1.2.2.1.2.%d" % onu_num), status=status == 3, mac=macbin2str(mac.value), signal=signal / 10 if signal else "—", uptime=safe_int( self.get_item(".1.3.6.1.2.1.2.2.1.9.%d" % onu_num)), fiberid=safe_int(fiber_id), ) except EasySNMPTimeoutError as e: raise EasySNMPTimeoutError("{} ({})".format( gettext("wait for a reply from the SNMP Timeout"), e))
def read_mac_address_port(self, port_num: int) -> Macs: if port_num > self.ports_len or port_num < 1: raise DeviceImplementationError("Port must be in range 1-%d" % self.ports_len) fdb = self.get_list_with_oid(".1.3.6.1.2.1.17.7.1.2.2.1.2") for fdb_port, oid in fdb: if port_num != int(fdb_port): continue vid = safe_int(oid[-7:-6][0]) fdb_mac = ":".join("%.2x" % int(i) for i in oid[-6:]) vid_name = self._get_vid_name(vid) yield MacItem(vid=vid, name=vid_name, mac=fdb_mac, port=safe_int(port_num))
def get(self, request, *args, **kwargs): act: int = safe_int(request.GET.get("ACT")) self.current_date = timezone.now().strftime("%d.%m.%Y %H:%M") if act <= 0: return self._bad_ret(-101, "ACT must be more than 0") try: sign = request.GET.get("SIGN") if not sign: return self._bad_ret(-101, "SIGN not passed") if not self.check_sign(request.GET, sign.lower()): return self._bad_ret(-101, "Bad sign") if act == 1: return self._fetch_user_info(request.GET) elif act == 4: return self._make_pay(request.GET) elif act == 7: return self._check_pay(request.GET) else: return self._bad_ret(-101, "ACT is not passed") except Customer.DoesNotExist: return self._bad_ret(-40, "Account does not exist") except (PayAllTimeGateway.DoesNotExist, Http404): return self._bad_ret(-40, "Pay gateway does not exist") except DatabaseError: return self._bad_ret(-90) except AllTimePayLog.DoesNotExist: return self._bad_ret(-10) except AttributeError: return self._bad_ret(-101)
def read_all_vlan_info(self) -> Vlans: vids = self.get_list_keyval(".1.3.6.1.2.1.17.7.1.4.3.1.1") for vid_name, vid in vids: vid = safe_int(vid) if vid in (0, 1): continue yield Vlan(vid=vid, title=vid_name)
def _get_access_vlan(port_num: int) -> int: return safe_int( self.get_item( ".1.3.6.1.4.1.3902.1012.3.50.15.100.1.1.4.%(fiber_num)d.%(onu_num)d.1.%(port_num)d" % {"port_num": port_num, "fiber_num": fiber_num, "onu_num": onu_num} ) )
def generate_random_username(): username = _generate_random_chars() try: models.Customer.objects.get(username=username) return generate_random_username() except models.Customer.DoesNotExist: return str(safe_int(username))
def get_auth_session_response(self, subscriber_lease, customer_service, customer, request_data): service = customer_service.service speed_in = int(service.speed_in * 1000000) speed_out = int(service.speed_out * 1000000) speed_in_burst = int(speed_in / 8 * 1.5) speed_out_burst = int(speed_out / 8 * 1.5) res = { "Framed-IP-Address": subscriber_lease.ip_addr, # 'Framed-IP-Netmask': '255.255.0.0', "User-Password": f"SERVICE-INET({speed_in},{speed_in_burst},{speed_out},{speed_out_burst})", } session_remaining_time = customer_service.calc_session_time( splice=True) # + 5 минут потому что в момент, когда закончится сессия, # улуга еще будет на учётке. А вот через несколько мин. услуга # уже должна перерасчитаться. session_remaining_time += timedelta(minutes=5) session_remaining_time_secs = safe_int( session_remaining_time.total_seconds()) if session_remaining_time_secs > 0: res.update({"Session-Timeout": session_remaining_time_secs}) return res
def _filter_raw_manage_customer_service(self, balance_equal_operator: str, customer_id=None): """ Фильтруем истёкшие абонентские услуги, которые закончились или которые можно автоматически продлить. :param balance_equal_operator: Как сравниваем баланс абонента и стоимость услуги. :param customer_id: Если передано то фильтруем ещё и по абоненту. :return: RawQuerySet """ # TODO: test it query = [ "select cs.* from customer_service cs", "left join customers c on cs.id = c.current_service_id", "left join services s on cs.service_id = s.id", "where", "cs.deadline < now() and", "c.auto_renewal_service and", "c.balance %s s.cost" % balance_equal_operator, ] customer_id = safe_int(customer_id) params = None if customer_id > 0: query.append("and c.baseaccount_ptr_id = %s") params = [customer_id] query = " ".join(query) return self.raw(raw_query=query, params=params)
def assign_guest(self, customer_mac: str, data: dict, customer_id: Optional[int] = None): """ Assign no service session. :param customer_mac: Customer device MAC address. :param data: Other data from RADIUS server. :param customer_id: customers.models.Customer model id. :return: rest_framework Response. """ if customer_id is None: lease = CustomerRadiusSession.objects.assign_guest_session( customer_mac=customer_mac) else: customer_id = safe_int(customer_id) if customer_id == 0: return _bad_ret('Bad "customer_id" arg.') lease = CustomerRadiusSession.objects.assign_guest_customer_session( customer_id=customer_id, customer_mac=customer_mac) if lease is None: # Not possible to assign guest ip, it's bad return Response( {"Reply-Message": "Not possible to assign guest ip, it's bad"}, status=status.HTTP_404_NOT_FOUND, ) # Creating guest session r = self.vendor_manager.get_auth_guest_session_response( guest_lease=lease, data=data) return Response(r)
def get_manager_klass(self): try: return next(klass for code, klass in DEVICE_TYPES if code == safe_int(self.dev_type)) except StopIteration: raise TypeError( "one of types is not subclass of BaseDeviceInterface. " "Or implementation of that device type is not found")
def scan_mac_address_vlan(self, request, pk=None): dev = self.get_object() vid = safe_int(request.query_params.get("vid")) if vid == 0: return Response("Valid vid required", status=status.HTTP_400_BAD_REQUEST) macs = dev.dev_read_mac_address_vlan(vid=vid) return Response([m._asdict() for m in macs])
def set_object_perms(self, request, *args, **kwargs): # request.data = { # 'groupId': 2, # 'selectedPerms': [1, 2, 3] # } if not request.user.is_superuser: return Response(status=status.HTTP_403_FORBIDDEN) serializer = RequestObjectsPermsSerializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.validated_data selected_profile_group = get_object_or_404(ProfileGroup, pk=data.get("groupId")) selected_perms = [ safe_int(i) for i in data.get("selectedPerms") if safe_int(i) > 0 ] selected_perms = Permission.objects.filter( pk__in=selected_perms).iterator() obj = self.get_object() ctype = get_content_type(obj) existing_perm_codes = { p for p in Permission.objects.filter( groupobjectpermission__content_type=ctype, groupobjectpermission__group=selected_profile_group, groupobjectpermission__object_pk=obj.pk, ).iterator() } selected_perm_codes = {p for p in selected_perms} for_del = existing_perm_codes - selected_perm_codes for_add = selected_perm_codes - existing_perm_codes # del perms for perm in for_del: remove_perm(perm, selected_profile_group, obj) # add perms for perm in for_add: assign_perm(perm, selected_profile_group, obj) return Response("ok")
def build_port(i: int, n: int): speed = self.get_item(".1.3.6.1.2.1.2.2.1.5.%d" % n) oper_status = safe_int(self.get_item(".1.3.6.1.2.1.2.2.1.7.%d" % n)) == 1 link_status = safe_int(self.get_item(".1.3.6.1.2.1.2.2.1.8.%d" % n)) == 1 ep = EltexPort( dev_interface=self, num=i + 1, snmp_num=n, name=self.get_item(".1.3.6.1.2.1.2.2.1.2.%d" % n), # name status=oper_status, # status mac= b"", # self.get_item('.1.3.6.1.2.1.2.2.1.6.%d' % n), # mac speed=0 if not link_status else safe_int(speed), # speed uptime=self.get_item(".1.3.6.1.2.1.2.2.1.9.%d" % n), # UpTime ) return ep
def _bad_ret(err_id: int, err_description: str = None) -> Response: now = timezone.now() r = { "status_code": safe_int(err_id), "time_stamp": now.strftime("%d.%m.%Y %H:%M") } if err_description: r.update({"description": err_description}) return Response(r)
def get_fibers(self): fibers = tuple({ "fb_id": int(fiber_id), "fb_name": "EPON0/%d" % fiber_num, "fb_active_onu": safe_int( self.get_item(".1.3.6.1.4.1.3320.101.6.1.1.21.%d" % int(fiber_id))), # 'fb_onu_ids': tuple(int(i) for i in self.get_item_plain( # '.1.3.6.1.4.1.3320.101.6.1.1.23.%d' % int(fiber_id)).split(',') if i # ), "fb_onu_num": safe_int(registered_onu_count), } for fiber_num, (registered_onu_count, fiber_id) in enumerate( self.get_list_keyval(".1.3.6.1.4.1.3320.101.6.1.1.2"), 1)) return fibers
def get_page_size(self, request): try: q_page_size = safe_int( request.query_params[self.page_size_query_param]) if q_page_size > 0: return q_page_size except (KeyError, ValueError): pass return self.page_size
def fetch_customers_srvnet_credentials_by_gw(self, request, *args, **kwargs): service_id = safe_int(request.query_params.get("gw_id")) if service_id > 0: res = Gateway.get_user_credentials_by_gw(gw_id=service_id) # res = (customer_id, lease_id, lease_time, lease_mac, ip_address, # speed_in, speed_out, speed_burst, service_start_time, # service_deadline) return Response(res) return Response(status=status.HTTP_403_FORBIDDEN)
def read_all_vlan_info(self) -> Vlans: vid = 1 while True: res = self.get_next(".1.3.6.1.2.1.17.7.1.4.3.1.1.%d" % vid) vid = safe_int(res.value[5:]) if vid == 1: continue if vid == 0: return yield Vlan(vid=vid, title=res.value)
def check_sign(self, data: dict, sign: str) -> bool: act: int = safe_int(data.get("ACT")) pay_account = data.get("PAY_ACCOUNT") serv_id = data.get("SERVICE_ID") pay_id = data.get("PAY_ID") md = md5() s = "_".join((str(act), pay_account or "", serv_id or "", pay_id or "", self._lazy_object.secret)) md.update(bytes(s, "utf-8")) our_sign = md.hexdigest() return our_sign == sign
def remove_from_olt(ip_addr: str, telnet_login: str, telnet_passw: str, telnet_prompt: str, int_name: str): if not re.match(expect_util.IP4_ADDR_REGEX, ip_addr): raise expect_util.ExpectValidationError("ip address for OLT not valid") # Split "EPON0/1:17" for fiber_num - 1, and onu_num - 17 try: fiber_num, onu_num = int_name.split("/")[1].split(":") fiber_num, onu_num = safe_int(fiber_num), safe_int(onu_num) except (IndexError, ValueError): raise DeviceImplementationError("Device interface unexpected") if onu_num < 1 or onu_num > 64: raise DeviceImplementationError("Onu num must be in range 1-64") # Enter ch = expect_util.MySpawn("telnet %s" % ip_addr) ch.timeout = 15 ch.expect_exact("Username: "******"Password: "******"Authentication failed!", "%s>" % telnet_prompt]) if choice == 0: raise DeviceConsoleError(gettext("Wrong login or password for telnet access")) # enable privileges ch.do_cmd("enable", "%s#" % telnet_prompt) # enter to config ch.do_cmd("config", "%s_config#" % telnet_prompt) fiber_prompt = "%s_config_epon0/%d#" % (telnet_prompt, fiber_num) # enter to fiber ch.do_cmd("int EPON0/%d" % fiber_num, fiber_prompt) # unbind onu ch.do_cmd("no epon bind-onu sequence %d" % onu_num, fiber_prompt) # end removing ch.close() return True
def scan_onu_on_fiber(self, request, fiber_num=0, pk=None): if not str(fiber_num).isdigit() or safe_int(fiber_num) < 1: return Response('"fiber_num" number param required', status=status.HTTP_400_BAD_REQUEST) fiber_num = safe_int(fiber_num) device = self.get_object() manager = device.get_manager_object_olt() if hasattr(manager, "get_ports_on_fiber"): try: onu_list = tuple( manager.get_ports_on_fiber(fiber_num=fiber_num)) return Response(onu_list) except ProcessLocked: return Response(_("Process locked by another process"), status=status.HTTP_503_SERVICE_UNAVAILABLE) else: return Response({ "Error": { "text": 'Manager has not "get_ports_on_fiber" attribute' } })
def read_all_vlan_info(self) -> Vlans: snmp_vid = 100000 while True: res = self.get_next(".1.3.6.1.2.1.2.2.1.1.%d" % snmp_vid) if res.snmp_type != "INTEGER": break vid = snmp_vid = safe_int(res.value) if vid < 100000 or vid > 104095: break vid = (vid - 100000) + 1 name = self._get_vid_name(vid=vid) yield Vlan(vid=vid, title=name)
def find_customer_service_by_device_credentials(customer_id: int, current_service_id: int): customer_id = safe_int(customer_id) current_service_id = safe_int(current_service_id) # TODO: make tests for it with connection.cursor() as cur: query = "SELECT * FROM " "find_customer_service_by_device_credentials(%s, %s)" cur.execute(query, [customer_id, current_service_id]) res = cur.fetchone() if res is None or res[0] is None: return None ( customer_service_id, service_id, speed_in, speed_out, cost, calc_type, is_admin, speed_burst, start_time, deadline, ) = res srv = Service( pk=service_id, title="", descr="", speed_in=float(speed_in), speed_out=float(speed_out), cost=float(cost), calc_type=calc_type, is_admin=is_admin, speed_burst=speed_burst, ) customer_service = CustomerService(pk=customer_service_id, service=srv, start_time=start_time, deadline=deadline) return customer_service
def get_port(self, snmp_num: int): snmp_num = safe_int(snmp_num) status = self.get_item(".1.3.6.1.2.1.2.2.1.7.%d" % snmp_num) status = status and int(status) == 1 return DLinkPort( num=snmp_num, name=self.get_item(".1.3.6.1.2.1.31.1.1.1.18.%d" % snmp_num), status=status, mac=self.get_item(".1.3.6.1.2.1.2.2.1.6.%d" % snmp_num), speed=self.get_item(".1.3.6.1.2.1.2.2.1.5.%d" % snmp_num), uptime=self.get_item(".1.3.6.1.2.1.2.2.1.9.%d" % snmp_num), dev_interface=self, )
def get_ports_on_fiber(self, fiber_num: int) -> Iterable: onu_types = self.get_list_keyval( ".1.3.6.1.4.1.3902.1012.3.28.1.1.1.%d" % fiber_num) onu_ports = self.get_list(".1.3.6.1.4.1.3902.1012.3.28.1.1.2.%d" % fiber_num) onu_signals = self.get_list( ".1.3.6.1.4.1.3902.1012.3.50.12.1.1.10.%d" % fiber_num) onu_states = self.get_list(".1.3.6.1.4.1.3902.1012.3.50.12.1.1.1.%d" % fiber_num) # Real sn in last 3 octets onu_sns = self.get_list(".1.3.6.1.4.1.3902.1012.3.28.1.1.5.%d" % fiber_num) onu_prefixs = self.get_list(".1.3.6.1.4.1.3902.1012.3.50.11.2.1.1.%d" % fiber_num) status_map = {1: "ok", 2: "down"} onu_list = ( { "onu_type": onu_type_num[0], "onu_port": onu_port, "onu_signal": conv_zte_signal(onu_signal), "onu_sn": onu_prefix.decode() + "".join("%.2X" % i for i in onu_sn[-4:]), # Real sn in last 4 octets, "snmp_extra": "%d.%d" % (fiber_num, safe_int(onu_type_num[1])), "onu_state": status_map.get(safe_int(onu_state), "unknown"), } for onu_type_num, onu_port, onu_signal, onu_sn, onu_prefix, onu_state in zip(onu_types, onu_ports, onu_signals, onu_sns, onu_prefixs, onu_states)) return onu_list
def get_details(self) -> Optional[Dict]: if self.dev_instance is None: return snmp_extra = self.dev_instance.snmp_extra if not snmp_extra: return fiber_num, onu_num = snmp_extra.split(".") fiber_num, onu_num = int(fiber_num), int(onu_num) fiber_addr = "%d.%d" % (fiber_num, onu_num) signal = safe_int(self.get_item(".1.3.6.1.4.1.3902.1012.3.50.12.1.1.10.%s.1" % fiber_addr)) # distance = self.get_item('.1.3.6.1.4.1.3902.1012.3.50.12.1.1.18.%s.1' % fiber_addr) sn = self.get_item_plain(".1.3.6.1.4.1.3902.1012.3.28.1.1.5.%s" % fiber_addr) if sn is not None: if isinstance(sn, bytes): sn = "ZTEG%s" % "".join("%.2X" % int(x) for x in sn[-4:]) else: sn = "ZTEG%s" % "".join("%.2X" % ord(x) for x in sn[-4:]) status_map = {1: "ok", 2: "down"} return { "status": status_map.get( safe_int(self.get_item(".1.3.6.1.4.1.3902.1012.3.50.12.1.1.1.%s.1" % fiber_addr)), "unknown" ), "signal": zte_utils.conv_zte_signal(signal), "mac": zte_utils.sn_to_mac(sn), "info": ( (_("name"), self.get_item(".1.3.6.1.4.1.3902.1012.3.28.1.1.3.%s" % fiber_addr)), # 'distance': safe_float(distance) / 10, # 'ip_addr': self.get_item('.1.3.6.1.4.1.3902.1012.3.50.16.1.1.10.%s' % fiber_addr), (_("vlans"), self.get_item(".1.3.6.1.4.1.3902.1012.3.50.15.100.1.1.7.%s.1.1" % fiber_addr)), (_("serial"), sn), (_("onu_type"), self.get_item(".1.3.6.1.4.1.3902.1012.3.28.1.1.1.%s" % fiber_addr)), ), }