def invokeSMCLI(rh, api, parms, hideInLog=[]):
    """
    Invoke SMCLI and parse the results.

    Input:
       Request Handle
       API name,
       SMCLI parms as an array
       (Optional) List of parms (by index) to hide in
          sysLog by replacing the parm with "<hidden>".

    Output:
       Dictionary containing the following:
          overallRC - overall return code, 0: success, non-zero: failure
          rc        - RC returned from SMCLI if overallRC = 0.
          rs        - RS returned from SMCLI if overallRC = 0.
          errno     - Errno returned from SMCLI if overallRC = 0.
          response  - String output of the SMCLI command.

    Note:
       - If the first three words of the header returned from smcli
         do not do not contain words that represent valid integer
         values or contain too few words then one or more error
         messages are generated. THIS SHOULD NEVER OCCUR !!!!
    """
    if len(hideInLog) == 0:
        rh.printSysLog("Enter vmUtils.invokeSMCLI, userid: " +
                       rh.userid + ", function: " + api +
                       ", parms: " + str(parms))
    else:
        logParms = parms
        for i in hideInLog:
            logParms[i] = '<hidden>'
        rh.printSysLog("Enter vmUtils.invokeSMCLI, userid: " +
               rh.userid + ", function: " + api +
               ", parms: " + str(logParms))
    goodHeader = False

    results = {
              'overallRC': 0,
              'rc': 0,
              'rs': 0,
              'errno': 0,
              'response': [],
              'strError': '',
             }

    cmd = []
    cmd.append('sudo')
    cmd.append('/opt/zthin/bin/smcli')
    cmd.append(api)
    cmd.append('--addRCheader')

    try:
        smcliResp = subprocess.check_output(cmd + parms,
            close_fds=True)
        if isinstance(smcliResp, bytes):
            smcliResp = bytes.decode(smcliResp, errors='replace')

        smcliResp = smcliResp.split('\n', 1)
        results['response'] = smcliResp[1]
        results['overallRC'] = 0
        results['rc'] = 0

    except CalledProcessError as e:
        strCmd = " ".join(cmd + parms)

        # Break up the RC header into its component parts.
        if e.output == '':
            smcliResp = ['']
        else:
            smcliResp = bytes.decode(e.output).split('\n', 1)

        # Split the header into its component pieces.
        rcHeader = smcliResp[0].split('(details)', 1)
        if len(rcHeader) == 0:
            rcHeader = ['', '']
        elif len(rcHeader) == 1:
            # No data after the details tag.  Add empty [1] value.
            rcHeader.append('')
        codes = rcHeader[0].split(' ')

        # Validate the rc, rs, and errno.
        if len(codes) < 3:
            # Unexpected number of codes.  Need at least 3.
            results = msgs.msg['0301'][0]
            results['response'] = msgs.msg['0301'][1] % (modId, api,
                strCmd, rcHeader[0], rcHeader[1])
        else:
            goodHeader = True
            # Convert the first word (overall rc from SMAPI) to an int
            # and set the SMT overall rc based on this value.
            orcError = False
            try:
                results['overallRC'] = int(codes[0])
                if results['overallRC'] not in [8, 24, 25]:
                    orcError = True
            except ValueError:
                goodHeader = False
                orcError = True
            if orcError:
                results['overallRC'] = 25    # SMCLI Internal Error
                results = msgs.msg['0302'][0]
                results['response'] = msgs.msg['0302'][1] % (modId,
                    api, codes[0], strCmd, rcHeader[0], rcHeader[1])

            # Convert the second word to an int and save as rc.
            try:
                results['rc'] = int(codes[1])
            except ValueError:
                goodHeader = False
                results = msgs.msg['0303'][0]
                results['response'] = msgs.msg['0303'][1] % (modId,
                    api, codes[1], strCmd, rcHeader[0], rcHeader[1])

            # Convert the second word to an int and save it as either
            # the rs or errno.
            try:
                word3 = int(codes[2])
                if results['overallRC'] == 8:
                    results['rs'] = word3    # Must be an rs
                elif results['overallRC'] == 25:
                    results['errno'] = word3    # Must be the errno
                # We ignore word 3 for everyone else and default to 0.
            except ValueError:
                goodHeader = False
                results = msgs.msg['0304'][0]
                results['response'] = msgs.msg['0304'][1] % (modId,
                    api, codes[1], strCmd, rcHeader[0], rcHeader[1])

        results['strError'] = rcHeader[1].lstrip()

        if goodHeader:
            # Produce a message that provides the error info.
            results['response'] = msgs.msg['0300'][1] % (modId,
                    api, results['overallRC'], results['rc'],
                    results['rs'], results['errno'],
                    strCmd, smcliResp[1])

    except Exception as e:
        # All other exceptions.
        strCmd = " ".join(cmd + parms)
        results = msgs.msg['0305'][0]
        results['response'] = msgs.msg['0305'][1] % (modId, strCmd,
            type(e).__name__, str(e))

    rh.printSysLog("Exit vmUtils.invokeSMCLI, rc: " +
        str(results['overallRC']))
    return results
Invoke SMCLI and parse the results.

    Input:
       Request Handle
       API name,
       SMCLI parms as an array
       (Optional) List of parms (by index) to hide in
          sysLog by replacing the parm with "<hidden>".

    Output:
       Dictionary containing the following:
          overallRC - overall return code, 0: success, non-zero: failure
          rc        - RC returned from SMCLI if overallRC = 0.
          rs        - RS returned from SMCLI if overallRC = 0.
          errno     - Errno returned from SMCLI if overallRC = 0.
          response  - String output of the SMCLI command.

    Note:
       - If the first three words of the header returned from smcli
         do not do not contain words that represent valid integer
         values or contain too few words then one or more error
         messages are generated. THIS SHOULD NEVER OCCUR !!!!