DMTF / Redfishtool

A Python34 program that implements a command line tool for accessing the Redfish API.
Other
224 stars 68 forks source link

Raw patch is failing on JSON input data #71

Closed luboss closed 3 years ago

luboss commented 4 years ago

I was trying to change password on HP Proliant G9 (server supporting Redfish API) because builtin functionality - AccountService is not working (another possible candidate for an issue). I followed HP Redfish API data model and constructed raw call with JSON data {'Password': 'TEST123'} (in quotes in the shell command). However I'm getting JSON error about NoneType when loading the string to patchData variable:

redfishtool.py --Secure=Always -v -r 172.12.3.45 -u Admin -p ABCDEFG raw PATCH '/rest/v1/AccountService/Accounts/1' '{"Password": "TEST123"}' Traceback (most recent call last): File "/home/lubos/Redfishtool/redfishtool.py", line 19, in <module> main(sys.argv) File "/home/lubos/Redfishtool/redfishtool/redfishtoolMain.py", line 372, in main rc,r,j,d=runSubCmd(rft) File "/home/lubos/Redfishtool/redfishtool/redfishtoolMain.py", line 449, in runSubCmd rc,r,j,d=subCmdTable[rft.subcommand](rft,cmdTop=True) File "/home/lubos/Redfishtool/redfishtool/raw.py", line 146, in RawMain rc,r,j,d = self.runOperation(rft) File "/home/lubos/Redfishtool/redfishtool/raw.py", line 105, in runOperation rc,r,j,d=operationTable[self.operation](self, op, rft, cmdTop=True) File "/home/lubos/Redfishtool/redfishtool/raw.py", line 241, in httpPatch patchData=json.loads(rft.requestData) File "/usr/lib/python3.5/json/__init__.py", line 312, in loads s.__class__.__name__)) TypeError: the JSON object must be str, not 'NoneType'

jautor commented 4 years ago

Something else going on here that we'll need to investigate, but on a ProLiant Gen9 you should be using "/redfish/v1/..." URIs - the pre-Redfish "/rest/v1" interface I don't think is even populated on most HPE Gen9 products (that was a Gen8 feature).

billdodd commented 4 years ago

FYI - the request data (payload) should be given via the -d param:

redfishtool.py --Secure=Always -v -r 172.12.3.45 -u Admin -p ABCDEFG -d '{"Password": "TEST123"}' raw PATCH '/rest/v1/AccountService/Accounts/1' 
mraineri commented 4 years ago

That would definitely explain the NoneType error; I think the parameter defaults to None if not provided

luboss commented 4 years ago

I can see now I was mislead by the help page:

$ /home/lubos/Redfishtool/redfishtool.py --help
   Usage:
     redfishtool:    {} [OPTIONS]  <SubCommand> <operation> [<args>]...
     redfishtool:    {} [OPTIONS]  hmraw  <method> <hmUrl> [<data>]
...

The help page should be probably corrected by changing hmraw to raw and prepending with -d.

mraineri commented 4 years ago

Good point; the readme isn't very clear either in my opinion.

mraineri commented 4 years ago

