1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use crate::Crd;
use serde::Serialize;

/// related to query parameters and uri
///
///
///
/// generate prefix for given crd
/// if crd group is core then /api is used otherwise /apis + group

pub fn prefix_uri(crd: &Crd, host: &str, namespace: &str, options: Option<&ListOptions>) -> String {
    let version = crd.version;
    let plural = crd.names.plural;
    let group = crd.group.as_ref();
    let api_prefix = match group {
        "core" => "api".to_owned(),
        _ => format!("apis/{}", group),
    };

    let query = if let Some(opt) = options {
        let mut query = "?".to_owned();
        let qs = serde_qs::to_string(opt).unwrap();
        query.push_str(&qs);
        query
    } else {
        "".to_owned()
    };

    format!(
        "{}/{}/{}/namespaces/{}/{}{}",
        host, api_prefix, version, namespace, plural, query
    )
}

/// goes as query parameter
#[derive(Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ListOptions {
    pub pretty: Option<bool>,
    #[serde(rename = "continue")]
    pub continu: Option<String>,
    pub field_selector: Option<String>,
    pub include_uninitialized: Option<bool>,
    pub label_selector: Option<String>,
    pub limit: Option<u32>,
    pub resource_version: Option<String>,
    pub timeout_seconds: Option<u32>,
    pub watch: Option<bool>,
}

#[derive(Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct DeleteOptions {
    pub api_version: Option<String>,
    pub grace_period_seconds: Option<u64>,
    pub kind: Option<String>,
    pub orphan_dependents: Option<String>,
    pub preconditions: Vec<Precondition>,
    pub propagation_policy: Option<String>,
}

#[derive(Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct Precondition {
    pub uid: String,
}

#[cfg(test)]
mod test {

    use super::prefix_uri;
    use super::ListOptions;
    use crate::metadata::DEFAULT_NS;
    use crate::Crd;
    use crate::CrdNames;

    const G1: Crd = Crd {
        group: "test.com",
        version: "v1",
        names: CrdNames {
            kind: "Item",
            plural: "items",
            singular: "item",
        },
    };

    const C1: Crd = Crd {
        group: "core",
        version: "v1",
        names: CrdNames {
            kind: "Item",
            plural: "items",
            singular: "item",
        },
    };

    #[test]
    fn test_api_prefix_group() {
        let uri = prefix_uri(&G1, "https://localhost", DEFAULT_NS, None);
        assert_eq!(
            uri,
            "https://localhost/apis/test.com/v1/namespaces/default/items"
        );
    }

    #[test]
    fn test_api_prefix_core() {
        let uri = prefix_uri(&C1, "https://localhost", DEFAULT_NS, None);
        assert_eq!(uri, "https://localhost/api/v1/namespaces/default/items");
    }

    #[test]
    fn test_api_prefix_watch() {
        let opt = ListOptions {
            watch: Some(true),
            ..Default::default()
        };
        let uri = prefix_uri(&C1, "https://localhost", DEFAULT_NS, Some(&opt));
        assert_eq!(
            uri,
            "https://localhost/api/v1/namespaces/default/items?watch=true"
        );
    }

    #[test]
    fn test_list_query() {
        let opt = ListOptions {
            pretty: Some(true),
            watch: Some(true),
            ..Default::default()
        };

        let qs = serde_qs::to_string(&opt).unwrap();
        assert_eq!(qs, "pretty=true&watch=true")
    }

}