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
use std::error;

use log::{info, warn};
use outscale_api::{
    apis::nat_service_api::read_nat_services,
    models::{FiltersNatService, ReadNatServicesRequest, ReadNatServicesResponse},
};

use crate::{
    core::{nat_services::NatServices, Resource, Resources},
    VERSION,
};

use super::Input;

pub type NatServiceId = String;
const RESOURCE_NAME: &str = "NatServices";

impl Input {
    pub fn fetch_nat_services(&mut self) -> Result<(), Box<dyn error::Error>> {
        if self.skip_fetch(RESOURCE_NAME) {
            return Ok(());
        }
        let result: ReadNatServicesResponse = loop {
            let filters: FiltersNatService = match &self.filters {
                Some(filter) => FiltersNatService {
                    tag_keys: Some(filter.tag_keys.clone()),
                    tag_values: Some(filter.tag_values.clone()),
                    tags: Some(filter.tags.clone()),
                    ..Default::default()
                },
                None => FiltersNatService::new(),
            };
            let request = ReadNatServicesRequest {
                filters: Some(Box::new(filters)),
                ..Default::default()
            };
            let response = read_nat_services(&self.config, Some(request));
            if Input::is_throttled(&response) {
                self.random_wait();
                continue;
            }
            break response?;
        };
        let nat_services = match result.nat_services {
            None => {
                warn!("no nat_service available!");
                return Ok(());
            }
            Some(nat_services) => nat_services,
        };

        for nat_service in nat_services {
            let nat_service_id = nat_service
                .nat_service_id
                .clone()
                .unwrap_or_else(|| String::from(""));
            self.nat_services.insert(nat_service_id, nat_service);
        }
        info!("fetched {} nat_service", self.nat_services.len());
        Ok(())
    }

    pub fn fill_resource_nat_service(&self, resources: &mut Resources) {
        for (nat_service_id, nat_service) in &self.nat_services {
            let price_product_per_nat_service_per_hour =
                self.catalog_entry("TinaOS-FCU", "NatGatewayUsage", "CreateNatGateway");
            let Some(nat_service_id) = &nat_service.nat_service_id else {
                warn!("cannot get nat_service_id content for {}", nat_service_id);
                continue;
            };
            let core_nat_service = NatServices {
                osc_cost_version: Some(String::from(VERSION)),
                account_id: self.account_id(),
                read_date_rfc3339: self.fetch_date.map(|date| date.to_rfc3339()),
                region: self.region.clone(),
                resource_id: Some(nat_service_id.clone()),
                price_per_hour: None,
                price_per_month: None,
                price_product_per_nat_service_per_hour,
            };
            resources
                .resources
                .push(Resource::NatServices(core_nat_service));
        }
    }
}