cloud_sdk/operation/prepared/
read_only_post.rs1use crate::authentication::{AuthenticationScopePolicy, ScopeRequirement};
4use crate::operation::{
5 CostIntent, OperationId, OperationImpact, OperationMetadata, RequestIdPolicy, RequestSemantics,
6 RetryEligibility,
7};
8use crate::transport::{EndpointIdentity, EndpointPolicy, EndpointScheme, TransportRequest};
9use crate::{Method, operation_id};
10
11use super::{ProviderService, RequestBodySensitivity};
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
18#[non_exhaustive]
19pub enum ApprovedReadOnlyPostQuery {
20 HetznerRobotTraffic,
22}
23
24impl ApprovedReadOnlyPostQuery {
25 pub(super) fn validate(
26 self,
27 request: TransportRequest<'_>,
28 service: ProviderService<'_>,
29 metadata: OperationMetadata,
30 authentication: AuthenticationScopePolicy<'_>,
31 body_sensitivity: RequestBodySensitivity,
32 ) -> Option<OperationId> {
33 match self {
34 Self::HetznerRobotTraffic => {
35 let endpoint = EndpointIdentity::new(
36 EndpointScheme::Https,
37 "robot-ws.your-server.de",
38 443,
39 "/",
40 )
41 .ok()?;
42 let expected_authentication = AuthenticationScopePolicy::new(
43 ScopeRequirement::Required(service.provider_id()),
44 ScopeRequirement::Required(service.service_id()),
45 ScopeRequirement::Required(endpoint),
46 ScopeRequirement::Forbidden,
47 ScopeRequirement::Forbidden,
48 ScopeRequirement::Forbidden,
49 );
50 let headers = request.headers();
51 let accept = headers.get("accept")?;
52 let content_type = headers.get("content-type")?;
53 (request.method() == Method::Post
54 && request.target().as_str() == "/traffic"
55 && !request.body().is_empty()
56 && headers.as_slice().len() == 2
57 && accept.value().as_str() == "application/json"
58 && content_type.value().as_str() == "application/x-www-form-urlencoded"
59 && service.provider_id().as_str() == "hetzner"
60 && service.service_id().as_str() == "robot"
61 && service.endpoint_policy() == EndpointPolicy::fixed(endpoint)
62 && authentication == expected_authentication
63 && metadata.impact() == OperationImpact::ReadOnly
64 && metadata.semantics() == RequestSemantics::Safe
65 && metadata.retry_eligibility() == RetryEligibility::ExplicitPolicy
66 && metadata.cost_intent() == CostIntent::NoKnownCost
67 && metadata.request_id_policy() == RequestIdPolicy::Discard
68 && body_sensitivity == RequestBodySensitivity::Sensitive)
69 .then_some(operation_id!("robot_get_traffic"))
70 }
71 }
72 }
73}