1cf82313 | 25-Jun-2024 |
Ed Tanous <ed@tanous.net> |
Allow fuzzy string comparisons in $filter expr
Filter allows comparing certain strings as numeric greater than or less than operators. The most obvious example of this is something like
\$filter=C
Allow fuzzy string comparisons in $filter expr
Filter allows comparing certain strings as numeric greater than or less than operators. The most obvious example of this is something like
\$filter=Created gt <timestamp>
Because internally timestamps are treated as strings, this requires including and parsing out the timestamps again, which we have utilities for.
In addition, "fuzzy" string comparisons, like
GPU_2 gt GPU_1
Should also be supported.
Tested: Unit tests pass
Change-Id: I39fc543921ed8cc93664d9cf297dad8ee902b68f Signed-off-by: Ed Tanous <ed@tanous.net>
show more ...
|
2261a982 | 24-Jun-2024 |
Ed Tanous <ed@tanous.net> |
Use lexme in redfish filter parser
Previously, the parser added space ignore instructions between every node. This is because there was one place where we actually cared about spaces, when doing op
Use lexme in redfish filter parser
Previously, the parser added space ignore instructions between every node. This is because there was one place where we actually cared about spaces, when doing operator comparisons (x eq y). If spaces are ignored, it's impossible to determine the end of x and the beginning of eq.
Spirit x3 has a lexeme, which allows us to ignore the parser skips temporarily, which allows us to parse the operations in a much simpler way. This also requires that we change to phrase_parse instead of parse.
Tested: Unit tests pass. Good coverage.
Change-Id: Ifc6f1681e8524ba5032ee118cc3b3a18b30c639e Signed-off-by: Ed Tanous <ed@tanous.net>
show more ...
|
25991f7d | 13-Jun-2024 |
Ed Tanous <ed@tanous.net> |
Add filter parameter support
$filter is a parameter documented in the Redfish specification, section 7.3.4. It defines a mechanism for filtering arbitrary collections of parameters based on a set o
Add filter parameter support
$filter is a parameter documented in the Redfish specification, section 7.3.4. It defines a mechanism for filtering arbitrary collections of parameters based on a set of arbitrary language expressions.
From the specification, it supports the following language operators:
() Precedence grouping operator. (Status/State eq 'Enabled' and Status/Health eq 'OK') or SystemType eq 'Physical'
and Logical and operator. ProcessorSummary/Count eq 2 and MemorySummary/TotalSystemMemoryGiB gt 64
eq Equal comparison operator. ProcessorSummary/Count eq 2
ge Greater than or equal to comparison operator. ProcessorSummary/Count ge 2
gt Great than comparison operator. ProcessorSummary/Count gt 2
le Less than or equal to comparison operator MemorySummary/TotalSystemMemoryGiB le 64
lt Less than comparison operator. MemorySummary/TotalSystemMemoryGiB lt 64
ne Not equal comparison operator. SystemType ne 'Physical'
not Logical negation operator. not (ProcessorSummary/Count eq 2)
or Logical or operator. ProcessorSummary/Count eq 2 or ProcessorSummary/Count eq 4
Support for these operators have been added in previous commits. This commit enables them behind the insecure-enable-redfish-query meson option. This is an arbitrary language, so the likelihood there's some improper implementation in the patch is high. This gives folks the ability to test it.
Tested: Lots of unit tests included in this patch.
Functionally tested the basic operators: ``` GET /redfish/v1/Managers/bmc/LogServices/Journal/Entries?\$filter=EntryType+eq+'Oem' GET /redfish/v1/Managers/bmc/LogServices/Journal/Entries?\$filter=EntryType+ne+'Oem' ```
Function as expected, producing multiple results or no results respectively.
GET /redfish/v1 reports "FilterQuery": true
Redfish service validator passes.
Change-Id: Id568acc5dcfce868af12da5ee16c4f0caae8060a Signed-off-by: Ed Tanous <ed@tanous.net>
show more ...
|
25b54dba | 17-Apr-2024 |
Ed Tanous <ed@tanous.net> |
Bring consistency to config options
The configuration options that exist in bmcweb are an amalgimation of CROW options, CMAKE options using #define, pre-bmcweb ifdef mechanisms and meson options usi
Bring consistency to config options
The configuration options that exist in bmcweb are an amalgimation of CROW options, CMAKE options using #define, pre-bmcweb ifdef mechanisms and meson options using a config file. This history has led to a lot of different ways to configure code in the codebase itself, which has led to problems, and issues in consistency.
ifdef options do no compile time checking of code not within the branch. This is good when you have optional dependencies, but not great when you're trying to ensure both options compile.
This commit moves all internal configuration options to: 1. A namespace called bmcweb 2. A naming scheme matching the meson option. hyphens are replaced with underscores, and the option is uppercased. This consistent transform allows matching up option keys with their code counterparts, without naming changes. 3. All options are bool true = enabled, and any options with _ENABLED or _DISABLED postfixes have those postfixes removed. (note, there are still some options with disable in the name, those are left as-is) 4. All options are now constexpr booleans, without an explicit compare.
To accomplish this, unfortunately an option list in config/meson.build is required, given that meson doesn't provide a way to dump all options, as is a manual entry in bmcweb_config.h.in, in addition to the meson_options. This obsoletes the map in the main meson.build, which helps some of the complexity.
Now that we've done this, we have some rules that will be documented. 1. Runtime behavior changes should be added as a constexpr bool to bmcweb_config.h 2. Options that require optionally pulling in a dependency shall use an ifdef, defined in the primary meson.build. (note, there are no options that currently meet this class, but it's included for completeness.)
Note, that this consolidation means that at configure time, all options are printed. This is a good thing and allows direct comparison of configs in log files.
Tested: Code compiles Server boots, and shows options configured in the default build. (HTTPS, log level, etc)
Change-Id: I94e79a56bcdc01755036e4e7278c7e69e25809ce Signed-off-by: Ed Tanous <ed@tanous.net>
show more ...
|
8099c517 | 01-Nov-2023 |
Ed Tanous <edtanous@google.com> |
Allow parsing null or value classes
In Redfish schema, just about all values can be a type (string, EDM.Numeric, etc) or null. Most APIs don't allow explicitly setting null, but there are a few cas
Allow parsing null or value classes
In Redfish schema, just about all values can be a type (string, EDM.Numeric, etc) or null. Most APIs don't allow explicitly setting null, but there are a few cases where it is useful, namely in lists, where an an empty object {} keeps the value the same, and null deletes the value from the list.
Previously we handled this by unpacking as nlohmann::json, but this allowed things like
[1.0, {}] to pass the check for an array of string values. We'd ideally like to reject the 1.0 at the first stage, as well as reduce the number of tiered readJson calls that we make.
This commit introducess support for unpacking std::variant types, that allows unpacking a known type, or explicitly allowing null, by unpacking std::nullptr_t.
Tested: Unit tests pass.
Change-Id: Ic7451877c824ac743faf1951cc2b5d9f8df8019c Signed-off-by: Ed Tanous <edtanous@google.com>
show more ...
|
d02aad39 | 13-Feb-2024 |
Ed Tanous <ed@tanous.net> |
Create Redfish specific setProperty call
There are currently 78 sdbusplus::asio::setProperty calls in redfish-core. The error handler for nearly all of them looks something like:
``` if (ec) {
Create Redfish specific setProperty call
There are currently 78 sdbusplus::asio::setProperty calls in redfish-core. The error handler for nearly all of them looks something like:
``` if (ec) { const sd_bus_error* dbusError = msg.get_error(); if ((dbusError != nullptr) && (dbusError->name == std::string_view( "xyz.openbmc_project.Common.Error.InvalidArgument"))) { BMCWEB_LOG_WARNING("DBUS response error: {}", ec); messages::propertyValueIncorrect(asyncResp->res, "<PropertyName>", <PropertyValue>); return; } messages::internalError(asyncResp->res); return; } messages::success(asyncResp->res);
```
In some cases there are more errors handled that translate to more error messages, but the vast majority only handle InvalidArgument. Many of these, like the ones in account_service.hpp, do the error handling in a lambda, which causes readability problems. This commit starts to make things more consistent, and easier for trivial property sets.
This commit invents a setDbusProperty method in the redfish namespace that tries to handle all DBus errors in a consistent manner. Looking for input on whether this will work before changing over the other 73 calls. Overall this is less code, fewer inline lambdas, and defaults that should work for MOST use cases of calling an OpenBMC daemon, and fall back to more generic errors when calling a "normal" dbus daemon.
As part of this, I've ported over several examples. Some things that might be up in the air: 1. Do we always return 204 no_content on property sets? Today there's a mix of 200, with a Base::Success message, and 204, with an empty body. 2. Do all DBus response codes map to the same error? A majority are covered by xyz.openbmc_project.Common.Error.InvalidArgument, but there are likely differences. If we allow any daemon to return any return code, does that cause compatibility problems later?
Tested: ``` curl -k --user "root:0penBmc" -H "Content-Type: application/json" -X PATCH -d '{"HostName":"openbmc@#"}' https://192.168.7.2/redfish/v1/Managers/bmc/EthernetInterfaces/eth0 ```
Returns the appropriate error in the response Base.1.16.0.PropertyValueIncorrect
Change-Id: If033a1112ba516792c9386c997d090c8f9094f3a Signed-off-by: Ed Tanous <ed@tanous.net>
show more ...
|
1b8b02a4 | 08-Jan-2023 |
Ed Tanous <edtanous@google.com> |
Simplify datetime parsing
This code as it stands pulls in the full datetime library from boost, including io, and a bunch of timezone code. The bmc doesn't make use of any of this, so we can rely o
Simplify datetime parsing
This code as it stands pulls in the full datetime library from boost, including io, and a bunch of timezone code. The bmc doesn't make use of any of this, so we can rely on a much simplified version.
Unfortunately for us, gcc still doesn't implement the c++20 std::chrono::parse[1]. There is a reference library available from [2] that backports the parse function to compilers that don't yet support it, and is the basis for the libc++ version. This commit opts to copy in the header as-written, under the assumption that we will never need to pull in new versions of this library, and will move to the std ersion as soon as it's available in the next gcc version.
This commit simplifies things down to improve compile times and binary size. It saves ~22KB of compressed binary size, or about 3%.
Tested: Unit tests pass. Pretty good coverage.
[1] https://en.cppreference.com/w/cpp/chrono/parse [2] https://github.com/HowardHinnant/date/blob/master/include/date/date.h
Signed-off-by: Ed Tanous <edtanous@google.com> Change-Id: I706b91cc3d9df3f32068125bc47ff0c374eb8d87
show more ...
|
32cdb4a7 | 23-May-2023 |
Willy Tu <wltu@google.com> |
query: Fix default expand level with delegated
With delegate expand, the default expand level is -= `queryCapabilities.canDelegateExpandLevel`. This creates an overlap of expand process between dele
query: Fix default expand level with delegated
With delegate expand, the default expand level is -= `queryCapabilities.canDelegateExpandLevel`. This creates an overlap of expand process between delegate expand vs. default expand.
With query.expandLevel = 2 -> query.expandLevel = 1 and delegated.expandLevel = 1.
Both delegated and default expand will try to only expand of level one instead of level 2 for the default.
The code in https://github.com/openbmc/bmcweb/blob/479e899d5f57a67647f83b7f615d2c8565290bcf/redfish-core/include/utils/query_param.hpp#L583-L597 stated that the level with "@odata.id" + other property is treated as a seperate level. So with `query.expandLevel = 1` it just loop through the id that was already expanded and is noop.
Tested:
Before: /redfish/v1/Chassis/BMC/Sensors?$expand=.($levels=2) returns the same result as level=1. Needs level=3 to expand to the next level.
The RelatedItem in here doesn't get expanded with level=2. ``` wget -qO- 'http://localhost:80/redfish/v1/Chassis/BMC/Sensors?$expand=.($levels=1)' ... { "@odata.id": "/redfish/v1/Chassis/BMC/Sensors/temperature_DIMMXX", "@odata.type": "#Sensor.v1_2_0.Sensor", "Id": "temperature_DIMMXX", "Name": "DIMMXX", "Reading": 30.0, "ReadingRangeMax": 127.0, "ReadingRangeMin": -128.0, "ReadingType": "Temperature", "ReadingUnits": "Cel", "RelatedItem": [ { "@odata.id": "/redfish/v1/Systems/system/Memory/dimmXX" } ], "Status": { "Health": "OK", "State": "Enabled" }, "Thresholds": { "LowerCaution": { "Reading": null }, "LowerCritical": { "Reading": null }, "UpperCaution": { "Reading": 93.0 }, "UpperCritical": { "Reading": 95.0 } } } ], "Members@odata.count": 242, "Name": "Sensors" } ```
After: level=2 was able to expand to the next level.
Change-Id: I542177a94a33f8df7afbb68837f3a53b86140c86 Signed-off-by: Willy Tu <wltu@google.com>
show more ...
|
994fd86a | 06-Jun-2023 |
Ed Tanous <edtanous@google.com> |
Fix hack on Set-Cookie
This is one that I couldn't figure out for a while. Turns out that fields has both a set() and an insert() method. Whereas set() replaces, insert() appends, which is what we
Fix hack on Set-Cookie
This is one that I couldn't figure out for a while. Turns out that fields has both a set() and an insert() method. Whereas set() replaces, insert() appends, which is what we want in this case.
This allows us to call the actual methods several times, instead of essentially string injecting our own code, which should make it clearer.
At the same time, there was one unit test that was structured such that it was using addHeader to clear a header, so this commit adds an explicit "clearHeader()" method, so we can be explicit.
Tested: Logging into the webui in chrome (which uses POST /login) shows: 401 with no cookie header if the incorrect password is used 200 with 2 Set-Cookie headers set: Set-Cookie: SESSION=<session tag>; SameSite=Strict; Secure; HttpOnly Set-Cookie: XSRF-TOKEN=<token tag>; SameSite=Strict; Secure
Change-Id: I9b87a48ea6ba892fc08e66940563dea86edb9a65 Signed-off-by: Ed Tanous <edtanous@google.com>
show more ...
|