|  | 
|  | 1 | +use core::net::IpAddr; | 
|  | 2 | + | 
|  | 3 | +use oauth10a::rest::RestClient; | 
|  | 4 | +use serde::{Deserialize, Serialize}; | 
|  | 5 | + | 
|  | 6 | +use crate::{Client, EndpointError, RestError, v4::ErrorResponse}; | 
|  | 7 | + | 
|  | 8 | +use super::{ | 
|  | 9 | +    MemberId, OwnerId, network_group_id::NetworkGroupId, peer::PeerId, | 
|  | 10 | +    wireguard::WireGuardPublicKey, | 
|  | 11 | +}; | 
|  | 12 | + | 
|  | 13 | +// PEER ROLE /////////////////////////////////////////////////////////////////// | 
|  | 14 | + | 
|  | 15 | +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] | 
|  | 16 | +pub enum PeerRole { | 
|  | 17 | +    #[serde(rename = "CLIENT")] | 
|  | 18 | +    Client, | 
|  | 19 | +    #[serde(rename = "SERVER")] | 
|  | 20 | +    Server, | 
|  | 21 | +} | 
|  | 22 | + | 
|  | 23 | +// PEER CREATED //////////////////////////////////////////////////////////////// | 
|  | 24 | + | 
|  | 25 | +/// Response from [`WannabePeer`] and [`WannabeExternalPeer`] requests. | 
|  | 26 | +#[derive(Debug, Deserialize)] | 
|  | 27 | +pub struct PeerCreated { | 
|  | 28 | +    #[serde(rename = "peerId")] | 
|  | 29 | +    pub peer_id: PeerId, | 
|  | 30 | +} | 
|  | 31 | + | 
|  | 32 | +// ERROR /////////////////////////////////////////////////////////////////////// | 
|  | 33 | + | 
|  | 34 | +#[derive(Debug, thiserror::Error)] | 
|  | 35 | +pub enum Error { | 
|  | 36 | +    #[error(transparent)] | 
|  | 37 | +    Endpoint(#[from] EndpointError), | 
|  | 38 | +    #[error("failed to post Wannabe External Peer for owner '{0}', network group '{1}', {0}")] | 
|  | 39 | +    Post(String, NetworkGroupId, RestError), | 
|  | 40 | +    #[error(transparent)] | 
|  | 41 | +    Status(#[from] ErrorResponse), | 
|  | 42 | +} | 
|  | 43 | + | 
|  | 44 | +// WANNABE EXTERNAL PEER /////////////////////////////////////////////////////// | 
|  | 45 | + | 
|  | 46 | +/// Request to join a Network Group as an external peer. | 
|  | 47 | +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] | 
|  | 48 | +pub struct WannabeExternalPeer { | 
|  | 49 | +    /// Label of a Network Group peer. | 
|  | 50 | +    #[serde(rename = "label")] | 
|  | 51 | +    pub label: String, | 
|  | 52 | +    /// The public IP v4 or v6 on which the peer is listening, | 
|  | 53 | +    /// when `peer_role` is [`PeerRole::Server`]. | 
|  | 54 | +    #[serde(rename = "ip", skip_serializing_if = "Option::is_none")] | 
|  | 55 | +    pub ip: Option<IpAddr>, | 
|  | 56 | +    /// The public TCP or UDP port number on which the peer is listening, | 
|  | 57 | +    /// when `peer_role` is [`PeerRole::Server`]. | 
|  | 58 | +    #[serde(rename = "port", skip_serializing_if = "Option::is_none")] | 
|  | 59 | +    pub port: Option<u16>, | 
|  | 60 | +    /// The role of this peer in the Network Group. | 
|  | 61 | +    #[serde(rename = "peerRole")] | 
|  | 62 | +    pub peer_role: PeerRole, | 
|  | 63 | +    /// Base64-encoded WireGuard public key of the peer. | 
|  | 64 | +    #[serde(rename = "publicKey")] | 
|  | 65 | +    pub public_key: WireGuardPublicKey, | 
|  | 66 | +    /// Host name of the peer. | 
|  | 67 | +    #[serde(rename = "hostname", skip_serializing_if = "Option::is_none")] | 
|  | 68 | +    pub hostname: Option<String>, | 
|  | 69 | +    /// Event that created the peer within the Network Group. | 
|  | 70 | +    #[serde(rename = "parentEvent", skip_serializing_if = "Option::is_none")] | 
|  | 71 | +    pub parent_event: Option<String>, | 
|  | 72 | +    /// Unique ID of a Network Group member. | 
|  | 73 | +    #[serde(rename = "parentMember")] | 
|  | 74 | +    pub parent_member: MemberId, | 
|  | 75 | +} | 
|  | 76 | + | 
|  | 77 | +impl WannabeExternalPeer { | 
|  | 78 | +    pub async fn post( | 
|  | 79 | +        &self, | 
|  | 80 | +        client: &Client, | 
|  | 81 | +        owner_id: &OwnerId, | 
|  | 82 | +        ng_id: &NetworkGroupId, | 
|  | 83 | +    ) -> Result<PeerCreated, Error> { | 
|  | 84 | +        let endpoint = client.endpoint(format_args!( | 
|  | 85 | +            "/v4/networkgroups/organisations/{owner_id}/networkgroups/{ng_id}/external-peers" | 
|  | 86 | +        ))?; | 
|  | 87 | + | 
|  | 88 | +        debug!( | 
|  | 89 | +            %endpoint, | 
|  | 90 | +            owner = %owner_id, | 
|  | 91 | +            network_group = %ng_id, | 
|  | 92 | +            "execute a request to join Network Group" | 
|  | 93 | +        ); | 
|  | 94 | + | 
|  | 95 | +        Ok(client | 
|  | 96 | +            .post(endpoint, self) | 
|  | 97 | +            .await | 
|  | 98 | +            .map_err(|e| Error::Post(owner_id.to_owned(), *ng_id, e))??) | 
|  | 99 | +    } | 
|  | 100 | +} | 
0 commit comments