use crate::prelude::*;

// WARNING: generated by kopium - manual changes will be overwritten
// kopium command: kopium -f /home/mmoreiradj/git/crd-rs/crds/cilium/v2/ciliumbgpclusterconfigs.yaml --schema=derived -d --hide-prelude
// kopium version: 0.22.5

/// Spec defines the desired cluster configuration of the BGP control plane.
#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)]
#[kube(
    group = "cilium.io",
    version = "v2",
    kind = "CiliumBGPClusterConfig",
    plural = "ciliumbgpclusterconfigs"
)]
#[kube(status = "CiliumBgpClusterConfigStatus")]
pub struct CiliumBgpClusterConfigSpec {
    /// A list of CiliumBGPInstance(s) which instructs
    /// the BGP control plane how to instantiate virtual BGP routers.
    #[serde(rename = "bgpInstances")]
    pub bgp_instances: Vec<CiliumBgpClusterConfigBgpInstances>,
    /// NodeSelector selects a group of nodes where this BGP Cluster
    /// config applies.
    /// If empty / nil this config applies to all nodes.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "nodeSelector"
    )]
    pub node_selector: Option<CiliumBgpClusterConfigNodeSelector>,
}

#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumBgpClusterConfigBgpInstances {
    /// LocalASN is the ASN of this BGP instance.
    /// Supports extended 32bit ASNs.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "localASN")]
    pub local_asn: Option<i64>,
    /// LocalPort is the port on which the BGP daemon listens for incoming connections.
    ///
    /// If not specified, BGP instance will not listen for incoming connections.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "localPort")]
    pub local_port: Option<i32>,
    /// Name is the name of the BGP instance. It is a unique identifier for the BGP instance
    /// within the cluster configuration.
    pub name: String,
    /// Peers is a list of neighboring BGP peers for this virtual router
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub peers: Option<Vec<CiliumBgpClusterConfigBgpInstancesPeers>>,
}

#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumBgpClusterConfigBgpInstancesPeers {
    /// AutoDiscovery is the configuration for auto-discovery of the peer address.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "autoDiscovery"
    )]
    pub auto_discovery: Option<CiliumBgpClusterConfigBgpInstancesPeersAutoDiscovery>,
    /// Name is the name of the BGP peer. It is a unique identifier for the peer within the BGP instance.
    pub name: String,
    /// PeerASN is the ASN of the peer BGP router.
    /// Supports extended 32bit ASNs.
    ///
    /// If peerASN is 0, the BGP OPEN message validation of ASN will be disabled and
    /// ASN will be determined based on peer's OPEN message.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "peerASN")]
    pub peer_asn: Option<i64>,
    /// PeerAddress is the IP address of the neighbor.
    /// Supports IPv4 and IPv6 addresses.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "peerAddress"
    )]
    pub peer_address: Option<String>,
    /// PeerConfigRef is a reference to a peer configuration resource.
    /// If not specified, the default BGP configuration is used for this peer.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "peerConfigRef"
    )]
    pub peer_config_ref: Option<CiliumBgpClusterConfigBgpInstancesPeersPeerConfigRef>,
}

/// AutoDiscovery is the configuration for auto-discovery of the peer address.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumBgpClusterConfigBgpInstancesPeersAutoDiscovery {
    /// defaultGateway is the configuration for auto-discovery of the default gateway.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "defaultGateway"
    )]
    pub default_gateway: Option<CiliumBgpClusterConfigBgpInstancesPeersAutoDiscoveryDefaultGateway>,
    /// mode is the mode of the auto-discovery.
    pub mode: CiliumBgpClusterConfigBgpInstancesPeersAutoDiscoveryMode,
}

/// defaultGateway is the configuration for auto-discovery of the default gateway.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumBgpClusterConfigBgpInstancesPeersAutoDiscoveryDefaultGateway {
    /// addressFamily is the address family of the default gateway.
    #[serde(rename = "addressFamily")]
    pub address_family:
        CiliumBgpClusterConfigBgpInstancesPeersAutoDiscoveryDefaultGatewayAddressFamily,
}

/// defaultGateway is the configuration for auto-discovery of the default gateway.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub enum CiliumBgpClusterConfigBgpInstancesPeersAutoDiscoveryDefaultGatewayAddressFamily {
    #[serde(rename = "ipv4")]
    Ipv4,
    #[serde(rename = "ipv6")]
    Ipv6,
}

/// AutoDiscovery is the configuration for auto-discovery of the peer address.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub enum CiliumBgpClusterConfigBgpInstancesPeersAutoDiscoveryMode {
    DefaultGateway,
}

/// PeerConfigRef is a reference to a peer configuration resource.
/// If not specified, the default BGP configuration is used for this peer.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumBgpClusterConfigBgpInstancesPeersPeerConfigRef {
    /// Name is the name of the peer config resource.
    /// Name refers to the name of a Kubernetes object (typically a CiliumBGPPeerConfig).
    pub name: String,
}

/// NodeSelector selects a group of nodes where this BGP Cluster
/// config applies.
/// If empty / nil this config applies to all nodes.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumBgpClusterConfigNodeSelector {
    /// matchExpressions is a list of label selector requirements. The requirements are ANDed.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "matchExpressions"
    )]
    pub match_expressions: Option<Vec<CiliumBgpClusterConfigNodeSelectorMatchExpressions>>,
    /// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
    /// map is equivalent to an element of matchExpressions, whose key field is "key", the
    /// operator is "In", and the values array contains only "value". The requirements are ANDed.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "matchLabels"
    )]
    pub match_labels: Option<BTreeMap<String, String>>,
}

/// A label selector requirement is a selector that contains values, a key, and an operator that
/// relates the key and values.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumBgpClusterConfigNodeSelectorMatchExpressions {
    /// key is the label key that the selector applies to.
    pub key: String,
    /// operator represents a key's relationship to a set of values.
    /// Valid operators are In, NotIn, Exists and DoesNotExist.
    pub operator: CiliumBgpClusterConfigNodeSelectorMatchExpressionsOperator,
    /// values is an array of string values. If the operator is In or NotIn,
    /// the values array must be non-empty. If the operator is Exists or DoesNotExist,
    /// the values array must be empty. This array is replaced during a strategic
    /// merge patch.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub values: Option<Vec<String>>,
}

/// A label selector requirement is a selector that contains values, a key, and an operator that
/// relates the key and values.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub enum CiliumBgpClusterConfigNodeSelectorMatchExpressionsOperator {
    In,
    NotIn,
    Exists,
    DoesNotExist,
}

/// Status is a running status of the cluster configuration
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumBgpClusterConfigStatus {
    /// The current conditions of the CiliumBGPClusterConfig
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub conditions: Option<Vec<Condition>>,
}