So, I started looking into adding the option, but it seems like it already is in the help text under the "Common OPTNS" section:

  Usage:
   redfishtool [OPTNS] raw <method> <path> 

   redfishtool raw -h        # for help
   redfishtool raw examples  #for example commands

  <method> is one of:  GET, PATCH, POST, DELETE, HEAD, PUT
  <path> is full URI path to a redfish resource--the full path following <ipaddr:port>, starting with forward slash /

   Common OPTNS:
   -u <user>,   --user=<usernm>     -- username used for remote redfish authentication
   -p <passwd>, --password=<passwd> -- password used for remote redfish authentication
   -t <token>,  --token=<token>    - redfish auth session token-for sessions across multiple calls

   -r <rhost>,  --rhost=<rhost>     -- remote redfish service hostname or IP:port
   -X <method>  --request=<method>  -- the http method to use. <method>={GET,PATCH,POST,DELETE,HEAD,PUT}. Default=GET
   -d <data>    --data=<data>       -- the http request "data" to send on PATCH,POST,or PUT requests
   -H <hdrs>, --Headers=<hdrs>      -- Specify the request header list--overrides defaults. Format "{ A:B, C:D...}" 
   -S <Secure>,  --Secure=<Secure>  -- When to use https: (Note: doesn't stop rhost from redirect http to https)
  <operations / methods>:
     GET             -- HTTP GET method
     PATCH           -- HTTP PATCH method
     POST            -- HTTP POST method
     DELETE          -- HTTP DELETE method
     HEAD            -- HTTP HEAD method
     PUT             -- HTTP PUT method
   examples        -- example raw commands with syntax
   hello           -- raw hello -- debug command
luboss commented 4 years ago

I have cloned fresh Redfishtool instance and my help looks bit different (especially hmraw line):

$ python3.5 redfishtool.py --help
   Usage:
     redfishtool:    {} [OPTIONS]  <SubCommand> <operation> [<args>]...
     redfishtool:    {} [OPTIONS]  hmraw  <method> <hmUrl> [<data>]

  Common OPTIONS:
   -V,          --version           -- show redfishtool version, and exit
   -h,          --help              -- show Usage, Options, and list of subCommands, and exit
   -v,          --verbose           -- verbose level, can repeat up to 5 times for more verbose output
                              -v(header), -vv(+addl info), -vvv(Request trace), -vvvv(+subCmd dbg), -vvvvv(max dbg)
   -s,          --status            -- status level, can repeat up to 5 times for more status output
                               -s(http_status),
                               -ss(+r.url, +r.elapsed executionTime ),
                               -sss(+request hdrs,data,authType, +response status_code, +response executionTime,
                                    +login auth token/sessId/sessUri)
                               -ssss(+response headers), -sssss(+response data
   -u <user>,   --user=<usernm>     -- username used for remote redfish authentication
   -p <passwd>, --password=<passwd> -- password used for remote redfish authentication
   -r <rhost>,  --rhost=<rhost>     -- remote redfish service hostname or IP:port
   -t <token>,  --token=<token>     -- redfish auth session token-for sessions across multiple calls
   -q,          --quiet             -- quiet mode--suppress error, warning, and diagnostic messages
   -c <cfgFile>,--config=<cfgFile>  -- read options (including credentials) from file <cfgFile>
   -T <timeout>,--Timeout=<timeout> -- timeout in seconds for each http request.  Default=10

   -P <property>, --Prop=<property> -- return only the specified property. Applies only to all "get" operations
   -E, --Entries                    -- Fetch the Logs entries. Applies to Logs sub-command of Systems, Chassis and Managers

  Options used by "raw" subcommand:
   -d <data>    --data=<data>       -- the http request "data" to send on PATCH,POST,or PUT requests

  Options to specify top-level collection members: eg: Systems -I <sysId>
   -I <Id>, --Id=<Id>               -- Use <Id> to specify the collection member
   -M <prop>:<val> --Match=<prop>:<val>-- Use <prop>=<val> search to find the collection member
   -F,  --First                     -- Use the 1st link returned in the collection or 1st "matching" link if used with -M
   -1,  --One                       -- Use the single link returned in the collection. Return error if more than one member exists
   -a,  --all                       -- Returns all members if the operation is a Get on a top-level collection like Systems
   -L <Link>,  --Link=<Link>        -- Use <Link> (eg /redfish/v1/Systems/1) to reference the collection member.
                                    --   If <Link> is not one of the links in the collection, and error is returned.
  Options to specify 2nd-level collection members: eg: Systems -I<sysId> Processors -i<procId>
   -i <id>, --id=<id>               -- use <id> to specify the 2nd-level collection member
   -m <prop>:<val> --match=<prop>:val>--use <prop>=<val> search of 2nd-level collection to specify member
   -l <link>  --link=<link>         -- Use <link> (eg /redfish/v1/SYstems/1/Processors/1) to reference a 2nd level resource
                                    --   A -I|M|F|1|L option is still required to specify the link to the top-lvl collection
   -a,  --all                       -- Returns all members of the 2nd level collection if the operation is a Get on the
                                    --   2nd level collection (eg Processors). -I|M|F|1|L still specifies the top-lvl collection.

  Additional OPTIONS:
   -W <num>:<connTimeout>,          -- Send up to <num> {GET /redfish} requests with <connTimeout> TCP connection timeout
         --Wait=<num>:<ConnTimeout> --   before sending subcommand to rhost.  Default is -W 1:3
   -A <Authn>,   --Auth <Authn>     -- Authentication type to use:  Authn={None|Basic|Session}  Default is Basic
   -S <Secure>,  --Secure=<Secure>  -- When to use https: (Note: doesn't stop rhost from redirect http to https)
                                       <Secure>={Always | IfSendingCredentials | IfLoginOrAuthenticatedApi(default) }
   -R <ver>,  --RedfishVersion=<ver>-- The Major Redfish Protocol version to use: ver={v1(dflt), v<n>, Latest}
   -C         --CheckRedfishVersion -- tells Redfishtool to execute GET /redfish to verify that the rhost supports
                                       the specified redfish protocol version before executing a sub-command.
                                       The -C flag is auto-set if the -R Latest or -W ... options are selected
   -H <hdrs>, --Headers=<hdrs>      -- Specify the request header list--overrides defaults. Format "{ A:B, C:D...}"
   -D <flag>,  --Debug=<flag>       -- Flag for dev debug. <flag> is a 32-bit uint: 0x<hex> or <dec> format

  Subcommands:
     hello                 -- redfishtool hello world subcommand for dev testing
     about                 -- display version and other information about this version of redfishtool
     versions              -- get redfishProtocol versions supported by rhost: GET ^/redfish
     root   |  serviceRoot -- get serviceRoot resouce: GET ^/redfish/v1/
     Systems               -- operations on Computer Systems in the /Systems collection
     Chassis               -- operations on Chassis in the /Chassis collection
     Managers              -- operations on Managers in the /Managers collection
     AccountService        -- operations on AccountService including user administration
     SessionService        -- operations on SessionService including Session login/logout
     odata                 -- get the Odata Service document: GET ^/redfish/v1/odata
     metadata              -- get the CSDL metadata document: GET ^/redfish/v1/$metadata
     raw                   -- subcommand to execute raw http methods(GET,PATCH,POST...) and URIs

  For Subcommand usage, options, operations, help:
     redfishtool <SubCommand> -h  -- usage and options for specific subCommand

Version 1.1.0:

$ python3.5 redfishtool.py -V
redfishtool Version: 1.1.0
mraineri commented 4 years ago

There are "help" screens for each of the sub commands; you can get something specific to "raw" with:

redfishtool raw --help

That's where the options specific for raw are shown.

mraineri commented 3 years ago

Closing; upon inspection of the help text for the raw command, there is documentation for how to use the -d argument for supplying data. Please reopen if this is not sufficiently visible or clear.