def createPodSpecificDhcpConfFile(self, session, podId): if podId is not None: try: pod = self._dao.getObjectById(session, Pod, podId) except (exc.NoResultFound): raise PodNotFound("Pod[id='%s']: not found" % (podId)) confWriter = DhcpConfWriter(self.__conf, pod, self._dao) confWriter.write(self.generatePodSpecificDhcpConf(session, pod.id)) else: raise PodNotFound("Pod id can't be None")
def getDevices(self, dbSession, podId): devices = {} listOfDevices = [] pod = self.report.getPod(dbSession, podId) if pod is not None: for device in pod.devices: outputDict = {} outputDict['id'] = device.id outputDict['name'] = device.name outputDict['role'] = device.role outputDict['family'] = device.family outputDict['macAddress'] = device.macAddress outputDict['managementIp'] = device.managementIp outputDict['serialNumber'] = device.serialNumber outputDict['deployStatus'] = device.deployStatus outputDict['configStatus'] = device.configStatus outputDict['l2Status'] = device.l2Status outputDict['l3Status'] = device.l3Status outputDict['uri'] = str(bottle.request.url).translate( None, ',') + '/' + device.id self.copyAdditionalDeviceFields(outputDict, device) listOfDevices.append(outputDict) devices['device'] = listOfDevices devices['uri'] = str(bottle.request.url).translate(None, ',') devices['total'] = len(pod.devices) return {'devices': devices} else: raise bottle.HTTPError(404, exception=PodNotFound(podId))
def getPod(self, dbSession, podId, requestUrl=None): if requestUrl is None: requestUrl = str(bottle.request.url).translate(None, ',') pod = self.report.getPod(dbSession, podId) if pod is not None: outputDict = {} devices = pod.devices for field in self.getPodFieldListToCopy(): outputDict[field] = pod.__dict__.get(field) ''' outputDict['id'] = pod.id outputDict['name'] = pod.name outputDict['description'] = pod.description outputDict['spineAS'] = pod.spineAS outputDict['spineDeviceType'] = pod.spineDeviceType outputDict['spineCount'] = pod.spineCount outputDict['leafAS'] = pod.leafAS outputDict['leafCount'] = pod.leafCount outputDict['loopbackPrefix'] = pod.loopbackPrefix outputDict['vlanPrefix'] = pod.vlanPrefix outputDict['interConnectPrefix'] = pod.interConnectPrefix outputDict['managementPrefix'] = pod.managementPrefix outputDict['outOfBandAddressList'] = pod.outOfBandAddressList outputDict['outOfBandGateway'] = pod.outOfBandGateway outputDict['topologyType'] = pod.topologyType outputDict['spineJunosImage'] = pod.spineJunosImage outputDict['hostOrVmCountPerLeaf'] = pod.hostOrVmCountPerLeaf ''' outputDict['leafSettings'] = [] for leafSetting in pod.leafSettings: outputDict['leafSettings'].append({ 'deviceType': leafSetting.deviceFamily, 'junosImage': leafSetting.junosImage }) outputDict['devicePassword'] = pod.getCleartextPassword() outputDict['uri'] = requestUrl outputDict['devices'] = { 'uri': requestUrl + '/devices', 'total': len(devices) } outputDict['cablingPlan'] = {'uri': requestUrl + '/cabling-plan'} outputDict['deviceConfiguration'] = { 'uri': requestUrl + '/device-configuration' } outputDict['ztpConfiguration'] = { 'uri': requestUrl + '/ztp-configuration' } outputDict['l2Report'] = {'uri': requestUrl + '/l2-report'} outputDict['l3Report'] = {'uri': requestUrl + '/l3-report'} logger.debug('getPod: %s' % (podId)) return {'pod': outputDict} else: raise bottle.HTTPError(404, exception=PodNotFound(podId))
def deletePod(self, dbSession, podId): pod = self.report.getPod(dbSession, podId) if pod is not None: self.__dao.deleteObject(dbSession, pod) util.deleteOutFolder(self._conf, pod) logger.debug("Pod with id: %s deleted" % (podId)) else: raise bottle.HTTPError(404, exception=PodNotFound(podId)) return bottle.HTTPResponse(status=204)
def getL3Report(self, dbSession, podId): try: cached = bottle.request.query.get('cached', '1') if cached == '1': cachedData = True else: cachedData = False bottle.response.headers['Content-Type'] = 'application/json' return self.l3Report.generateReport(podId, cachedData) except Exception as e: raise bottle.HTTPError(404, exception=PodNotFound(podId, e))
def getDeviceConfigsInZip(self, dbSession, podId): pod = self.report.getPod(dbSession, podId) if pod is None: raise bottle.HTTPError(404, exception=PodNotFound(podId)) logger.debug('Pod name: %s' % (pod.name)) zippedConfigFiles = self.createZipArchive(pod) if zippedConfigFiles is not None: bottle.response.headers['Content-Type'] = 'application/zip' return zippedConfigFiles else: raise bottle.HTTPError( 404, exception=DeviceConfigurationNotFound( "Pod exists but no configs for devices.'%s " % (pod.name)))
def getLeafGenericConfiguration(self, dbSession, podId, deviceModel): pod = self.report.getPod(dbSession, podId) if pod is None: raise bottle.HTTPError(404, exception=PodNotFound(podId)) logger.debug('Pod name: %s, id: %s' % (pod.name, podId)) leafSetting = self.__dao.getLeafSetting(dbSession, podId, deviceModel) if leafSetting is None or leafSetting.config is None: raise bottle.HTTPError( 404, exception=DeviceConfigurationNotFound( "Pod exists but no leaf generic config found, probably configuration \ was not created. deviceModel: %s, pod name: '%s', id: '%s'" % (deviceModel, pod.name, podId))) bottle.response.headers['Content-Type'] = 'application/json' return leafSetting.config
def generateReport(self, podId, cachedData=True, writeToFile=False): with self._dao.getReadSession() as session: pod = self.getPod(session, podId) if pod is None: logger.error('No pod found for podId: %s' % (podId)) raise PodNotFound('No pod found for podId: %s' % (podId)) if cachedData == False: logger.info('Generating L3Report from real data') # Note this map is static so we only intialize it once for entire L3 report deviceAsn2NameMap = self.getDeviceAsn2NameMap(podId, session) # reset all spines l3 status self.resetSpineL3Status(pod.devices) futureList = [] for device in pod.devices: if device.role == 'leaf': l3DataCollector = L3DataCollector( device.id, self._conf, self._dao, deviceAsn2NameMap) futureList.append( self.executor.submit( l3DataCollector.startL3Report)) logger.info('Submitted processing all devices') concurrent.futures.wait(futureList) # At this point multiple threads, ie multiple db sessions # have updated device, so we need to refresh pod data. # Rather than refresh, better option is expire, which # would trigger lazy load. session.expire(pod) logger.info('Done processing all devices') else: logger.info('Generating L3Report from cached data') l3ReportWriter = L3ReportWriter(self._conf, pod, self._dao) if writeToFile: return l3ReportWriter.writeThreeStageL3ReportJson() else: return l3ReportWriter.getThreeStageL3ReportJson()
def getZtpConfig(self, dbSession, podId): pod = self.report.getPod(dbSession, podId) if pod is not None: logger.debug('pod name: %s' % (pod.name)) podFolder = pod.id + '-' + pod.name fileName = os.path.join(podFolder, "dhcpd.conf") logger.debug( 'webServerRoot: %s, fileName: %s, exists: %s' % (webServerRoot, fileName, os.path.exists(os.path.join(webServerRoot, fileName)))) ztpConf = bottle.static_file(fileName, root=webServerRoot) if isinstance(ztpConf, bottle.HTTPError): raise bottle.HTTPError( 404, exception=DeviceConfigurationNotFound( "Pod exists but no ztp Config found. Pod name: '%s " % (pod.name))) return ztpConf else: raise bottle.HTTPError(404, exception=PodNotFound(podId))
def getCablingPlan(self, dbSession, podId): header = bottle.request.get_header('Accept') logger.debug('Accept header before processing: %s' % (header)) # hack to remove comma character, must be a bug on Bottle header = header.translate(None, ',') logger.debug('Accept header after processing: %s' % (header)) pod = self.report.getPod(dbSession, podId) if pod is not None: logger.debug('Pod name: %s' % (pod.name)) if header == 'application/json': cablingPlan = pod.cablingPlan if cablingPlan is not None and cablingPlan.json is not None: logger.debug('CablingPlan found in DB') return cablingPlan.json else: raise bottle.HTTPError(404, exception=CablingPlanNotFound( pod.id)) else: podFolder = pod.id + '-' + pod.name fileName = os.path.join(podFolder, 'cablingPlan.dot') logger.debug( 'webServerRoot: %s, fileName: %s, exists: %s' % (webServerRoot, fileName, os.path.exists(os.path.join(webServerRoot, fileName)))) logger.debug('Cabling file name: %s' % (fileName)) cablingPlan = bottle.static_file(fileName, root=webServerRoot) if isinstance(cablingPlan, bottle.HTTPError): raise bottle.HTTPError( 404, exception=CablingPlanNotFound(podFolder)) return cablingPlan else: raise bottle.HTTPError(404, exception=PodNotFound(podId))