blob: 29225292ec0fd937e50dd4f8f05624abe93f098f [file]
#ifndef THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_SERVER_H_
#define THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_SERVER_H_
// The headers with NOLINT are necessary dependencies that are commonly used in
// gBMC's tech stack.
#include <cstddef>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/statusor.h"
#include "boost/asio/io_context.hpp" // NOLINT
#include "boost/asio/thread_pool.hpp" // NOLINT
#include "boost/beast/http/verb.hpp" // NOLINT
#include "boost/uuid/uuid.hpp" // NOLINT
#include "boost/uuid/uuid_generators.hpp" // NOLINT
#include "boost/uuid/uuid_io.hpp" // NOLINT
#include "subscription.h"
#include "redfish_v1.grpc.pb.h"
#include "redfish_v1.pb.h"
#include "redfish_v1_grpc_include.h"
#include "time/clock.h"
#include "app.hpp"
#include "grpcpp/support/status.h"
#include "tlbmc/service/fru_service.h"
#include "tlbmc/credentials/credential_manager.h"
#include "tlbmc/deterministic_bmc/offline_config_parser/proto_reader.h"
#include "tlbmc/hal/nic_veeprom/interface.h"
#include "veeprom.pb.h"
#include "tlbmc/hal/system_registry.h"
#include "tlbmc/hft/core/hft_service.h"
#include "tlbmc/redfish/app.h"
#include "g3/grpc_headers.h"
#include "rate_limiter.h"
#include "zatar/bmcweb_cert_provider.h"
namespace milotic {
// The configuration for the Redfish service.
struct RedfishServiceConfig {
int port = 443;
std::string trust_bundle_path = "/var/google/trust_bundle/trust_bundle.pem";
std::string private_key_path = "/var/volatile/prodid/server.pem";
std::string own_cert_path = "/var/volatile/prodid/server.pem";
std::string self_signed_key_cert_path =
"/var/volatile/self_signed_key_cert.pem";
std::string crl_directory = "/var/google/loas3/crl";
std::string authz_config_path = "/var/google/authz_policies/redfish.json";
std::string authz_platform_config_path =
"/var/google/authz_policies/redfish_platform_addendum.json";
std::string persistent_base_privileges_folder = "/var/google/authz_policies";
std::string rofs_base_privileges_folder = "/usr/share/redfish_privileges";
std::string gmi_file_path =
"/var/google/googlemachineidentity/live/machine_identity.pb";
std::string oauth_key_path = "/var/volatile/oauth_public_key.pem";
std::string pattern_to_entity_overrides_path =
"/usr/share/redfish_privileges/pattern_to_uri.json";
std::string redfish_override_policy_path =
"/usr/share/redfish_override_policy";
std::string offline_node_entity_path =
"/var/google/googlemachineidentity/live/offline_node_entities.pb";
std::string authority_policy_file_binary = "/var/google/loas3/policy.pb";
std::string owner_verification_cert_path =
"/var/volatile/owner-verification/cert.pem";
std::string owner_verification_config_path =
"/var/volatile/owner-verification/config.textproto";
std::string bmc_ssh_trusted_user_ca_keys_path = "/run/ssh/trusted_ca_pubkeys";
std::string trust_bundle_signature_path =
"/var/google/trust_bundle/trust_bundle_sig.p7s";
std::string os_verification_cert_path = "/var/google/os-keys/cert.pem";
std::string os_verification_key_path = "/var/google/os-keys/key.pem";
std::string serial_console_trusted_user_ca_keys_path =
"/var/google/ssh/trusted_user_ca_keys.pub";
std::string serial_console_detatched_signature_path =
"/var/google/ssh/trusted_user_ca_keys_sig.p7s";
std::string serial_console_access_level_dir = "/run/bloom";
std::string syslog_client_conf_override_path =
"/var/google/production_syslog/client-override.conf";
std::string syslog_root_cert_path =
"/var/google/production_syslog/root_cert.pem";
std::string tlbmc_entity_config_location =
"/usr/share/entity-manager/configurations";
std::string tlbmc_proto_config_location = "/etc/tlbmc/";
std::string tlbmc_disable_file = "/var/google/tlbmc/disable_tlbmc";
std::string tlbmc_config_bundle_path =
"/var/google/tlbmc/tlbmc_config_bundle.textproto";
std::string tlbmc_release_file_path = "/etc/os-release";
std::string tlbmc_iio_sysfs_path = "/sys/bus/iio/devices/";
std::string tlbmc_i2c_sysfs_path = "/sys/bus/i2c/devices/";
std::string tlbmc_i3c_sysfs_path = "/sys/bus/i3c/devices/";
std::string tlbmc_led_sysfs_path = "/sys/class/leds/";
std::string tlbmc_peci_sysfs_path = "/sys/bus/peci";
std::string tlbmc_root_dir = "/";
// Uhmm offline config path for deterministic BMC. This is subject to change
// based on future deployments.
std::string uhmm_offline_data_path = "/var/google/uhmm/offline_data.txtpb";
deterministic_bmc::ProtoFormat uhmm_offline_data_format =
deterministic_bmc::ProtoFormat::kTextProto;
// Enable deterministic BMC feature for TLBMC.
bool enable_deterministic_periodic_fru_scanning = true;
int periodic_deterministic_fru_scan_interval_ms = 30 * 1000; // 30 seconds
// SMBIOS inventory binary file paths
std::string smbios_single_host_file_path = "/var/lib/smbios/smbios2";
std::string smbios_multihost_host_file_path_prefix =
"/var/lib/smbios/smbios-remote-host-";
// SMBIOS Status file paths
std::string smbios_single_host_status_file_path = "/run/smbios-mdr/status";
std::string smbios_multihost_host_status_file_path_prefix =
"/run/smbios-mdr/status-host-";
// SMBIOS Search paths
std::vector<std::string> smbios_search_paths = {};
// Enable multi-threading for the GET requests.
bool multi_thread_get = false;
// Enable tlBMC service. Note, tlBMC can be disabled if the server fails tlBMC
// store creation even if this flag is true.
bool enable_tlbmc = false;
// Enable pacemaker service.
bool enable_pacemaker = false;
// The maximum number of events to queue per client.
size_t maximum_event_queue_size = 1000;
// Disable the Redfish eventing.
bool disable_eventing = false;
// Disable Authentication and authorization. DO NOT USE in production.
bool enable_insecure_server = false;
// Generate a serials of testing events. DO NOT USE in production.
// This can be removed once we are able to inject a fake subscription service.
bool generate_testing_events = false;
// Record various latencies, such as time spent in job queue, total handler
// latency time, etc inside the response for profiling.
bool do_profiling = false;
// Check the existence of the LOAS3 validation policy. If set to true and the
// policy is not found, the server will start up without client verification
// and only allow recovery Redfish operations.
bool check_loas3_policy = false;
// Enable HFT service.
bool enable_hft = true;
// Enable Fast-Sanity service.
bool enable_fast_sanity = false;
// Enable HFT fake subscription manager.
bool enable_hft_fake_manager = false;
// Enable HFT test sensor injection for integration testing.
bool enable_hft_test_sensor = false;
// Enable TLBMC trace.
bool enable_tlbmc_trace = false;
// Enable TLBMC thermal control, which will disable phosphor-pid-control.
bool enable_tlbmc_thermal_control = false;
// Enable tlBMC Octeon10 EVK mode. In this mode, tlBMC will start with the
// super customized store for Octeon10 EVK.
bool enable_tlbmc_octeon10_evk = false;
// Unit test only.
bool tlbmc_in_unit_test = false;
// Unit test only.
bool tlbmc_unit_test_enable_fake_fram_scanner = false;
// Unit test only.
bool tlbmc_unit_test_enable_fake_gpio_collector = false;
// Unit test only.
bool tlbmc_unit_test_enable_fake_fru_collector_for_fast_sanity = false;
// Test only.
std::optional<absl::flat_hash_map<std::string, absl::StatusOr<std::string>>>
executor_command_map = std::nullopt;
// Clock for testing.
ecclesia::Clock* clock = ecclesia::Clock::RealClock();
// Defers the router registration and validation after tlBMC app
// creation, `CreateTlbmcApp`. So that programmer can choose when to use
// `RegisterTlbmcRoutesAndValidate`.
// By default, this is set to true, so that individual route test can register
// their own routes. Otherwise, `RegisterTlbmcRoutesAndValidate` will be
// called in `CreateTlbmcApp`, especially in platform e2e tests.
bool tlbmc_defer_router_registration_and_validation = true;
// System Registry for HAL Calls.
std::shared_ptr<::milotic_tlbmc::SystemRegistry> system_registry = nullptr;
std::shared_ptr<milotic_tlbmc::CredentialManager> credential_manager =
nullptr;
std::shared_ptr<absl::AnyInvocable<
std::unique_ptr<::milotic_tlbmc::nic_veeprom::Accessor>(
::milotic_tlbmc::nic_veeprom::NicTelemetryVersion version, int bus,
int address) const>>
nic_accessor_factory = nullptr;
};
// Checks server's creds state and request metadata/headers
grpc::Status SubscriptionPreCheck(
const grpc::AuthContext& auth_context,
const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata,
const ::redfish::v1::Request* request,
::milotic::redfish::BmcWebCertProvider::ServerStatus server_status);
class GrpcRedfishService {
public:
// Creates the TlBMC app, defers the router registration to
// `RegisterTlbmcRoutesAndValidate`.
// This never returns `nullptr` if `config.enable_tlbmc` is true and no force
// disable file is found.
static std::unique_ptr<milotic_tlbmc::RedfishApp> CreateTlbmcApp(
const RedfishServiceConfig& config);
// Registers all the routes and validates the router.
// Call this function only after you have set up smart router.
static void RegisterTlbmcRoutesAndValidate(
milotic_tlbmc::RedfishApp* app,
const std::string& system_root_path = "/");
// For server with no multi-thread support.
GrpcRedfishService(
App& app,
const std::shared_ptr<boost::asio::io_context>& io_context_main_thread,
const RedfishServiceConfig& config)
: GrpcRedfishService(app, io_context_main_thread, nullptr, config,
nullptr) {}
// If `SubscriptionService` is not available, the service will start without
// event support.
GrpcRedfishService(
App& app,
const std::shared_ptr<boost::asio::io_context>& io_context_main_thread,
const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
const RedfishServiceConfig& config)
: GrpcRedfishService(app, io_context_main_thread,
io_context_worker_threads, config, nullptr) {}
// The actual constructor that takes all the parameters.
GrpcRedfishService(
App* app, const milotic_tlbmc::RedfishApp* tlbmc_app,
const std::shared_ptr<boost::asio::io_context>& io_context_main_thread,
const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
const RedfishServiceConfig& config,
ecclesia::SubscriptionService* subscription_service);
// Traditional gBMCWeb only mode.
GrpcRedfishService(
App& app,
const std::shared_ptr<boost::asio::io_context>& io_context_main_thread,
const std::shared_ptr<boost::asio::io_context>& io_context_worker_threads,
const RedfishServiceConfig& config,
ecclesia::SubscriptionService* subscription_service)
: GrpcRedfishService(&app, nullptr, io_context_main_thread,
io_context_worker_threads, config,
subscription_service) {}
// TLBMC only mode.
GrpcRedfishService(const milotic_tlbmc::RedfishApp& tlbmc_app,
const RedfishServiceConfig& config)
: GrpcRedfishService(nullptr, &tlbmc_app, nullptr, nullptr, config,
nullptr) {}
void Wait() { server_->Wait(); }
milotic_hft::HftServiceImpl* GetHftService() { return hft_service_.get(); }
~GrpcRedfishService() { Shutdown(); }
#ifdef UNIT_TEST_BUILD
milotic_fast_sanity::FruServiceOptions fru_service_options_;
const RedfishServiceConfig& GetConfigForTest() const { return config_; }
#endif
private:
void Shutdown();
// `cert_provider_` must be initialized before and destructed after the other
// data members.
std::unique_ptr<::milotic::redfish::BmcWebCertProvider> cert_provider_;
RedfishServiceConfig config_;
std::unique_ptr<crow::RateLimiter> rate_limiter_;
std::unique_ptr<ecclesia::GrpcRedfishV1::CallbackService> service_;
std::unique_ptr<milotic_fast_sanity::FruServiceImpl> fru_service_;
ecclesia::SubscriptionService* subscription_service_ = nullptr;
std::unique_ptr<milotic_hft::HftServiceImpl> hft_service_;
std::unique_ptr<grpc::Server> server_;
};
} // namespace milotic
#endif // THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_SERVER_H_