Beispiel #1
0
 def test_json_config_nvalid(self, tmpdir):
     '''!
     Test case when the new json configuration file to apply is syntaxically incorrect.
     Verify that the plugin return with a non zero exit code.
     '''
     content = """
     #!/bin/sh
     exit 1
     """
     self.__write_file("file:///tmp/test_firmware_"+sysEeprom.get_product_name(), content)
     d = tmpdir.mkdir("valid")
     fh = d.join("input.json")
     fh.write("""
     {
         "configdb-json": {
             "clear-config": false,
             "halt-on-failure": false,
             "ignore-result": false,
             "reboot-on-failure": false,
             "reboot-on-success": false,
             "status": "BOOT",
             "timestamp": "2019-05-01 19:49:25",
             "url": {
                 "destination": "/etc/sonic/config_db.json",
                 "source": "file:///tmp/test_firmware_%s"
             }
         }
     }
     """ %(sysEeprom.get_product_name()))
     configdb_json = ConfigDBJson(str(fh))
     with pytest.raises(SystemExit) as pytest_wrapped_e:
         configdb_json.main()
     assert pytest_wrapped_e.type == SystemExit
     assert pytest_wrapped_e.value.code == 1
Beispiel #2
0
    def test_product_name(self):
        '''!
        Test when we call the constructor function using the product name
        '''

        id = Identifier('product-name')
        v = id.getIdentifier()
        assert (v == sysEeprom.get_product_name())
Beispiel #3
0
    def getIdentifier(self):
        '''!
         Obtain the resolved identifier string based on the identifier data.

         @return
              In case of success: \n
                Identifier string \n
              In case of error: \n
                None
        '''
        try:
            identifier_data = self.identifier_data
            if isinstance(identifier_data, dict) is False:
                if identifier_data == "hostname":
                    return socket.gethostname()
                elif identifier_data == "hostname-fqdn":
                    return socket.getfqdn()
                elif identifier_data == "serial-number":
                    return sysEeprom.get_serial_number()
                elif identifier_data == "product-name":
                    return sysEeprom.get_product_name()
                elif identifier_data == "sonic-version":
                    return get_sonic_version()
                else:
                    return identifier_data
            elif identifier_data.get('url') is not None:
                url_data = identifier_data.get('url')
                (fd, filename) = tempfile.mkstemp(prefix='identifier_',
                                                  dir=getCfg('ztp-tmp'))
                os.close(fd)
                urlObj = URL(url_data, filename)
                updateActivity('Downloading identifier script from \'%s\'' %
                               (urlObj.getSource()))
                rc, identifier_script = urlObj.download()
                if rc == 0 and os.path.isfile(identifier_script):
                    updateActivity(
                        'Executing identifier script downloaded from \'%s\'' %
                        (urlObj.getSource()))
                    (rc, cmd_stdout,
                     cmd_stderr) = runCommand([identifier_script])
                    if rc != 0:
                        logger.error(
                            'Error encountered while executing identifier %s Exit code: (%d).'
                            % (identifier_script, rc))
                        return None
                    if len(cmd_stdout) == 0:
                        return ""
                    else:
                        return cmd_stdout[0]
        except (TypeError, ValueError) as e:
            logger.error(
                'Exception: [%s] encountered while processing identifier data in dynamic URL.'
                % str(e))
            return None
        return None
Beispiel #4
0
    def test_constructor2(self):
        '''!
        Test when we call the constructor function with incomplete or wrong parameters
        '''

        dl = [('identifier', 'product-name')]
        d = dict(dl)
        dl_url = [('source', d)]
        d_url = dict(dl_url)
        durl = DynamicURL(d_url)
        s = durl.getSource()
        assert (s == sysEeprom.get_product_name())
Beispiel #5
0
    def test_download2(self):
        '''!
        Test when we call download() method
        '''

        content = 'Hello the world!'
        self.__write_file("/tmp/test_firmware_" + sysEeprom.get_product_name(),
                          content)

        dl = [('identifier', 'product-name'),
              ('prefix', 'file:///tmp/test_firmware_')]
        d = dict(dl)
        dl_url = [('source', d)]
        d_url = dict(dl_url)
        durl = DynamicURL(d_url)
        s = durl.getSource()
        assert (s == 'file:///tmp/test_firmware_' +
                sysEeprom.get_product_name())

        rc, dest = durl.download()
        assert (rc == 0)
        assert (self.__read_file(dest) == content)
