blob: 0fc5e2d460e62f0f3b32b6efff3a29d7ba2939ba [file] [log] [blame]
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -08001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from synchronizers.new_base.pullstep import PullStep
Matteo Scandolo33523412018-04-12 15:21:13 -070016from synchronizers.new_base.modelaccessor import model_accessor, OLTDevice, VOLTService
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080017
18from xosconfig import Config
19from multistructlog import create_logger
20
Matteo Scandolo33523412018-04-12 15:21:13 -070021import requests
22from requests import ConnectionError
23from requests.models import InvalidURL
24
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080025log = create_logger(Config().get('logging'))
26
27class OLTDevicePullStep(PullStep):
28 def __init__(self):
29 super(OLTDevicePullStep, self).__init__(observed_model=OLTDevice)
30
Matteo Scandolo33523412018-04-12 15:21:13 -070031 # NOTE move helpers where they can be loaded by multiple modules?
32 @staticmethod
33 def format_url(url):
34 if 'http' in url:
35 return url
36 else:
37 return 'http://%s' % url
38
39 @staticmethod
40 def get_voltha_info(olt_service):
41 return {
42 'url': OLTDevicePullStep.format_url(olt_service.voltha_url),
Matteo Scandolo19466a02018-05-16 17:43:39 -070043 'port': olt_service.voltha_port,
Matteo Scandolo33523412018-04-12 15:21:13 -070044 'user': olt_service.voltha_user,
45 'pass': olt_service.voltha_pass
46 }
47
48 @staticmethod
49 def datapath_id_to_hex(id):
50 if isinstance(id, basestring):
51 id = int(id)
52 return "{0:0{1}x}".format(id, 16)
53
54 @staticmethod
55 def get_ids_from_logical_device(o):
56 voltha_url = OLTDevicePullStep.get_voltha_info(o.volt_service)['url']
Matteo Scandolo19466a02018-05-16 17:43:39 -070057 voltha_port = OLTDevicePullStep.get_voltha_info(o.volt_service)['port']
Matteo Scandolo33523412018-04-12 15:21:13 -070058
Matteo Scandolo19466a02018-05-16 17:43:39 -070059 r = requests.get("%s:%s/api/v1/logical_devices" % (voltha_url, voltha_port))
Matteo Scandolo33523412018-04-12 15:21:13 -070060
61 if r.status_code != 200:
62 raise Exception("Failed to retrieve logical devices from VOLTHA: %s" % r.text)
63
64 res = r.json()
65
66 for ld in res["items"]:
67 if ld["root_device_id"] == o.device_id:
68 o.of_id = ld["id"]
69 o.dp_id = "of:" + OLTDevicePullStep.datapath_id_to_hex(ld["datapath_id"]) # convert to hex
70 return o
71
72 raise Exception("Can't find a logical device for device id: %s" % o.device_id)
73 # end note
74
Matteo Scandolo4a8b4d62018-03-06 17:18:46 -080075 def pull_records(self):
76 log.info("pulling OLT devices from VOLTHA")
Matteo Scandolo33523412018-04-12 15:21:13 -070077
78 try:
79 self.volt_service = VOLTService.objects.all()[0]
80 except IndexError:
81 log.warn('VOLTService not found')
82 return
83
84 voltha_url = OLTDevicePullStep.get_voltha_info(self.volt_service)['url']
Matteo Scandolo19466a02018-05-16 17:43:39 -070085 voltha_port = OLTDevicePullStep.get_voltha_info(self.volt_service)['port']
Matteo Scandolo33523412018-04-12 15:21:13 -070086
87 try:
Matteo Scandolo19466a02018-05-16 17:43:39 -070088 r = requests.get("%s:%s/api/v1/devices" % (voltha_url, voltha_port))
Matteo Scandolo33523412018-04-12 15:21:13 -070089
90 if r.status_code != 200:
91 log.info("It was not possible to fetch devices from VOLTHA")
92
93 # keeping only OLTs
94 devices = [d for d in r.json()["items"] if "olt" in d["type"]]
95
96 log.debug("received devices", olts=devices)
97
98 # TODO
Matteo Scandolo19466a02018-05-16 17:43:39 -070099 # [ ] delete OLTS as OLTDevice.objects.all() - updated OLTs
Matteo Scandolo33523412018-04-12 15:21:13 -0700100
101 if r.status_code != 200:
102 log.info("It was not possible to fetch devices from VOLTHA")
103
104 olts_in_voltha = self.create_or_update_olts(devices)
105
106 except ConnectionError, e:
107 log.warn("It was not possible to connect to VOLTHA", reason=e)
108 return
109 except InvalidURL, e:
110 log.warn("VOLTHA url is invalid, is it configured in the VOLTService?", reason=e)
111 return
112
113 def create_or_update_olts(self, olts):
114
115 updated_olts = []
116
117 for olt in olts:
118 try:
119 if olt["type"] == "simulated_olt":
120 [host, port] = ["172.17.0.1", "50060"]
121 else:
122 [host, port] = olt["host_and_port"].split(":")
123 model = OLTDevice.objects.filter(device_type=olt["type"], host=host, port=port)[0]
124 log.debug("OLTDevice already exists, updating it", device_type=olt["type"], host=host, port=port)
125
126 if model.enacted < model.updated:
127 log.info("Skipping pull on OLTDevice %s as enacted < updated" % model.name, name=model.name, id=model.id, enacted=model.enacted, updated=model.updated)
128 return
129
130 except IndexError:
131 model = OLTDevice()
132 model.device_type = olt["type"]
133
134 if olt["type"] == "simulated_olt":
135 model.host = "172.17.0.1"
136 model.port = 50060
137
138 log.debug("OLTDevice is new, creating it", device_type=olt["type"], host=host, port=port)
139
140 # Adding feedback state to the device
141 model.device_id = olt["id"]
142 model.admin_state = olt["admin_state"]
143 model.oper_status = olt["oper_status"]
144
145 model.volt_service = self.volt_service
146 model.volt_service_id = self.volt_service.id
147
148 # get logical device
149 OLTDevicePullStep.get_ids_from_logical_device(model)
150
151 model.save()
152
153 updated_olts.append(model)
154
155 return updated_olts
156
157
158
159
160
161