use crate::prelude::*;

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

#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, JsonSchema)]
#[kube(
    group = "cilium.io",
    version = "v2",
    kind = "CiliumClusterwideEnvoyConfig",
    plural = "ciliumclusterwideenvoyconfigs"
)]
pub struct CiliumClusterwideEnvoyConfigSpec {
    /// BackendServices specifies Kubernetes services whose backends
    /// are automatically synced to Envoy using EDS.  Traffic for these
    /// services is not forwarded to an Envoy listener. This allows an
    /// Envoy listener load balance traffic to these backends while
    /// normal Cilium service load balancing takes care of balancing
    /// traffic for these services at the same time.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "backendServices"
    )]
    pub backend_services: Option<Vec<CiliumClusterwideEnvoyConfigBackendServices>>,
    /// NodeSelector is a label selector that determines to which nodes
    /// this configuration applies.
    /// If nil, then this config applies to all nodes.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "nodeSelector"
    )]
    pub node_selector: Option<CiliumClusterwideEnvoyConfigNodeSelector>,
    /// Envoy xDS resources, a list of the following Envoy resource types:
    /// type.googleapis.com/envoy.config.listener.v3.Listener,
    /// type.googleapis.com/envoy.config.route.v3.RouteConfiguration,
    /// type.googleapis.com/envoy.config.cluster.v3.Cluster,
    /// type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment, and
    /// type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret.
    pub resources: Vec<BTreeMap<String, serde_json::Value>>,
    /// Services specifies Kubernetes services for which traffic is
    /// forwarded to an Envoy listener for L7 load balancing. Backends
    /// of these services are automatically synced to Envoy usign EDS.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub services: Option<Vec<CiliumClusterwideEnvoyConfigServices>>,
}

#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumClusterwideEnvoyConfigBackendServices {
    /// Name is the name of a destination Kubernetes service that identifies traffic
    /// to be redirected.
    pub name: String,
    /// Namespace is the Kubernetes service namespace.
    /// In CiliumEnvoyConfig namespace defaults to the namespace of the CEC,
    /// In CiliumClusterwideEnvoyConfig namespace defaults to "default".
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub namespace: Option<String>,
    /// Ports is a set of port numbers, which can be used for filtering in case of underlying
    /// is exposing multiple port numbers.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub number: Option<Vec<String>>,
}

/// NodeSelector is a label selector that determines to which nodes
/// this configuration applies.
/// If nil, then this config applies to all nodes.
#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumClusterwideEnvoyConfigNodeSelector {
    /// 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<CiliumClusterwideEnvoyConfigNodeSelectorMatchExpressions>>,
    /// 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 CiliumClusterwideEnvoyConfigNodeSelectorMatchExpressions {
    /// 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: CiliumClusterwideEnvoyConfigNodeSelectorMatchExpressionsOperator,
    /// 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 CiliumClusterwideEnvoyConfigNodeSelectorMatchExpressionsOperator {
    In,
    NotIn,
    Exists,
    DoesNotExist,
}

#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
pub struct CiliumClusterwideEnvoyConfigServices {
    /// Listener specifies the name of the Envoy listener the
    /// service traffic is redirected to. The listener must be
    /// specified in the Envoy 'resources' of the same
    /// CiliumEnvoyConfig.
    ///
    /// If omitted, the first listener specified in 'resources' is
    /// used.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub listener: Option<String>,
    /// Name is the name of a destination Kubernetes service that identifies traffic
    /// to be redirected.
    pub name: String,
    /// Namespace is the Kubernetes service namespace.
    /// In CiliumEnvoyConfig namespace this is overridden to the namespace of the CEC,
    /// In CiliumClusterwideEnvoyConfig namespace defaults to "default".
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub namespace: Option<String>,
    /// Ports is a set of service's frontend ports that should be redirected to the Envoy
    /// listener. By default all frontend ports of the service are redirected.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub ports: Option<Vec<i64>>,
}
