summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunitha Harish <sunithaharish04@gmail.com>2019-03-21 19:01:24 +0300
committerEd Tanous <ed.tanous@intel.com>2019-03-29 01:27:12 +0300
commitfda13ad2223f3af2a7c4bedd7117ddbd38426126 (patch)
treec8916c769483cec553c1f44a1c8b821e13bce013
parent343ff2e152b30bcc82a1bb9120ff873e8ff40e93 (diff)
downloadbmcweb-fda13ad2223f3af2a7c4bedd7117ddbd38426126.tar.xz
Redfish(Network): Fixes VLAN specific issues
This commit fixes the following issues. Before this fix the VLAN functionality was inconsiststant. 1)Add VLANs property to the EthernetInterface resource 2)Removed VLAN property under EthernetInterface resource 3)Made the property - VLANEnable mandatory for creating vlans (POST command) 4)Fetch the VLANId when GET on the VLAN Interface resource 5)Updated Ethernet schema to EthernetInterface.v1_4_1 6)Changed the propert name "DHCPv4Configuration" to "DHCPv4" as per the schema Tested by: GET https://${bmc}/redfish/v1/Managers/bmc/EthernetInterfaces/eth0 GET https://${bmc}/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/VLANs POST -D headers.txt https://${bmc}/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/VLANs -d '{ "VLANId" : 30, "VLANEnable": true}' GET https://${bmc}/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/VLANs/eth0_30 Signed-off-by: Sunitha Harish <sunithaharish04@gmail.com> Change-Id: I2339f6711cdd56fe42fee030701125492911dc26
-rw-r--r--redfish-core/lib/ethernet.hpp157
1 files changed, 60 insertions, 97 deletions
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 476e03aff2..25dff50ffb 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -82,7 +82,7 @@ struct EthernetInterfaceData
std::string hostname;
std::string default_gateway;
std::string mac_address;
- std::optional<uint32_t> vlan_id;
+ std::vector<std::uint32_t> vlan_id;
std::vector<std::string> nameservers;
};
@@ -192,7 +192,7 @@ inline void extractEthernetInterfaceData(const std::string &ethiface_id,
std::get_if<uint32_t>(&propertyPair.second);
if (id != nullptr)
{
- ethData.vlan_id = *id;
+ ethData.vlan_id.push_back(*id);
}
}
}
@@ -669,8 +669,7 @@ inline void getDHCPConfigData(const std::shared_ptr<AsyncResp> asyncResp)
messages::internalError(asyncResp->res);
return;
}
- nlohmann::json &DHCPConfigTypeJson =
- asyncResp->res.jsonValue["DHCPv4Configuration"];
+ nlohmann::json &DHCPConfigTypeJson = asyncResp->res.jsonValue["DHCPv4"];
for (const auto &property : dbus_data)
{
auto value =
@@ -851,12 +850,17 @@ class EthernetCollection : public Node
nlohmann::json &iface_array = res.jsonValue["Members"];
iface_array = nlohmann::json::array();
+ std::string tag = "_";
for (const std::string &iface_item : iface_list)
{
- iface_array.push_back(
- {{"@odata.id",
- "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
- iface_item}});
+ std::size_t found = iface_item.find(tag);
+ if (found == std::string::npos)
+ {
+ iface_array.push_back(
+ {{"@odata.id",
+ "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
+ iface_item}});
+ }
}
res.jsonValue["Members@odata.count"] = iface_array.size();
@@ -896,15 +900,6 @@ class EthernetInterface : public Node
const EthernetInterfaceData &ethData,
const std::shared_ptr<AsyncResp> asyncResp)
{
- if (!ethData.vlan_id)
- {
- // This interface is not a VLAN. Cannot do anything with it
- // TODO(kkowalsk) Change this message
- messages::propertyNotWritable(asyncResp->res, "VLANEnable");
-
- return;
- }
-
// VLAN is configured on the interface
if (vlanEnable == true)
{
@@ -1238,25 +1233,17 @@ class EthernetInterface : public Node
}
json_response["SpeedMbps"] = ethData.speed;
json_response["MACAddress"] = ethData.mac_address;
- json_response["DHCPv4Configuration"]["DHCPEnabled"] =
- ethData.DHCPEnabled;
+ json_response["DHCPv4"]["DHCPEnabled"] = ethData.DHCPEnabled;
if (!ethData.hostname.empty())
{
json_response["HostName"] = ethData.hostname;
}
- nlohmann::json &vlanObj = json_response["VLAN"];
- if (ethData.vlan_id)
- {
- vlanObj["VLANEnable"] = true;
- vlanObj["VLANId"] = *ethData.vlan_id;
- }
- else
- {
- vlanObj["VLANEnable"] = false;
- vlanObj["VLANId"] = 0;
- }
+ json_response["VLANs"] = {
+ {"@odata.id", "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
+ iface_id + "/VLANs"}};
+
json_response["NameServers"] = ethData.nameservers;
if (ipv4Data.size() > 0)
@@ -1300,7 +1287,7 @@ class EthernetInterface : public Node
return;
}
asyncResp->res.jsonValue["@odata.type"] =
- "#EthernetInterface.v1_2_0.EthernetInterface";
+ "#EthernetInterface.v1_4_1.EthernetInterface";
asyncResp->res.jsonValue["@odata.context"] =
"/redfish/v1/$metadata#EthernetInterface.EthernetInterface";
asyncResp->res.jsonValue["Name"] = "Manager Ethernet Interface";
@@ -1325,52 +1312,24 @@ class EthernetInterface : public Node
const std::string &iface_id = params[0];
- std::optional<nlohmann::json> vlan;
std::optional<std::string> hostname;
std::optional<std::string> macAddress;
std::optional<nlohmann::json> ipv4Addresses;
std::optional<nlohmann::json> ipv6Addresses;
- if (!json_util::readJson(req, res, "VLAN", vlan, "HostName", hostname,
- "IPv4Addresses", ipv4Addresses,
- "IPv6Addresses", ipv6Addresses, "MACAddress",
- macAddress))
+ if (!json_util::readJson(
+ req, res, "HostName", hostname, "IPv4Addresses", ipv4Addresses,
+ "IPv6Addresses", ipv6Addresses, "MACAddress", macAddress))
{
return;
}
- std::optional<uint64_t> vlanId;
- std::optional<bool> vlanEnable;
-
- if (vlan)
- {
- if (!json_util::readJson(*vlan, res, "VLANEnable", vlanEnable,
- "VLANId", vlanId))
- {
- return;
- }
- // Need both vlanId and vlanEnable to service this request
- if (static_cast<bool>(vlanId) ^ static_cast<bool>(vlanEnable))
- {
- if (vlanId)
- {
- messages::propertyMissing(asyncResp->res, "VLANEnable");
- }
- else
- {
- messages::propertyMissing(asyncResp->res, "VLANId");
- }
-
- return;
- }
- }
-
// Get single eth interface data, and call the below callback for JSON
// preparation
getEthernetIfaceData(
iface_id,
- [this, asyncResp, iface_id, vlanId, vlanEnable,
- hostname = std::move(hostname), macAddress = std::move(macAddress),
+ [this, asyncResp, iface_id, hostname = std::move(hostname),
+ macAddress = std::move(macAddress),
ipv4Addresses = std::move(ipv4Addresses),
ipv6Addresses = std::move(ipv6Addresses)](
const bool &success, const EthernetInterfaceData &ethData,
@@ -1380,20 +1339,14 @@ class EthernetInterface : public Node
// ... otherwise return error
// TODO(Pawel)consider distinguish between non existing
// object, and other errors
- messages::resourceNotFound(
- asyncResp->res, "VLAN Network Interface", iface_id);
+ messages::resourceNotFound(asyncResp->res,
+ "Ethernet Interface", iface_id);
return;
}
parseInterfaceData(asyncResp->res.jsonValue, iface_id, ethData,
ipv4Data);
- if (vlanId && vlanEnable)
- {
- handleVlanPatch(iface_id, *vlanId, *vlanEnable, ethData,
- asyncResp);
- }
-
if (hostname)
{
handleHostnamePatch(*hostname, asyncResp);
@@ -1464,20 +1417,16 @@ class VlanNetworkInterface : public Node
"/VLANs/" + iface_id;
json_response["VLANEnable"] = true;
- if (ethData.vlan_id)
+ if (!ethData.vlan_id.empty())
{
- json_response["VLANId"] = *ethData.vlan_id;
+ json_response["VLANId"] = ethData.vlan_id.back();
}
}
- bool verifyNames(crow::Response &res, const std::string &parent,
- const std::string &iface)
+ bool verifyNames(const std::string &parent, const std::string &iface)
{
- std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
if (!boost::starts_with(iface, parent + "_"))
{
- messages::resourceNotFound(asyncResp->res, "VLAN Network Interface",
- iface);
return false;
}
else
@@ -1512,7 +1461,7 @@ class VlanNetworkInterface : public Node
"/redfish/v1/$metadata#VLanNetworkInterface.VLanNetworkInterface";
res.jsonValue["Name"] = "VLAN Network Interface";
- if (!verifyNames(res, parent_iface_id, iface_id))
+ if (!verifyNames(parent_iface_id, iface_id))
{
return;
}
@@ -1520,11 +1469,12 @@ class VlanNetworkInterface : public Node
// Get single eth interface data, and call the below callback for JSON
// preparation
getEthernetIfaceData(
- iface_id,
- [this, asyncResp, parent_iface_id, iface_id](
+ params[1],
+ [this, asyncResp, parent_iface_id{std::string(params[0])},
+ iface_id{std::string(params[1])}](
const bool &success, const EthernetInterfaceData &ethData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data) {
- if (success && ethData.vlan_id)
+ if (success && ethData.vlan_id.size() != 0)
{
parseInterfaceData(asyncResp->res.jsonValue,
parent_iface_id, iface_id, ethData,
@@ -1554,8 +1504,10 @@ class VlanNetworkInterface : public Node
const std::string &parentIfaceId = params[0];
const std::string &ifaceId = params[1];
- if (!verifyNames(res, parentIfaceId, ifaceId))
+ if (!verifyNames(parentIfaceId, ifaceId))
{
+ messages::resourceNotFound(asyncResp->res, "VLAN Network Interface",
+ ifaceId);
return;
}
@@ -1606,20 +1558,22 @@ class VlanNetworkInterface : public Node
const std::string &parentIfaceId = params[0];
const std::string &ifaceId = params[1];
- if (!verifyNames(asyncResp->res, parentIfaceId, ifaceId))
+ if (!verifyNames(parentIfaceId, ifaceId))
{
+ messages::resourceNotFound(asyncResp->res, "VLAN Network Interface",
+ ifaceId);
return;
}
// Get single eth interface data, and call the below callback for JSON
// preparation
getEthernetIfaceData(
- ifaceId,
- [this, asyncResp, parentIfaceId{std::string(parentIfaceId)},
- ifaceId{std::string(ifaceId)}](
+ params[1],
+ [this, asyncResp, parentIfaceId{std::string(params[0])},
+ ifaceId{std::string(params[1])}](
const bool &success, const EthernetInterfaceData &ethData,
const boost::container::flat_set<IPv4AddressData> &ipv4Data) {
- if (success && ethData.vlan_id)
+ if (success && !ethData.vlan_id.empty())
{
parseInterfaceData(asyncResp->res.jsonValue, parentIfaceId,
ifaceId, ethData, ipv4Data);
@@ -1720,12 +1674,6 @@ class VlanNetworkInterfaceCollection : public Node
}
}
- if (iface_array.empty())
- {
- messages::resourceNotFound(
- asyncResp->res, "EthernetInterface", rootInterfaceName);
- return;
- }
asyncResp->res.jsonValue["Members@odata.count"] =
iface_array.size();
asyncResp->res.jsonValue["Members"] = std::move(iface_array);
@@ -1744,12 +1692,27 @@ class VlanNetworkInterfaceCollection : public Node
messages::internalError(asyncResp->res);
return;
}
-
+ bool vlanEnable = false;
uint32_t vlanId = 0;
- if (!json_util::readJson(req, res, "VLANId", vlanId))
+ if (!json_util::readJson(req, res, "VLANId", vlanId, "VLANEnable",
+ vlanEnable))
+ {
+ return;
+ }
+ // Need both vlanId and vlanEnable to service this request
+ if (!vlanId)
+ {
+ messages::propertyMissing(asyncResp->res, "VLANId");
+ }
+ if (!vlanEnable)
+ {
+ messages::propertyMissing(asyncResp->res, "VLANEnable");
+ }
+ if (static_cast<bool>(vlanId) ^ static_cast<bool>(vlanEnable))
{
return;
}
+
const std::string &rootInterfaceName = params[0];
auto callback = [asyncResp](const boost::system::error_code ec) {
if (ec)