diff options
Diffstat (limited to 'gae/webapp/src/endpoint/lab_info.py')
-rw-r--r-- | gae/webapp/src/endpoint/lab_info.py | 158 |
1 files changed, 129 insertions, 29 deletions
diff --git a/gae/webapp/src/endpoint/lab_info.py b/gae/webapp/src/endpoint/lab_info.py index 8945db4..d42148b 100644 --- a/gae/webapp/src/endpoint/lab_info.py +++ b/gae/webapp/src/endpoint/lab_info.py @@ -11,30 +11,29 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - """Lab Info APIs implemented using Google Cloud Endpoints.""" import datetime import endpoints - -from protorpc import remote +import logging from google.appengine.ext import ndb +from webapp.src import vtslab_status as Status +from webapp.src.endpoint import endpoint_base from webapp.src.endpoint import host_info from webapp.src.proto import model - -SCHEDULE_INFO_RESOURCE = endpoints.ResourceContainer( - model.LabInfoMessage) +LAB_INFO_RESOURCE = endpoints.ResourceContainer(model.LabInfoMessage) +LAB_HOST_INFO_RESOURCE = endpoints.ResourceContainer(model.LabHostInfoMessage) -@endpoints.api(name='lab_info', version='v1') -class LabInfoApi(remote.Service): +@endpoints.api(name='lab', version='v1') +class LabInfoApi(endpoint_base.EndpointBase): """Endpoint API for lab_info.""" @endpoints.method( - SCHEDULE_INFO_RESOURCE, + LAB_INFO_RESOURCE, model.DefaultResponse, path="clear", http_method="POST", @@ -49,34 +48,135 @@ class LabInfoApi(remote.Service): return_code=model.ReturnCodeMessage.SUCCESS) @endpoints.method( - SCHEDULE_INFO_RESOURCE, + LAB_INFO_RESOURCE, model.DefaultResponse, path="set", http_method="POST", name="set") def set(self, request): """Sets the lab info based on `request`.""" - for host in request.host: - lab = model.LabModel() - lab.name = request.name - lab.owner = request.owner - lab.hostname = host.hostname - lab.ip = host.ip - lab.script = host.script - devices = [] - null_device_count = 0 - if host.device: - for device in host.device: - devices.append("%s=%s" % (device.serial, device.product)) - if device.product == "null": + if "host" in [x.name for x in request.all_fields()]: + labs_to_put = [] + for host in request.host: + duplicate_query = model.LabModel.query( + model.LabModel.name == request.name, + model.LabModel.owner == request.owner, + model.LabModel.hostname == host.hostname) + duplicates = duplicate_query.fetch() + if duplicates: + lab = duplicates[0] + else: + lab = model.LabModel() + lab.name = request.name + lab.owner = request.owner + lab.admin = request.admin + lab.hostname = host.hostname + lab.ip = host.ip + lab.script = host.script + + null_device_count = 0 + devices_to_put = [] + for config_device in host.device: + if config_device.product == "null": null_device_count += 1 - if devices: - lab.devices = ",".join(devices) - lab.timestamp = datetime.datetime.now() - lab.put() + continue + if config_device.serial and config_device.product: + device_query = model.DeviceModel.query( + model.DeviceModel.serial == config_device.serial) + devices = device_query.fetch() + if devices: + device = devices[0] + if (device.hostname != host.hostname) and ( + device.status != + Status.DEVICE_STATUS_DICT["no-response"]): + logging.error( + "{} is alive in another host.".format( + config_device.serial)) + # TODO: send an alert to lab.admin + continue + if device.hostname == host.hostname and set( + device.device_equipment) == set( + config_device.device_equipment): + # no need to update. + continue + else: + device = model.DeviceModel() + device.status = Status.DEVICE_STATUS_DICT[ + "no-response"] + device.product = config_device.product + device.serial = config_device.serial + device.hostname = host.hostname + device.scheduling_status = ( + Status.DEVICE_SCHEDULING_STATUS_DICT["free"]) + device.timestamp = datetime.datetime.now() + device.device_equipment = config_device.device_equipment + devices_to_put.append(device) + else: + logging.error("Lab config does not have device " + "information correctly; it should " + "specify device product and serial.") + if devices_to_put: + ndb.put_multi(devices_to_put) + + lab.timestamp = datetime.datetime.now() + labs_to_put.append(lab) + + if null_device_count > 0: + host_info.AddNullDevices(host.hostname, null_device_count) - if null_device_count > 0: - host_info.AddNullDevices(host.hostname, null_device_count) + if labs_to_put: + ndb.put_multi(labs_to_put) return model.DefaultResponse( return_code=model.ReturnCodeMessage.SUCCESS) + + @endpoints.method( + LAB_HOST_INFO_RESOURCE, + model.DefaultResponse, + path="set_version", + http_method="POST", + name="set_version") + def set_version(self, request): + """Sets vtslab version of the host <hostname>""" + lab_query = model.LabModel.query( + model.LabModel.hostname == request.hostname) + labs = lab_query.fetch() + + labs_to_put = [] + for lab in labs: + lab.vtslab_version = request.vtslab_version.split(":")[0] + labs_to_put.append(lab) + if labs_to_put: + ndb.put_multi(labs_to_put) + + return model.DefaultResponse( + return_code=model.ReturnCodeMessage.SUCCESS) + + @endpoints.method( + endpoint_base.GET_REQUEST_RESOURCE, + model.LabResponseMessage, + path="get", + http_method="POST", + name="get") + def get(self, request): + """Gets the labs from datastore.""" + return_list, more = self.Get(request=request, + metaclass=model.LabModel, + message=model.LabMessage) + + return model.LabResponseMessage(labs=return_list, has_next=more) + + @endpoints.method( + endpoint_base.COUNT_REQUEST_RESOURCE, + model.CountResponseMessage, + path="count", + http_method="POST", + name="count") + def count(self, request): + """Gets total number of BuildModel entities stored in datastore.""" + filters = self.CreateFilterList( + filter_string=request.filter, metaclass=model.LabModel) + + count = self.Count(metaclass=model.LabModel, filters=filters) + + return model.CountResponseMessage(count=count) |