xref: /openbmc/bmcweb/redfish-core/include/utils/manager_utils.hpp (revision 0775449c62385f163a207d0f0c8e1f6338de1062)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 #pragma once
4 
5 #include "bmcweb_config.h"
6 
7 #include "async_resp.hpp"
8 #include "dbus_utility.hpp"
9 #include "error_messages.hpp"
10 #include "logging.hpp"
11 #include "persistent_data.hpp"
12 
13 #include <nlohmann/json.hpp>
14 
15 #include <array>
16 #include <cstddef>
17 #include <functional>
18 #include <memory>
19 #include <string_view>
20 #include <utility>
21 
22 namespace redfish
23 {
24 
25 constexpr std::array<std::string_view, 1> bmcInterfaces = {
26     "xyz.openbmc_project.Inventory.Item.Bmc"};
27 namespace manager_utils
28 {
29 
30 inline void setServiceIdentification(
31     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32     std::string_view serviceIdentification)
33 {
34     constexpr const size_t maxStrSize = 99;
35     constexpr const char* allowedChars =
36         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 _-";
37     if (serviceIdentification.size() > maxStrSize)
38     {
39         messages::stringValueTooLong(asyncResp->res, "ServiceIdentification",
40                                      maxStrSize);
41         return;
42     }
43     if (serviceIdentification.find_first_not_of(allowedChars) !=
44         std::string_view::npos)
45     {
46         messages::propertyValueError(asyncResp->res, "ServiceIdentification");
47         return;
48     }
49 
50     persistent_data::ConfigFile& config = persistent_data::getConfig();
51     config.serviceIdentification = serviceIdentification;
52     config.writeData();
53     messages::success(asyncResp->res);
54 }
55 
56 inline void getServiceIdentification(
57     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
58     const bool isServiceRoot)
59 {
60     std::string_view serviceIdentification =
61         persistent_data::getConfig().serviceIdentification;
62 
63     // This property shall not be present if its value is an empty string or
64     // null: Redfish Data Model Specification 6.125.3
65     if (isServiceRoot && serviceIdentification.empty())
66     {
67         return;
68     }
69     asyncResp->res.jsonValue["ServiceIdentification"] = serviceIdentification;
70 }
71 
72 inline void afterGetValidManagerPath(
73     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
74     const std::string& managerId,
75     const std::function<
76         void(const std::string& managerPath,
77              const dbus::utility::MapperServiceMap& serviceMap)>& callback,
78     const boost::system::error_code& ec,
79     const dbus::utility::MapperGetSubTreeResponse& subtree)
80 {
81     if (ec)
82     {
83         if (ec == boost::system::errc::io_error)
84         {
85             // Not found
86             BMCWEB_LOG_WARNING("Manager {} not found", managerId);
87             messages::resourceNotFound(asyncResp->res, "Manager", managerId);
88             return;
89         }
90         BMCWEB_LOG_ERROR("D-Bus response error {}", ec.value());
91         messages::internalError(asyncResp->res);
92         return;
93     }
94     if (subtree.empty())
95     {
96         BMCWEB_LOG_WARNING("Manager {} not found", managerId);
97         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
98         return;
99     }
100 
101     if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
102     {
103         messages::resourceNotFound(asyncResp->res, "Manager", managerId);
104         return;
105     }
106     // Assume only 1 bmc D-Bus object
107     // Throw an error if there is more than 1
108     if (subtree.size() > 1)
109     {
110         BMCWEB_LOG_ERROR("Found more than 1 bmc D-Bus object!");
111         messages::internalError(asyncResp->res);
112         return;
113     }
114 
115     callback(subtree[0].first, subtree[0].second);
116 }
117 
118 inline void getValidManagerPath(
119     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
120     const std::string& managerId,
121     std::function<void(const std::string& managerPath,
122                        const dbus::utility::MapperServiceMap& serviceMap)>&&
123         callback)
124 {
125     dbus::utility::getSubTree(
126         "/xyz/openbmc_project/inventory", 0, bmcInterfaces,
127         [asyncResp, managerId, callback = std::move(callback)](
128             const boost::system::error_code& ec,
129             const dbus::utility::MapperGetSubTreeResponse& subtree) {
130             afterGetValidManagerPath(asyncResp, managerId, callback, ec,
131                                      subtree);
132         });
133 }
134 
135 } // namespace manager_utils
136 
137 } // namespace redfish
138