Пример #1
0
    def __buildDefaults(self, section):
        '''!
         Helper API to include missing objects in a configuration section and validate their values.
         Below are the objects that are validated and added if not present: \n
           - ignore-result\n
           - reboot-on-success\n
           - reboot-on-failure\n
           - halt-on-failure\n
           - timestamp\n

         Below are the objects whose value is validated:\n
           - status
           - suspend-exit-code

         If the specified value is invalid  of if the object is not specified, its value is read from ztp_cfg.json

         @param section (dict) Configuration Section input data read from JSON file.

        '''
        default_objs = [
            'ignore-result', 'reboot-on-success', 'reboot-on-failure',
            'halt-on-failure'
        ]
        # Loop through objects and update them with default values
        for key in default_objs:
            _val = getField(section, key, bool, getCfg(key))
            section[key] = _val

        # set status
        if section.get('status') is None:
            section['status'] = 'BOOT'
            section['timestamp'] = getTimestamp()
        elif isString(section.get('status')) is False or \
            section.get('status') not in ['BOOT', 'IN-PROGRESS', 'SUSPEND', 'DISABLED', 'FAILED', 'SUCCESS']:
            logger.warning(
                'Invalid value (%s) used for configuration section status. Setting it to DISABLED.'
                % section.get('status'))
            section['status'] = 'DISABLED'
            section['timestamp'] = getTimestamp()

        # Validate suspend-exit code
        if section.get('suspend-exit-code') is not None:
            suspend_exit_code = getField(section, 'suspend-exit-code', int,
                                         None)
            if suspend_exit_code is None or suspend_exit_code < 0:
                del section['suspend-exit-code']

        # Add timestamp if missing
        if section.get('timestamp') is None:
            section['timestamp'] = getTimestamp()
def getRuntime(status, startTimeStamp, endTimeStamp):
    if status == 'IN-PROGRESS':
        return timeDiff(startTimeStamp, getTimestamp())
    elif status == 'SUCCESS' or status == 'FAILED':
        return timeDiff(startTimeStamp, endTimeStamp)
    else:
        return None
def getTimeString(msg):
    split_msg = msg.split('|', 1)
    if len(split_msg) == 2:
        time_str = split_msg[0]
        try:
            return "({})".format(timeDiff(time_str.strip(),
                                          getTimestamp())) + split_msg[1]
        except:
            ret = msg
    else:
        return msg
Пример #4
0
    def updateStatus(self, obj, status):
        '''!
         Update status of configuration section. Also update the timestamp indicating date/time when it is updated. The changes
         are also saved to the JSON file on disk which corresponds to the configuration section.

         @param status (str) Value to be stored as status

        '''
        if isinstance(obj, dict) and isString(status):
            self.objJson.set(obj, 'status', status)
            self.objJson.set(obj, 'timestamp', getTimestamp(), True)
        else:
            logger.error('Invalid argument type.')
            raise TypeError('Invalid argument type')
Пример #5
0
    def test_logging_output(self):
        '''!
        Test logging on both stdout and console
        '''
        if os.path.isfile("/tmp/test_Logger.txt"):
            os.remove("/tmp/test_Logger.txt")
        os.remove("/etc/rsyslog.d/10-ztp-log-file.conf")
        log = Logger(log_file="/tmp/test_Logger.txt")
        assert (log != None)
        log.setLevel("warning")
        msg = "Test 1 " + getTimestamp()
        log.warning(msg)
        assert (self.__search_file('/var/log/syslog', msg) == True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) == True)

        msg = "Test 2 " + getTimestamp()
        log.debug(msg)
        assert (self.__search_file('/var/log/syslog', msg) != True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) != True)

        log.setLevel("error")
        msg = "Test 3 " + getTimestamp()
        log.debug(msg)
        assert (self.__search_file('/var/log/syslog', msg) != True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) != True)

        log.setLevel("critical")
        msg = "Test 4 " + getTimestamp()
        log.info(msg)
        assert (self.__search_file('/var/log/syslog', msg) != True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) != True)

        log.setLevel("warning")
        msg = "Test 5 " + getTimestamp()
        log.warning(msg)
        assert (self.__search_file('/var/log/syslog', msg) == True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) == True)

        msg = "Test 6 " + getTimestamp()
        log.error(msg)
        assert (self.__search_file('/var/log/syslog', msg) == True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) == True)

        log.setLevel("critical")
        msg = "Test 7 " + getTimestamp()
        log.debug(msg)
        assert (self.__search_file('/var/log/syslog', msg) != True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) != True)

        msg = "Test 8 " + getTimestamp()
        log.info(msg)
        assert (self.__search_file('/var/log/syslog', msg) != True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) != True)

        msg = "Test 9 " + getTimestamp()
        log.warning(msg)
        assert (self.__search_file('/var/log/syslog', msg) != True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) != True)

        msg = "Test 10 " + getTimestamp()
        log.error(msg)
        assert (self.__search_file('/var/log/syslog', msg) != True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) != True)

        msg = "Test 11 " + getTimestamp()
        log.critical(msg)
        assert (self.__search_file('/var/log/syslog', msg) == True)
        assert (self.__search_file('/tmp/test_Logger.txt', msg) == True)