Beispiel #6
0
    def test_download1(self):
        '''!
        Test when we call download() method
        '''

        dl = [('identifier', 'product-name'), ('prefix', 'XYZ_')]
        d = dict(dl)
        dl_url = [('source', d)]
        d_url = dict(dl_url)
        durl = DynamicURL(d_url)
        s = durl.getSource()
        assert (s == 'XYZ_' + sysEeprom.get_product_name())
        durl.download()
Beispiel #7
0
    def __init__(self,
                 url=None,
                 dst_file=None,
                 incl_http_headers=None,
                 is_secure=None,
                 timeout=None,
                 retry=None,
                 curl_args=None,
                 encrypted=None):
        '''!
        Constructor for the class, and optionally provide the parameters which can be used later by getUrl()

        @param url (str, optional) url of the file you want to get

        @param dst_file (str, optional) Filename for the data being stored. \n
            If not specified, it will be derived from the url (last part of it, e.g. basename).

        @param incl_http_headers (bool, optional) Include or not the additional HTTP headers
            (product name, serial number, mac address)

        @param is_secure (bool, optional) Every SSL connection curl makes is verified or not to be secure

        @param timeout (int, optional) Maximum number of seconds allowed for curl's connection to take. \n
            This  only  limits the connection phase.

        @param retry (int, optional) Number of times curl will retry in case of a transient error

        @param curl_args (str, optional) Options you want to pass to curl command line program

        @param encrypted (bool) Is the connectin with the server being encrypted?

        @return
            In case of success: \n
                Tupple: (0, data) \n
            In case of error: \n
                Tupple: (error code, html content)
        '''
        ## url of the file you want to get
        self.__url = url
        ## Name of the file where the file retrieved from the server is saved
        self.__dst_file = dst_file
        ## Do we send the HTTP headers (product name, serial number, mac address)?
        if incl_http_headers is None:
            self.__incl_http_headers = getCfg('include-http-headers')
        else:
            self.__incl_http_headers = incl_http_headers
        ## Should curl consider the SSL connection as secure or not?
        if is_secure is not None:
            self.__is_secure = is_secure
        else:
            self.__is_secure = getCfg('https-secure')

        ## Maximum number of seconds allowed for curl's connection to take
        if timeout is None:
            self.__timeout = getCfg('curl-timeout')
        else:
            self.__timeout = timeout
        ## Number of times curl will retry in case of a transient error
        if retry is None:
            self.__retry = getCfg('curl-retries')
        else:
            self.__retry = retry
        ## Optional curl cli program options
        self.__curl_args = curl_args
        ## Is the connection with the server encrypted?
        self.__encrypted = encrypted

        # Read system eeprom
        ## Product name read from the system eeprom
        self.__product_name = sysEeprom.get_product_name()
        ## Serial number read from the system eeprom
        self.__serial_number = sysEeprom.get_serial_number()
        ## MAC address read from the system eeprom
        self.__mac_addr = sysEeprom.get_mac_addr()

        # We need some items from the global ZTP config file
        ## Read which http-user-agent curl will be returning to the server
        self.__user_agent = getCfg('http-user-agent')

        # Read SONiC version
        self.__sonic_version = get_sonic_version()

        # Generate the http headers
        ## We include Product name, S/N and MAC address in the http headers sent to the server
        self.__http_headers = []
        if self.__product_name is not None:
            self.__http_headers.append('PRODUCT-NAME: ' + self.__product_name)
        if self.__serial_number is not None:
            self.__http_headers.append('SERIAL-NUMBER: ' +
                                       self.__serial_number)
        if self.__mac_addr is not None:
            self.__http_headers.append('BASE-MAC-ADDRESS: ' + self.__mac_addr)
        if self.__sonic_version is not None:
            self.__http_headers.append('SONiC-VERSION: ' +
                                       self.__sonic_version)