blob: c34aa0d282c2e05f3f930d3077cbb13e8f624a7c [file] [log] [blame]
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001"""
2Copyright 2020 The Magma Authors.
3
4This source code is licensed under the BSD-style license found in the
5LICENSE file in the root directory of this source tree.
6
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12"""
13
14from threading import Thread
15from typing import List
16from unittest import mock
17
18from lte.protos.mconfig import mconfigs_pb2
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080019from configuration.service_configs import load_service_config
Wei-Yu Chen49950b92021-11-08 19:19:18 +080020from common.sentry import sentry_init
21from common.service import MagmaService
22from enodeb_status import (
23 get_operational_states,
24 get_service_status_old,
25)
26from logger import EnodebdLogger as logger
27from state_machines.enb_acs_manager import StateMachineManager
28from orc8r.protos.service303_pb2 import State
29
30from enodebd_iptables_rules import set_enodebd_iptables_rule
31from rpc_servicer import EnodebdRpcServicer
32from stats_manager import StatsManager
33from tr069.server import tr069_server
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080034from prometheus_client import start_http_server as prometheus_start_http_server
Wei-Yu Chen49950b92021-11-08 19:19:18 +080035
36
37def get_context(ip: str):
38 with mock.patch('spyne.server.wsgi.WsgiApplication') as MockTransport:
39 MockTransport.req_env = {"REMOTE_ADDR": ip}
40 with mock.patch('spyne.server.wsgi.WsgiMethodContext') as MockContext:
41 MockContext.transport = MockTransport
42 return MockContext
43
44
45def main():
46 """
47 Top-level function for enodebd
48 """
49 service = MagmaService('enodebd', mconfigs_pb2.EnodebD())
50 logger.init()
51
Wei-Yu Chen678f0a52021-12-21 13:50:52 +080052 enodebd_cfg = load_service_config('enodebd')
53 prometheus_cfg = enodebd_cfg.get("prometheus", None)
54
55 if not prometheus_cfg:
56 logger.warning("Prometheus configuration wasn't found in enodebd configuration.")
57 else:
58 prometheus_ip = prometheus_cfg.get("ip")
59 prometheus_port = prometheus_cfg.get("port")
60 prometheus_start_http_server(prometheus_port, addr=prometheus_ip)
61 logger.info(
62 "Starting Prometheus server on address %s:%d",
63 prometheus_ip, prometheus_port)
64
Wei-Yu Chen49950b92021-11-08 19:19:18 +080065 # Optionally pipe errors to Sentry
66 sentry_init(service_name=service.name)
67
68 # State machine manager for tracking multiple connected eNB devices.
69 state_machine_manager = StateMachineManager(service)
70
71 # Statistics manager
72 stats_mgr = StatsManager(state_machine_manager)
73 stats_mgr.run()
74
75 # Start TR-069 thread
76 server_thread = Thread(
77 target=tr069_server,
78 args=(state_machine_manager,),
79 daemon=True,
80 )
81 server_thread.start()
82
83 # Add all servicers to the server
84 enodebd_servicer = EnodebdRpcServicer(state_machine_manager)
85 enodebd_servicer.add_to_server(service.rpc_server)
86
87 # Register function to get service status
88 def get_enodebd_status():
89 return get_service_status_old(state_machine_manager)
90 service.register_get_status_callback(get_enodebd_status)
91
92 # Register a callback function for GetOperationalStates service303 function
93 def get_enodeb_operational_states() -> List[State]:
94 return get_operational_states(state_machine_manager, service.mconfig)
95 service.register_operational_states_callback(get_enodeb_operational_states)
96
97 # Set eNodeBD iptables rules due to exposing public IP to eNodeB
98 service.loop.create_task(set_enodebd_iptables_rule())
99
100 # Run the service loop
101 service.run()
102
103 # Cleanup the service
104 service.close()
105
106
107def call_repeatedly(loop, interval, function, *args, **kwargs):
108 """
109 Wrapper function to schedule function periodically
110 """
111 # Schedule next call
112 loop.call_later(
113 interval, call_repeatedly, loop, interval, function,
114 *args, **kwargs,
115 )
116 # Call function
117 function(*args, **kwargs)
118
119
120if __name__ == "__main__":
121 main()