Пример #6
0
    def executeLoop(self, test_mode=False):
        '''!
         ZTP service loop which peforms provisioning data discovery and initiates processing.
        '''

        updateActivity('Initializing')

        # Set testing mode
        self.test_mode = test_mode

        # Check if ZTP is disabled administratively, bail out if disabled
        if getCfg('admin-mode') is False:
            logger.info('ZTP is administratively disabled.')
            self.__removeZTPProfile()
            return

        # Check if ZTP data restart flag is set
        if os.path.isfile(getCfg('ztp-restart-flag')):
            self.__ztp_restart = True
            os.remove(getCfg('ztp-restart-flag'))

        if self.test_mode:
            logger.warning(
                'ZTP service started in test mode with restricted functionality.'
            )
        else:
            logger.info('ZTP service started.')

        self.__ztp_engine_start_time = getTimestamp()
        _start_time = None
        self.ztp_mode = 'DISCOVERY'
        # Main provisioning data discovery loop
        while self.ztp_mode == 'DISCOVERY':
            updateActivity('Discovering provisioning data', overwrite=False)
            try:
                result = self.__discover()
            except Exception as e:
                logger.error(
                    "Exception [%s] encountered while running the discovery logic."
                    % (str(e)))
                _exc_type, _exc_value, _exc_traceback = sys.exc_info()
                __tb = traceback.extract_tb(_exc_traceback)
                for l in __tb:
                    logger.debug('  File ' + l[0] + ', line ' + str(l[1]) +
                                 ', in ' + str(l[2]))
                    logger.debug('    ' + str(l[3]))
                self.__forceRestartDiscovery(
                    "Invalid provisioning data received")
                continue

            if result:
                if self.ztp_mode == 'MANUAL_CONFIG':
                    logger.info(
                        "Configuration file '%s' detected. Shutting down ZTP service."
                        % (getCfg('config-db-json')))
                    break
                elif self.ztp_mode != 'DISCOVERY':
                    (rv, msg) = self.__processZTPJson()
                    if rv == "retry":
                        self.ztp_mode = 'DISCOVERY'
                    elif rv == "restart":
                        self.__forceRestartDiscovery(msg)
                    else:
                        break

            # Initialize in-band interfaces to establish connectivity if not done already
            self.__loadZTPProfile("discovery")
            logger.debug('Provisioning data not found.')

            # Scan for inband interfaces to link up and restart interface connectivity
            if self.__link_scan():
                updateActivity('Restarting network discovery after link scan')
                logger.info('Restarting network discovery after link scan.')
                runCommand('systemctl restart interfaces-config',
                           capture_stdout=False)
                logger.info('Restarted network discovery after link scan.')
                _start_time = time.time()
                continue

            # Start keeping time of last time restart networking was done
            if _start_time is None:
                _start_time = time.time()

            # Check if we have to restart networking
            if (time.time() - _start_time > getCfg('restart-ztp-interval')):
                updateActivity('Restarting network discovery')
                if self.test_mode is False:
                    # Remove existing leases to source new provisioning data
                    self.__cleanup_dhcp_leases()
                    logger.info('Restarting network discovery.')
                    runCommand('systemctl restart interfaces-config',
                               capture_stdout=False)
                    logger.info('Restarted network discovery.')
                _start_time = time.time()
                continue

            # Try after sometime
            time.sleep(getCfg('discovery-interval'))

        # Cleanup installed ZTP configuration profile
        self.__removeZTPProfile()
        if self.reboot_on_completion and self.test_mode == False:
            updateActivity('System reboot requested')
            systemReboot()
        updateActivity('Exiting ZTP server')