redfish_axum/
storage_controller.rs

1// Generated by redfish-codegen. Do not modify.
2
3/// The default privileges required for accessing StorageController instances.
4pub struct DefaultPrivileges;
5impl redfish_core::privilege::OperationPrivilegeMapping for DefaultPrivileges {
6    type Get = redfish_core::privilege::Login;
7    type Head = redfish_core::privilege::Login;
8    type Post = redfish_core::privilege::ConfigureComponents;
9    type Put = redfish_core::privilege::ConfigureComponents;
10    type Patch = redfish_core::privilege::ConfigureComponents;
11    type Delete = redfish_core::privilege::ConfigureComponents;
12}
13
14/// The privileges required for accessing [EnvironmentMetrics][crate::environment_metrics::EnvironmentMetrics] instances as properties of
15/// a StorageController instance.
16pub struct EnvironmentMetricsPrivileges;
17impl redfish_core::privilege::OperationPrivilegeMapping for EnvironmentMetricsPrivileges {
18    type Get = redfish_core::privilege::Login;
19    type Head = redfish_core::privilege::Login;
20    type Post = redfish_core::privilege::ConfigureComponents;
21    type Put = redfish_core::privilege::ConfigureComponents;
22    type Patch = redfish_core::privilege::ConfigureComponents;
23    type Delete = redfish_core::privilege::ConfigureComponents;
24}
25
26/// This endpoint implements the StorageController component.
27///
28/// It can be mounted on the following components:
29/// * [StorageControllerCollection][crate::storage_controller_collection::StorageControllerCollection]
30pub struct StorageController<S, P>
31where
32    S: Clone,
33{
34    router: axum::routing::MethodRouter<S>,
35    privilege_marker: std::marker::PhantomData<fn() -> P>,
36    allowed_methods: Vec<axum::http::method::Method>,
37    environment_metrics: Option<axum::Router<S>>,
38    metrics: Option<axum::Router<S>>,
39    attach_namespaces: Option<axum::routing::MethodRouter<S>>,
40    detach_namespaces: Option<axum::routing::MethodRouter<S>>,
41    security_receive: Option<axum::routing::MethodRouter<S>>,
42    security_send: Option<axum::routing::MethodRouter<S>>,
43}
44
45impl<S> Default for StorageController<S, DefaultPrivileges>
46where
47    S: Clone,
48{
49    fn default() -> Self {
50        Self {
51            router: Default::default(),
52            privilege_marker: Default::default(),
53            allowed_methods: Vec::new(),
54            environment_metrics: Default::default(),
55            metrics: Default::default(),
56            attach_namespaces: Default::default(),
57            detach_namespaces: Default::default(),
58            security_receive: Default::default(),
59            security_send: Default::default(),
60        }
61    }
62}
63
64impl<S, P> StorageController<S, P>
65where
66    S: AsRef<dyn redfish_core::auth::AuthenticateRequest> + Clone + Send + Sync + 'static,
67    P: redfish_core::privilege::OperationPrivilegeMapping + 'static,
68    <P as redfish_core::privilege::OperationPrivilegeMapping>::Get: Send,
69    <P as redfish_core::privilege::OperationPrivilegeMapping>::Put: Send,
70    <P as redfish_core::privilege::OperationPrivilegeMapping>::Patch: Send,
71    <P as redfish_core::privilege::OperationPrivilegeMapping>::Post: Send,
72{
73    pub fn get<H, T>(mut self, handler: H) -> Self
74    where
75        H: axum::handler::Handler<T, S, axum::body::Body>,
76        T: 'static,
77    {
78        let operation = axum::routing::get(
79            |auth: redfish_core::extract::RedfishAuth<P::Get>,
80             axum::extract::State(state): axum::extract::State<S>,
81             mut request: axum::http::Request<axum::body::Body>| async {
82                request.extensions_mut().insert(auth.user);
83                handler.call(request, state).await
84            },
85        );
86        self.router = self.router.get(operation);
87        self.allowed_methods.push(axum::http::method::Method::GET);
88        self
89    }
90
91    pub fn put<H, T>(mut self, handler: H) -> Self
92    where
93        H: axum::handler::Handler<T, S, axum::body::Body>,
94        T: 'static,
95    {
96        let operation = axum::routing::put(
97            |auth: redfish_core::extract::RedfishAuth<P::Put>,
98             axum::extract::State(state): axum::extract::State<S>,
99             mut request: axum::http::Request<axum::body::Body>| async {
100                request.extensions_mut().insert(auth.user);
101                handler.call(request, state).await
102            },
103        );
104        self.router = self.router.put(operation);
105        self.allowed_methods.push(axum::http::method::Method::PUT);
106        self
107    }
108
109    pub fn patch<H, T>(mut self, handler: H) -> Self
110    where
111        H: axum::handler::Handler<T, S, axum::body::Body>,
112        T: 'static,
113    {
114        let operation = axum::routing::patch(
115            |auth: redfish_core::extract::RedfishAuth<P::Patch>,
116             axum::extract::State(state): axum::extract::State<S>,
117             mut request: axum::http::Request<axum::body::Body>| async {
118                request.extensions_mut().insert(auth.user);
119                handler.call(request, state).await
120            },
121        );
122        self.router = self.router.patch(operation);
123        self.allowed_methods.push(axum::http::method::Method::PATCH);
124        self
125    }
126
127    /// Serves an instance of a [EnvironmentMetrics][crate::environment_metrics::EnvironmentMetrics].
128    pub fn environment_metrics(mut self, environment_metrics: axum::Router<S>) -> Self {
129        self.environment_metrics = Some(environment_metrics);
130        self
131    }
132
133    /// Serves an instance of a [StorageControllerMetrics][crate::storage_controller_metrics::StorageControllerMetrics].
134    pub fn metrics(mut self, metrics: axum::Router<S>) -> Self {
135        self.metrics = Some(metrics);
136        self
137    }
138
139    /// Perform the AttachNamespaces operation on this StorageController instance.
140    pub fn attach_namespaces<H, T>(mut self, handler: H) -> Self
141    where
142        H: axum::handler::Handler<T, S, axum::body::Body>,
143        T: 'static,
144    {
145        self.attach_namespaces = Some(axum::routing::post(
146            |auth: redfish_core::extract::RedfishAuth<P::Post>,
147             axum::extract::State(state): axum::extract::State<S>,
148             mut request: axum::http::Request<axum::body::Body>| async {
149                request.extensions_mut().insert(auth.user);
150                handler.call(request, state).await
151            },
152        ));
153        self
154    }
155
156    /// Perform the DetachNamespaces operation on this StorageController instance.
157    pub fn detach_namespaces<H, T>(mut self, handler: H) -> Self
158    where
159        H: axum::handler::Handler<T, S, axum::body::Body>,
160        T: 'static,
161    {
162        self.detach_namespaces = Some(axum::routing::post(
163            |auth: redfish_core::extract::RedfishAuth<P::Post>,
164             axum::extract::State(state): axum::extract::State<S>,
165             mut request: axum::http::Request<axum::body::Body>| async {
166                request.extensions_mut().insert(auth.user);
167                handler.call(request, state).await
168            },
169        ));
170        self
171    }
172
173    /// Perform the SecurityReceive operation on this StorageController instance.
174    pub fn security_receive<H, T>(mut self, handler: H) -> Self
175    where
176        H: axum::handler::Handler<T, S, axum::body::Body>,
177        T: 'static,
178    {
179        self.security_receive = Some(axum::routing::post(
180            |auth: redfish_core::extract::RedfishAuth<P::Post>,
181             axum::extract::State(state): axum::extract::State<S>,
182             mut request: axum::http::Request<axum::body::Body>| async {
183                request.extensions_mut().insert(auth.user);
184                handler.call(request, state).await
185            },
186        ));
187        self
188    }
189
190    /// Perform the SecuritySend operation on this StorageController instance.
191    pub fn security_send<H, T>(mut self, handler: H) -> Self
192    where
193        H: axum::handler::Handler<T, S, axum::body::Body>,
194        T: 'static,
195    {
196        self.security_send = Some(axum::routing::post(
197            |auth: redfish_core::extract::RedfishAuth<P::Post>,
198             axum::extract::State(state): axum::extract::State<S>,
199             mut request: axum::http::Request<axum::body::Body>| async {
200                request.extensions_mut().insert(auth.user);
201                handler.call(request, state).await
202            },
203        ));
204        self
205    }
206
207    pub fn into_router(self) -> axum::Router<S> {
208        let Self {
209            router,
210            mut allowed_methods,
211            environment_metrics,
212            metrics,
213            attach_namespaces,
214            detach_namespaces,
215            security_receive,
216            security_send,
217            ..
218        } = self;
219        let result = axum::Router::default();
220        let result = match environment_metrics {
221            Some(router) => result.nest("/EnvironmentMetrics", router),
222            None => result,
223        };
224        let result = match metrics {
225            Some(router) => result.nest("/Metrics", router),
226            None => result,
227        };
228        let result = match attach_namespaces {
229            Some(router) => result.route("/Actions/StorageController.AttachNamespaces", router),
230            None => result,
231        };
232        let result = match detach_namespaces {
233            Some(router) => result.route("/Actions/StorageController.DetachNamespaces", router),
234            None => result,
235        };
236        let result = match security_receive {
237            Some(router) => result.route("/Actions/StorageController.SecurityReceive", router),
238            None => result,
239        };
240        let result = match security_send {
241            Some(router) => result.route("/Actions/StorageController.SecuritySend", router),
242            None => result,
243        };
244        allowed_methods.dedup();
245        let allow_header = allowed_methods
246            .into_iter()
247            .map(|method| method.to_string())
248            .reduce(|one, two| one + "," + &two)
249            .unwrap();
250        result.route(
251            "/",
252            router.fallback(|| async {
253                (
254                    axum::http::StatusCode::METHOD_NOT_ALLOWED,
255                    axum::Json(redfish_core::error::one_message(redfish_codegen::registries::base::v1_16_0::Base::OperationNotAllowed.into())),
256                )
257            })
258            .route_layer(axum::middleware::from_fn_with_state(
259                allow_header,
260                |axum::extract::State(allow_header): axum::extract::State<String>,
261                 request: axum::http::Request<axum::body::Body>,
262                 next: axum::middleware::Next<axum::body::Body>| async move {
263                    let apply_allow = matches!(*request.method(), axum::http::Method::GET | axum::http::Method::HEAD);
264                    let mut response = next.run(request).await;
265                    if apply_allow && !response.headers().contains_key(axum::http::header::ALLOW) {
266                        response.headers_mut().insert(
267                            axum::http::header::ALLOW,
268                            axum::http::HeaderValue::from_str(&allow_header).unwrap(),
269                        );
270                    }
271                    response
272                },
273            )),
274        )
275    }
276}