summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRatan Gupta <ratagupt@linux.vnet.ibm.com>2019-03-02 14:16:57 +0300
committerRatan Gupta <ratagupt@linux.vnet.ibm.com>2019-03-19 06:38:21 +0300
commitf476acbf885119861a1fecad47399a8eeeff0086 (patch)
treedc1a9d7471ba46685700f28702a0eff8ce02cc5c
parentaf713a64876d7736a43dc46e5abaeb7070fa5a62 (diff)
downloadbmcweb-f476acbf885119861a1fecad47399a8eeeff0086.tar.xz
Redfish(Network): Support for deletion of IP address through PATCH operation
Before this commit we were reading the IPV4address through readJSON function in vector of json, readJSON doesn't like the null list parameter and throws the error as below "The value null for the property IPv4Addresses is of a different type than the property can accept" This commit fixes that problem and some restructuring the code to make delete work. TestedBy: PATCH {"IPv4Addresses": [{},null,{},{}]} deletes second object PATCH {"IPv4Addresses": [null,{}]} deletes first object Suppose if the IPv4Address has two addresses then the Following PATCH request would give the folowing error. PATCH {"IPv4Addresses": [{},{},null] { "IPv4Addresses/0@Message.ExtendedInfo": [ { "@odata.type": "/redfish/v1/$metadata#Message.v1_0_0.Message", "Message": "The value [{},{},null] for the property IPv4Addresses/2 is of a different format than the property can accept.", "MessageArgs": [ "[{},{},null]", "IPv4Addresses/2" ], } Change-Id: Iaefd59de469cb345e86b19349b27567a4fcec3fa Signed-off-by: Ratan Gupta <ratagupt@linux.vnet.ibm.com>
-rw-r--r--redfish-core/lib/ethernet.hpp156
1 files changed, 80 insertions, 76 deletions
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index c98c8f4b12..2a0b618d8b 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -965,10 +965,17 @@ class EthernetInterface : public Node
}
void handleIPv4Patch(
- const std::string &ifaceId, std::vector<nlohmann::json> &input,
+ const std::string &ifaceId, nlohmann::json &input,
const boost::container::flat_set<IPv4AddressData> &ipv4Data,
const std::shared_ptr<AsyncResp> asyncResp)
{
+ if (!input.is_array())
+ {
+ messages::propertyValueTypeError(asyncResp->res, input.dump(),
+ "IPv4Addresses");
+ return;
+ }
+
int entryIdx = 0;
boost::container::flat_set<IPv4AddressData>::const_iterator thisData =
ipv4Data.begin();
@@ -977,6 +984,28 @@ class EthernetInterface : public Node
std::string pathString =
"IPv4Addresses/" + std::to_string(entryIdx);
+ if (thisJson.is_null())
+ {
+ if (thisData != ipv4Data.end())
+ {
+ deleteIPv4(ifaceId, thisData->id, entryIdx, asyncResp);
+ thisData++;
+ }
+ else
+ {
+ messages::propertyValueFormatError(
+ asyncResp->res, input.dump(), pathString);
+ return;
+ // TODO(ratagupt) Not sure about the property where value is
+ // list and if unable to update one of the
+ // list value then should we proceed further or
+ // break there, would ask in the redfish forum
+ // till then we stop processing the next list item.
+ }
+ entryIdx++;
+ continue; // not an error as per the redfish spec.
+ }
+
if (thisJson.empty())
{
if (thisData != ipv4Data.end())
@@ -988,7 +1017,7 @@ class EthernetInterface : public Node
messages::propertyMissing(asyncResp->res,
pathString + "/Address");
return;
- // TODO Not sure about the property where value is
+ // TODO(ratagupt) Not sure about the property where value is
// list and if unable to update one of the
// list value then should we proceed further or
// break there, would ask in the redfish forum
@@ -1057,96 +1086,72 @@ class EthernetInterface : public Node
}
}
- // if a vlan already exists, modify the existing
+ // if IP address exist then modify it.
if (thisData != ipv4Data.end())
{
- // Existing object that should be modified/deleted/remain
- // unchanged
- if (thisJson.is_null())
+ // Apply changes
+ if (address)
{
- auto callback = [entryIdx{std::to_string(entryIdx)},
- asyncResp](
+ auto callback = [asyncResp, entryIdx,
+ address{std::string(*address)}](
const boost::system::error_code ec) {
if (ec)
{
messages::internalError(asyncResp->res);
return;
}
- asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] =
- nullptr;
+ asyncResp->res
+ .jsonValue["IPv4Addresses"][entryIdx]["Address"] =
+ std::move(address);
};
+
crow::connections::systemBus->async_method_call(
std::move(callback), "xyz.openbmc_project.Network",
"/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" +
thisData->id,
- "xyz.openbmc_project.Object.Delete", "Delete");
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.IP", "Address",
+ std::variant<std::string>(*address));
}
- else if (thisJson.is_object())
+
+ if (subnetMask)
{
- // Apply changes
- if (address)
- {
- auto callback =
- [asyncResp, entryIdx, address = *address](
- const boost::system::error_code ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["IPv4Addresses"]
- [entryIdx]["Address"] =
- address;
- };
-
- crow::connections::systemBus->async_method_call(
- std::move(callback), "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId +
- "/ipv4/" + thisData->id,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.IP", "Address",
- std::variant<std::string>(*address));
- }
+ changeIPv4SubnetMaskProperty(ifaceId, entryIdx,
+ thisData->id, *subnetMask,
+ prefixLength, asyncResp);
+ }
- if (subnetMask)
- {
- changeIPv4SubnetMaskProperty(ifaceId, entryIdx,
- thisData->id, *subnetMask,
- prefixLength, asyncResp);
- }
+ if (addressOrigin)
+ {
+ changeIPv4Origin(ifaceId, entryIdx, thisData->id,
+ *addressOrigin, addressOriginInDBusFormat,
+ asyncResp);
+ }
- if (addressOrigin)
- {
- changeIPv4Origin(ifaceId, entryIdx, thisData->id,
- *addressOrigin,
- addressOriginInDBusFormat, asyncResp);
- }
+ if (gateway)
+ {
+ auto callback = [asyncResp, entryIdx,
+ gateway{std::string(*gateway)}](
+ const boost::system::error_code ec) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res
+ .jsonValue["IPv4Addresses"][entryIdx]["Gateway"] =
+ std::move(gateway);
+ };
- if (gateway)
- {
- auto callback =
- [asyncResp, entryIdx,
- gateway{std::string(*gateway)}](
- const boost::system::error_code ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["IPv4Addresses"]
- [entryIdx]["Gateway"] =
- std::move(gateway);
- };
-
- crow::connections::systemBus->async_method_call(
- std::move(callback), "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId +
- "/ipv4/" + thisData->id,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.IP", "Gateway",
- std::variant<std::string>(*gateway));
- }
+ crow::connections::systemBus->async_method_call(
+ std::move(callback), "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" +
+ thisData->id,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.IP", "Gateway",
+ std::variant<std::string>(*gateway));
}
+
thisData++;
}
else
@@ -1297,8 +1302,8 @@ class EthernetInterface : public Node
std::optional<nlohmann::json> vlan;
std::optional<std::string> hostname;
- std::optional<std::vector<nlohmann::json>> ipv4Addresses;
- std::optional<std::vector<nlohmann::json>> ipv6Addresses;
+ std::optional<nlohmann::json> ipv4Addresses;
+ std::optional<nlohmann::json> ipv6Addresses;
if (!json_util::readJson(req, res, "VLAN", vlan, "HostName", hostname,
"IPv4Addresses", ipv4Addresses,
@@ -1375,8 +1380,7 @@ class EthernetInterface : public Node
// efficiently move out the intermedia nlohmann::json
// objects. This makes a copy of the structure, and operates
// on that, but could be done more efficiently
- std::vector<nlohmann::json> ipv4 =
- std::move(*ipv4Addresses);
+ nlohmann::json ipv4 = std::move(*ipv4Addresses);
handleIPv4Patch(iface_id, ipv4, ipv4Data, asyncResp);
}