feat: adding aws zone info

This commit is contained in:
Pierre Mavro
2021-12-21 00:04:56 +01:00
committed by Pierre Mavro
parent ca38733206
commit 8a9370cddd
42 changed files with 900 additions and 263 deletions

27
Cargo.lock generated
View File

@@ -2098,6 +2098,8 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"strum",
"strum_macros",
"sysinfo",
"tar",
"tempdir",
@@ -2786,6 +2788,12 @@ dependencies = [
"semver 0.9.0",
]
[[package]]
name = "rustversion"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]]
name = "ryu"
version = "1.0.5"
@@ -3114,6 +3122,25 @@ dependencies = [
"bytes 0.4.12",
]
[[package]]
name = "strum"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
[[package]]
name = "strum_macros"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
dependencies = [
"heck",
"proc-macro2 1.0.28",
"quote 1.0.9",
"rustversion",
"syn 1.0.74",
]
[[package]]
name = "subtle"
version = "2.4.1"

View File

@@ -28,6 +28,8 @@ uuid = { version = "0.8", features = ["v4", "serde"] }
url = "2.2.2"
function_name = "0.2.0"
thiserror = "1.0.30"
strum = "0.23"
strum_macros = "0.23"
# FIXME use https://crates.io/crates/blocking instead of runtime.rs

View File

@@ -12,7 +12,7 @@ locals {
resource "aws_subnet" "documentdb_zone_a" {
count = length(var.documentdb_subnets_zone_a)
availability_zone = data.aws_availability_zones.available.names[0]
availability_zone = var.aws_availability_zones[0]
cidr_block = var.documentdb_subnets_zone_a[count.index]
vpc_id = aws_vpc.eks.id
@@ -22,7 +22,7 @@ resource "aws_subnet" "documentdb_zone_a" {
resource "aws_subnet" "documentdb_zone_b" {
count = length(var.documentdb_subnets_zone_b)
availability_zone = data.aws_availability_zones.available.names[1]
availability_zone = var.aws_availability_zones[1]
cidr_block = var.documentdb_subnets_zone_b[count.index]
vpc_id = aws_vpc.eks.id
@@ -32,7 +32,7 @@ resource "aws_subnet" "documentdb_zone_b" {
resource "aws_subnet" "documentdb_zone_c" {
count = length(var.documentdb_subnets_zone_c)
availability_zone = data.aws_availability_zones.available.names[2]
availability_zone = var.aws_availability_zones[2]
cidr_block = var.documentdb_subnets_zone_c[count.index]
vpc_id = aws_vpc.eks.id

View File

@@ -19,8 +19,7 @@ resource "aws_eip" "eip_zone_c" {
resource "aws_subnet" "eks_zone_a_public" {
count = length(var.eks_subnets_zone_a_public)
// todo: provide a static list in order to avoid a possible outage if AWS add a new zone
availability_zone = data.aws_availability_zones.available.names[0]
availability_zone = var.aws_availability_zones[0]
cidr_block = var.eks_subnets_zone_a_public[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = true
@@ -31,7 +30,7 @@ resource "aws_subnet" "eks_zone_a_public" {
resource "aws_subnet" "eks_zone_b_public" {
count = length(var.eks_subnets_zone_b_public)
availability_zone = data.aws_availability_zones.available.names[1]
availability_zone = var.aws_availability_zones[1]
cidr_block = var.eks_subnets_zone_b_public[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = true
@@ -42,7 +41,7 @@ resource "aws_subnet" "eks_zone_b_public" {
resource "aws_subnet" "eks_zone_c_public" {
count = length(var.eks_subnets_zone_c_public)
availability_zone = data.aws_availability_zones.available.names[2]
availability_zone = var.aws_availability_zones[2]
cidr_block = var.eks_subnets_zone_c_public[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = true
@@ -123,7 +122,7 @@ resource "aws_route_table_association" "eks_cluster_zone_c_public" {
resource "aws_subnet" "eks_zone_a" {
count = length(var.eks_subnets_zone_a_private)
availability_zone = data.aws_availability_zones.available.names[0]
availability_zone = var.aws_availability_zones[0]
cidr_block = var.eks_subnets_zone_a_private[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = false
@@ -134,7 +133,7 @@ resource "aws_subnet" "eks_zone_a" {
resource "aws_subnet" "eks_zone_b" {
count = length(var.eks_subnets_zone_b_private)
availability_zone = data.aws_availability_zones.available.names[1]
availability_zone = var.aws_availability_zones[1]
cidr_block = var.eks_subnets_zone_b_private[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = false
@@ -145,7 +144,7 @@ resource "aws_subnet" "eks_zone_b" {
resource "aws_subnet" "eks_zone_c" {
count = length(var.eks_subnets_zone_c_private)
availability_zone = data.aws_availability_zones.available.names[2]
availability_zone = var.aws_availability_zones[2]
cidr_block = var.eks_subnets_zone_c_private[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = false

View File

@@ -3,7 +3,7 @@
resource "aws_subnet" "eks_zone_a" {
count = length(var.eks_subnets_zone_a_private)
availability_zone = data.aws_availability_zones.available.names[0]
availability_zone = var.aws_availability_zones[0]
cidr_block = var.eks_subnets_zone_a_private[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = true
@@ -14,7 +14,7 @@ resource "aws_subnet" "eks_zone_a" {
resource "aws_subnet" "eks_zone_b" {
count = length(var.eks_subnets_zone_b_private)
availability_zone = data.aws_availability_zones.available.names[1]
availability_zone = var.aws_availability_zones[1]
cidr_block = var.eks_subnets_zone_b_private[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = true
@@ -25,7 +25,7 @@ resource "aws_subnet" "eks_zone_b" {
resource "aws_subnet" "eks_zone_c" {
count = length(var.eks_subnets_zone_c_private)
availability_zone = data.aws_availability_zones.available.names[2]
availability_zone = var.aws_availability_zones[2]
cidr_block = var.eks_subnets_zone_c_private[count.index]
vpc_id = aws_vpc.eks.id
map_public_ip_on_launch = true

View File

@@ -12,7 +12,7 @@ locals {
resource "aws_subnet" "elasticache_zone_a" {
count = length(var.elasticache_subnets_zone_a)
availability_zone = data.aws_availability_zones.available.names[0]
availability_zone = var.aws_availability_zones[0]
cidr_block = var.elasticache_subnets_zone_a[count.index]
vpc_id = aws_vpc.eks.id
@@ -22,7 +22,7 @@ resource "aws_subnet" "elasticache_zone_a" {
resource "aws_subnet" "elasticache_zone_b" {
count = length(var.elasticache_subnets_zone_b)
availability_zone = data.aws_availability_zones.available.names[1]
availability_zone = var.aws_availability_zones[1]
cidr_block = var.elasticache_subnets_zone_b[count.index]
vpc_id = aws_vpc.eks.id
@@ -32,7 +32,7 @@ resource "aws_subnet" "elasticache_zone_b" {
resource "aws_subnet" "elasticache_zone_c" {
count = length(var.elasticache_subnets_zone_c)
availability_zone = data.aws_availability_zones.available.names[2]
availability_zone = var.aws_availability_zones[2]
cidr_block = var.elasticache_subnets_zone_c[count.index]
vpc_id = aws_vpc.eks.id

View File

@@ -12,7 +12,7 @@ locals {
resource "aws_subnet" "elasticsearch_zone_a" {
count = length(var.elasticsearch_subnets_zone_a)
availability_zone = data.aws_availability_zones.available.names[0]
availability_zone = var.aws_availability_zones[0]
cidr_block = var.elasticsearch_subnets_zone_a[count.index]
vpc_id = aws_vpc.eks.id
@@ -22,7 +22,7 @@ resource "aws_subnet" "elasticsearch_zone_a" {
resource "aws_subnet" "elasticsearch_zone_b" {
count = length(var.elasticsearch_subnets_zone_b)
availability_zone = data.aws_availability_zones.available.names[1]
availability_zone = var.aws_availability_zones[1]
cidr_block = var.elasticsearch_subnets_zone_b[count.index]
vpc_id = aws_vpc.eks.id
@@ -32,7 +32,7 @@ resource "aws_subnet" "elasticsearch_zone_b" {
resource "aws_subnet" "elasticsearch_zone_c" {
count = length(var.elasticsearch_subnets_zone_c)
availability_zone = data.aws_availability_zones.available.names[2]
availability_zone = var.aws_availability_zones[2]
cidr_block = var.elasticsearch_subnets_zone_c[count.index]
vpc_id = aws_vpc.eks.id

View File

@@ -26,7 +26,7 @@ locals {
resource "aws_subnet" "rds_zone_a" {
count = length(var.rds_subnets_zone_a)
availability_zone = data.aws_availability_zones.available.names[0]
availability_zone = var.aws_availability_zones[0]
cidr_block = var.rds_subnets_zone_a[count.index]
vpc_id = aws_vpc.eks.id
@@ -36,7 +36,7 @@ resource "aws_subnet" "rds_zone_a" {
resource "aws_subnet" "rds_zone_b" {
count = length(var.rds_subnets_zone_b)
availability_zone = data.aws_availability_zones.available.names[1]
availability_zone = var.aws_availability_zones[1]
cidr_block = var.rds_subnets_zone_b[count.index]
vpc_id = aws_vpc.eks.id
@@ -46,7 +46,7 @@ resource "aws_subnet" "rds_zone_b" {
resource "aws_subnet" "rds_zone_c" {
count = length(var.rds_subnets_zone_c)
availability_zone = data.aws_availability_zones.available.names[2]
availability_zone = var.aws_availability_zones[2]
cidr_block = var.rds_subnets_zone_c[count.index]
vpc_id = aws_vpc.eks.id

View File

@@ -44,6 +44,12 @@ variable "test_cluster" {
# AWS specific
variable "aws_availability_zones" {
description = "AWS availability zones"
default = {{ aws_availability_zones }}
type = list(string)
}
variable "vpc_cidr_block" {
description = "VPC CIDR block"
default = "{{ vpc_cidr_block }}"

View File

@@ -6,13 +6,13 @@ use std::str::FromStr;
use retry::delay::{Fibonacci, Fixed};
use retry::Error::Operation;
use retry::OperationResult;
use rusoto_core::Region;
use serde::{Deserialize, Serialize};
use tera::Context as TeraContext;
use crate::cloud_provider::aws::kubernetes::helm_charts::{aws_helm_charts, ChartsConfigPrerequisites};
use crate::cloud_provider::aws::kubernetes::node::AwsInstancesType;
use crate::cloud_provider::aws::kubernetes::roles::get_default_roles_to_create;
use crate::cloud_provider::aws::regions::{AwsRegion, AwsZones};
use crate::cloud_provider::environment::Environment;
use crate::cloud_provider::helm::deploy_charts_levels;
use crate::cloud_provider::kubernetes::{
@@ -40,7 +40,9 @@ use crate::error::{
use crate::errors::EngineError as NewEngineError;
use crate::events::{EnvironmentStep, Stage};
use crate::logger::Logger;
use crate::models::{Action, Context, Features, Listen, Listener, Listeners, ListenersHelper, ToHelmString};
use crate::models::{
Action, Context, Features, Listen, Listener, Listeners, ListenersHelper, ToHelmString, ToTerraformString,
};
use crate::object_storage::s3::S3;
use crate::object_storage::ObjectStorage;
use crate::string::terraform_list_format;
@@ -123,7 +125,8 @@ pub struct EKS<'a> {
long_id: uuid::Uuid,
name: String,
version: String,
region: Region,
region: AwsRegion,
zones: Vec<AwsZones>,
cloud_provider: &'a dyn CloudProvider,
dns_provider: &'a dyn DnsProvider,
s3: S3,
@@ -141,7 +144,8 @@ impl<'a> EKS<'a> {
long_id: uuid::Uuid,
name: &str,
version: &str,
region: &str,
region: AwsRegion,
zones: Vec<String>,
cloud_provider: &'a dyn CloudProvider,
dns_provider: &'a dyn DnsProvider,
options: Options,
@@ -150,6 +154,21 @@ impl<'a> EKS<'a> {
) -> Result<Self, EngineError> {
let template_directory = format!("{}/aws/bootstrap", context.lib_root_dir());
let mut aws_zones: Vec<AwsZones> = Vec::with_capacity(3);
for zone in zones {
match AwsZones::from_string(zone.to_string()) {
Ok(x) => aws_zones.push(x),
Err(e) => {
return Err(EngineError {
cause: EngineErrorCause::Internal,
scope: EngineErrorScope::Engine,
execution_id: id.to_string(),
message: Some(format!("Zone may not be found or supported: {:?}", e)),
})
}
};
}
for node_group in &nodes_groups {
if AwsInstancesType::from_str(node_group.instance_type.as_str()).is_err() {
return Err(EngineError::new(
@@ -180,7 +199,8 @@ impl<'a> EKS<'a> {
long_id,
name: name.to_string(),
version: version.to_string(),
region: Region::from_str(region).unwrap(),
region,
zones: aws_zones,
cloud_provider,
dns_provider,
s3,
@@ -243,6 +263,14 @@ impl<'a> EKS<'a> {
let format_ips =
|ips: &Vec<String>| -> Vec<String> { ips.iter().map(|ip| format!("\"{}\"", ip)).collect::<Vec<_>>() };
let format_zones = |zones: &Vec<AwsZones>| -> Vec<String> {
zones
.iter()
.map(|zone| zone.to_terraform_format_string())
.collect::<Vec<_>>()
};
let aws_zones = format_zones(&self.zones);
let mut eks_zone_a_subnet_blocks_private = format_ips(&self.options.eks_zone_a_subnet_blocks);
let mut eks_zone_b_subnet_blocks_private = format_ips(&self.options.eks_zone_b_subnet_blocks);
@@ -426,7 +454,7 @@ impl<'a> EKS<'a> {
self.cloud_provider().terraform_state_credentials().region.as_str(),
);
context.insert("aws_region", &self.region.name());
context.insert("aws_region", &self.region());
context.insert("aws_terraform_backend_bucket", "qovery-terrafom-tfstates");
context.insert("aws_terraform_backend_dynamodb_table", "qovery-terrafom-tfstates");
context.insert("vpc_cidr_block", &vpc_cidr_block);
@@ -434,6 +462,7 @@ impl<'a> EKS<'a> {
context.insert("s3_kubeconfig_bucket", &self.kubeconfig_bucket_name());
// AWS - EKS
context.insert("aws_availability_zones", &aws_zones);
context.insert("eks_cidr_subnet", &eks_cidr_subnet.clone());
context.insert("kubernetes_cluster_name", &self.name());
context.insert("kubernetes_cluster_id", self.id());
@@ -643,7 +672,7 @@ impl<'a> EKS<'a> {
infra_options: self.options.clone(),
cluster_id: self.id.clone(),
cluster_long_id: self.long_id,
region: self.region().to_string(),
region: self.region(),
cluster_name: self.cluster_name().to_string(),
cloud_provider: "aws".to_string(),
test_cluster: self.context.is_test_cluster(),
@@ -1211,14 +1240,18 @@ impl<'a> Kubernetes for EKS<'a> {
self.version.as_str()
}
fn region(&self) -> &str {
self.region.name()
fn region(&self) -> String {
self.region.to_aws_format()
}
fn zone(&self) -> &str {
""
}
fn aws_zones(&self) -> Option<Vec<AwsZones>> {
Some(self.zones.clone())
}
fn cloud_provider(&self) -> &dyn CloudProvider {
self.cloud_provider
}

View File

@@ -14,6 +14,7 @@ use crate::runtime::block_on;
pub mod application;
pub mod databases;
pub mod kubernetes;
pub mod regions;
pub mod router;
pub struct AWS {
@@ -24,6 +25,7 @@ pub struct AWS {
name: String,
pub access_key_id: String,
pub secret_access_key: String,
pub zones: Vec<String>,
terraform_state_credentials: TerraformStateCredentials,
listeners: Listeners,
}
@@ -37,6 +39,7 @@ impl AWS {
name: &str,
access_key_id: &str,
secret_access_key: &str,
zones: Vec<String>,
terraform_state_credentials: TerraformStateCredentials,
) -> Self {
AWS {
@@ -47,6 +50,7 @@ impl AWS {
name: name.to_string(),
access_key_id: access_key_id.to_string(),
secret_access_key: secret_access_key.to_string(),
zones,
terraform_state_credentials,
listeners: vec![],
}
@@ -121,6 +125,10 @@ impl CloudProvider for AWS {
}
}
fn zones(&self) -> &Vec<String> {
&self.zones
}
fn credentials_environment_variables(&self) -> Vec<(&str, &str)> {
vec![
(AWS_ACCESS_KEY_ID, self.access_key_id.as_str()),

View File

@@ -0,0 +1,454 @@
use crate::cloud_provider::aws::regions::AwsZones::*;
use crate::cloud_provider::aws::regions::RegionAndZoneErrors::*;
use crate::models::ToTerraformString;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
use strum_macros::EnumIter;
// Sync with Qovery Core team if you update this content
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, EnumIter)]
pub enum AwsZones {
// North Virginia
UsEast1A,
UsEast1B,
UsEast1C,
// Ohio
UsEast2A,
UsEast2B,
UsEast2C,
// Oregon
UsWest2A,
UsWest2B,
UsWest2C,
// Cap Town
AfSouth1A,
AfSouth1B,
AfSouth1C,
// Hong Kong
ApEast1A,
ApEast1B,
ApEast1C,
// Mumbai
ApSouth1A,
ApSouth1B,
ApSouth1C,
// Tokyo
ApNortheast1A,
ApNortheast1C,
ApNortheast1D,
// Seoul
ApNortheast2A,
ApNortheast2B,
ApNortheast2C,
// Osaka
ApNortheast3A,
ApNortheast3B,
ApNortheast3C,
// Singapore
ApSoutheast1A,
ApSoutheast1B,
ApSoutheast1C,
// Sydney
ApSoutheast2A,
ApSoutheast2B,
ApSoutheast2C,
// Toronto
CaCentral1A,
CaCentral1B,
CaCentral1D,
// Beijing
CnNorth1A,
CnNorth1B,
CnNorth1C,
// Ningxia
CnNorthwest1A,
CnNorthwest1B,
CnNorthwest1C,
// Frankfurt
EuCentral1A,
EuCentral1B,
EuCentral1C,
// Ireland
EuWest1A,
EuWest1B,
EuWest1C,
// London
EuWest2A,
EuWest2B,
EuWest2C,
// Paris
EuWest3A,
EuWest3B,
EuWest3C,
// Stockholm
EuNorth1A,
EuNorth1B,
EuNorth1C,
// Milan
EuSouth1A,
EuSouth1B,
EuSouth1C,
// Bahrain
MeSouth1A,
MeSouth1B,
MeSouth1C,
// Sao Paulo
SaEast1A,
SaEast1B,
SaEast1C,
}
impl ToTerraformString for AwsZones {
fn to_terraform_format_string(&self) -> String {
format!("\"{}\"", self.to_string())
}
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, EnumIter)]
// Sync with Qovery Core team if you update this content
pub enum AwsRegion {
UsEast1,
UsEast2,
UsWest2,
AfSouth1,
ApEast1,
ApSouth1,
ApNortheast1,
ApNortheast2,
ApNortheast3,
ApSoutheast1,
ApSoutheast2,
CaCentral1,
CnNorth1,
CnNorthwest1,
EuCentral1,
EuWest1,
EuWest2,
EuWest3,
EuNorth1,
EuSouth1,
MeSouth1,
SaEast1,
}
impl FromStr for AwsRegion {
type Err = ();
fn from_str(s: &str) -> Result<AwsRegion, ()> {
let v: &str = &s.to_lowercase();
match v {
"ap-east-1" | "apeast1" => Ok(AwsRegion::ApEast1),
"ap-northeast-1" | "apnortheast1" => Ok(AwsRegion::ApNortheast1),
"ap-northeast-2" | "apnortheast2" => Ok(AwsRegion::ApNortheast2),
"ap-northeast-3" | "apnortheast3" => Ok(AwsRegion::ApNortheast3),
"ap-south-1" | "apsouth1" => Ok(AwsRegion::ApSouth1),
"ap-southeast-1" | "apsoutheast1" => Ok(AwsRegion::ApSoutheast1),
"ap-southeast-2" | "apsoutheast2" => Ok(AwsRegion::ApSoutheast2),
"ca-central-1" | "cacentral1" => Ok(AwsRegion::CaCentral1),
"eu-central-1" | "eucentral1" => Ok(AwsRegion::EuCentral1),
"eu-west-1" | "euwest1" => Ok(AwsRegion::EuWest1),
"eu-west-2" | "euwest2" => Ok(AwsRegion::EuWest2),
"eu-west-3" | "euwest3" => Ok(AwsRegion::EuWest3),
"eu-north-1" | "eunorth1" => Ok(AwsRegion::EuNorth1),
"eu-south-1" | "eusouth1" => Ok(AwsRegion::EuSouth1),
"me-south-1" | "mesouth1" => Ok(AwsRegion::MeSouth1),
"sa-east-1" | "saeast1" => Ok(AwsRegion::SaEast1),
"us-east-1" | "useast1" => Ok(AwsRegion::UsEast1),
"us-east-2" | "useast2" => Ok(AwsRegion::UsEast2),
"us-west-2" | "uswest2" => Ok(AwsRegion::UsWest2),
"cn-north-1" | "cnnorth1" => Ok(AwsRegion::CnNorth1),
"cn-northwest-1" | "cnnorthwest1" => Ok(AwsRegion::CnNorthwest1),
"af-south-1" | "afsouth1" => Ok(AwsRegion::AfSouth1),
_ => Err(()),
}
}
}
impl AwsRegion {
pub fn new(&self) -> &AwsRegion {
self
}
pub fn to_string(&self) -> String {
let enum_name = format!("{}", self);
format!("{}", enum_name)
}
pub fn to_aws_format(&self) -> String {
match self {
AwsRegion::UsEast1 => "us-east-1",
AwsRegion::UsEast2 => "us-east-2",
AwsRegion::UsWest2 => "us-west-2",
AwsRegion::AfSouth1 => "af-south-1",
AwsRegion::ApEast1 => "ap-east-1",
AwsRegion::ApSouth1 => "ap-south-1",
AwsRegion::ApNortheast1 => "ap-northeast-1",
AwsRegion::ApNortheast2 => "ap-northeast-2",
AwsRegion::ApNortheast3 => "ap-northeast-3",
AwsRegion::ApSoutheast1 => "ap-southeast-1",
AwsRegion::ApSoutheast2 => "ap-southeast-2",
AwsRegion::CaCentral1 => "ca-central-1",
AwsRegion::CnNorth1 => "cn-north-1",
AwsRegion::CnNorthwest1 => "cn-northwest-1",
AwsRegion::EuCentral1 => "eu-central-1",
AwsRegion::EuWest1 => "eu-west-1",
AwsRegion::EuWest2 => "eu-west-2",
AwsRegion::EuWest3 => "eu-west-3",
AwsRegion::EuNorth1 => "eu-north-1",
AwsRegion::EuSouth1 => "eu-south-1",
AwsRegion::MeSouth1 => "me-south-1",
AwsRegion::SaEast1 => "sa-east-1",
}
.to_string()
}
pub fn get_zones_to_string(&self) -> Vec<String> {
let zones = self.get_zones();
let zones_to_string: Vec<String> = zones.into_iter().map(|x| x.to_string()).collect();
zones_to_string
}
pub fn get_zones(&self) -> Vec<AwsZones> {
// Warning, order matters
match self {
AwsRegion::UsEast1 => {
vec![UsEast1A, UsEast1B, UsEast1C]
}
AwsRegion::UsEast2 => {
vec![UsEast2A, UsEast2B, UsEast2C]
}
AwsRegion::UsWest2 => {
vec![UsWest2A, UsWest2B, UsWest2C]
}
AwsRegion::AfSouth1 => {
vec![AfSouth1A, AfSouth1B, AfSouth1C]
}
AwsRegion::ApEast1 => {
vec![ApEast1A, ApEast1B, ApEast1C]
}
AwsRegion::ApSouth1 => {
vec![ApSouth1A, ApSouth1B, ApSouth1C]
}
AwsRegion::ApNortheast1 => {
vec![ApNortheast1A, ApNortheast1C, ApNortheast1D]
}
AwsRegion::ApNortheast2 => {
vec![ApNortheast2A, ApNortheast2B, ApNortheast2C]
}
AwsRegion::ApNortheast3 => {
vec![ApNortheast3A, ApNortheast3B, ApNortheast3C]
}
AwsRegion::ApSoutheast1 => {
vec![ApSoutheast1A, ApSoutheast1B, ApSoutheast1C]
}
AwsRegion::ApSoutheast2 => {
vec![ApSoutheast2A, ApSoutheast2B, ApSoutheast2C]
}
AwsRegion::CaCentral1 => {
vec![CaCentral1A, CaCentral1B, CaCentral1D]
}
AwsRegion::CnNorth1 => {
vec![CnNorth1A, CnNorth1B, CnNorth1C]
}
AwsRegion::CnNorthwest1 => {
vec![CnNorthwest1A, CnNorthwest1B, CnNorthwest1C]
}
AwsRegion::EuCentral1 => {
vec![EuCentral1A, EuCentral1B, EuCentral1C]
}
AwsRegion::EuWest1 => {
vec![EuWest1A, EuWest1B, EuWest1C]
}
AwsRegion::EuWest2 => {
vec![EuWest2A, EuWest2B, EuWest2C]
}
AwsRegion::EuWest3 => {
vec![EuWest3A, EuWest3B, EuWest3C]
}
AwsRegion::EuNorth1 => {
vec![EuNorth1A, EuNorth1B, EuNorth1C]
}
AwsRegion::EuSouth1 => {
vec![EuSouth1A, EuSouth1B, EuSouth1C]
}
AwsRegion::MeSouth1 => {
vec![MeSouth1A, MeSouth1B, MeSouth1C]
}
AwsRegion::SaEast1 => {
vec![SaEast1A, SaEast1B, SaEast1C]
}
}
}
}
#[derive(Debug, PartialEq)]
pub enum RegionAndZoneErrors {
RegionNotFound,
RegionNotSupported,
ZoneNotFound,
ZoneNotSupported,
}
impl AwsZones {
pub fn to_string(&self) -> String {
match self {
UsEast1A => "us-east-1a",
UsEast1B => "us-east-1b",
UsEast1C => "us-east-1c",
UsEast2A => "us-east-2a",
UsEast2B => "us-east-2b",
UsEast2C => "us-east-2c",
UsWest2A => "us-west-2a",
UsWest2B => "us-west-2b",
UsWest2C => "us-west-2c",
AfSouth1A => "af-south-1a",
AfSouth1B => "af-south-1b",
AfSouth1C => "af-south-1c",
ApEast1A => "ap-east-1a",
ApEast1B => "ap-east-1b",
ApEast1C => "ap-east-1c",
ApSouth1A => "ap-south-1a",
ApSouth1B => "ap-south-1b",
ApSouth1C => "ap-south-1c",
ApNortheast1A => "ap-northeast-1a",
ApNortheast1C => "ap-northeast-1c",
ApNortheast1D => "ap-northeast-1d",
ApNortheast2A => "ap-northeast-2a",
ApNortheast2B => "ap-northeast-2b",
ApNortheast2C => "ap-northeast-2c",
ApNortheast3A => "ap-northeast-3a",
ApNortheast3B => "ap-northeast-3b",
ApNortheast3C => "ap-northeast-3c",
ApSoutheast1A => "ap-southeast-1a",
ApSoutheast1B => "ap-southeast-1b",
ApSoutheast1C => "ap-southeast-1c",
ApSoutheast2A => "ap-southeast-2a",
ApSoutheast2B => "ap-southeast-2b",
ApSoutheast2C => "ap-southeast-2c",
CaCentral1A => "ca-central-1a",
CaCentral1B => "ca-central-1b",
CaCentral1D => "ca-central-1d",
CnNorth1A => "cn-north-1a",
CnNorth1B => "cn-north-1b",
CnNorth1C => "cn-north-1c",
CnNorthwest1A => "cn-northwest-1a",
CnNorthwest1B => "cn-northwest-1b",
CnNorthwest1C => "cn-northwest-1c",
EuCentral1A => "eu-central-1a",
EuCentral1B => "eu-central-1b",
EuCentral1C => "eu-central-1c",
EuWest1A => "eu-west-1a",
EuWest1B => "eu-west-1b",
EuWest1C => "eu-west-1c",
EuWest2A => "eu-west-2a",
EuWest2B => "eu-west-2b",
EuWest2C => "eu-west-2c",
EuWest3A => "eu-west-3a",
EuWest3B => "eu-west-3b",
EuWest3C => "eu-west-3c",
EuNorth1A => "eu-north-1a",
EuNorth1B => "eu-north-1b",
EuNorth1C => "eu-north-1c",
EuSouth1A => "eu-south-1a",
EuSouth1B => "eu-south-1b",
EuSouth1C => "eu-south-1c",
MeSouth1A => "me-south-1a",
MeSouth1B => "me-south-1b",
MeSouth1C => "me-south-1c",
SaEast1A => "sa-east-1a",
SaEast1B => "sa-east-1b",
SaEast1C => "sa-east-1c",
}
.to_string()
}
pub fn from_string(zone: String) -> Result<AwsZones, RegionAndZoneErrors> {
// create tmp region from zone and get zone name (one letter)
let sanitized_zone_name = zone.to_lowercase().replace("-", "").replace("_", "");
let mut sanitized_region = sanitized_zone_name.clone();
sanitized_region.pop();
// ensure the region exists
let region = match AwsRegion::from_str(&sanitized_region) {
Ok(x) => x,
Err(_) => return Err(RegionNotFound),
};
if region.to_string().to_lowercase() != sanitized_region {
return Err(RegionNotFound);
};
// check if the zone is currently supported
for zone in region.get_zones() {
if zone.to_string().replace("-", "") == sanitized_zone_name {
return Ok(zone);
}
}
Err(ZoneNotSupported)
}
pub fn get_region(&self) -> String {
let zone = self.to_string();
zone[0..zone.len() - 1].to_string()
}
}
impl fmt::Display for AwsRegion {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl fmt::Display for AwsZones {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
#[cfg(test)]
mod tests {
use crate::cloud_provider::aws::regions::AwsZones::{EuWest3A, EuWest3B, EuWest3C};
use crate::cloud_provider::aws::regions::{AwsRegion, AwsZones, RegionAndZoneErrors};
use std::str::FromStr;
use strum::IntoEnumIterator;
#[test]
fn test_aws_zones() {
assert_eq!(AwsZones::EuWest3A.to_string(), "eu-west-3a".to_string());
assert_eq!(AwsZones::ApNortheast1D.to_string(), "ap-northeast-1d".to_string());
assert_eq!(AwsZones::from_string("eu-west-3a".to_string()), Ok(AwsZones::EuWest3A));
// ensure all zones are supported
for zone in AwsZones::iter() {
let sanitized_zone = format!("{:?}", zone);
let current_zone = AwsZones::from_string(sanitized_zone.to_lowercase());
assert_eq!(current_zone.unwrap(), zone);
}
assert_eq!(
AwsZones::from_string("eu-west-3x".to_string()),
Err(RegionAndZoneErrors::ZoneNotSupported)
);
}
#[test]
fn test_aws_get_region_from_zone() {
assert_eq!(AwsZones::EuWest3A.get_region(), "eu-west-3".to_string());
assert_eq!(AwsZones::ApNortheast1D.get_region(), "ap-northeast-1".to_string());
}
#[test]
fn test_aws_region() {
assert_eq!(AwsRegion::EuWest3.to_aws_format(), "eu-west-3");
assert_eq!(AwsRegion::EuWest3.to_string(), "EuWest3");
assert_eq!(AwsRegion::EuWest3.get_zones(), vec![EuWest3A, EuWest3B, EuWest3C]);
assert_eq!(AwsRegion::from_str("eu-west-3"), Ok(AwsRegion::EuWest3));
assert_eq!(AwsRegion::from_str("euwest3"), Ok(AwsRegion::EuWest3));
assert_eq!(AwsRegion::from_str("euwest"), Err(()));
for region in AwsRegion::iter() {
let aws_region = format!("{:?}", region);
assert!(AwsRegion::from_str(aws_region.as_str()).is_ok());
}
}
}

View File

@@ -417,7 +417,7 @@ pub enum StorageType {
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum Region {
pub enum DoRegion {
NewYorkCity1,
NewYorkCity2,
NewYorkCity3,
@@ -433,64 +433,64 @@ pub enum Region {
Bangalore,
}
impl Region {
impl DoRegion {
pub fn as_str(&self) -> &str {
match self {
Region::NewYorkCity1 => "nyc1",
Region::NewYorkCity2 => "nyc2",
Region::NewYorkCity3 => "nyc3",
Region::Amsterdam2 => "ams2",
Region::Amsterdam3 => "ams3",
Region::SanFrancisco1 => "sfo1",
Region::SanFrancisco2 => "sfo2",
Region::SanFrancisco3 => "sfo3",
Region::Singapore => "sgp1",
Region::London => "lon1",
Region::Frankfurt => "fra1",
Region::Toronto => "tor1",
Region::Bangalore => "blr1",
DoRegion::NewYorkCity1 => "nyc1",
DoRegion::NewYorkCity2 => "nyc2",
DoRegion::NewYorkCity3 => "nyc3",
DoRegion::Amsterdam2 => "ams2",
DoRegion::Amsterdam3 => "ams3",
DoRegion::SanFrancisco1 => "sfo1",
DoRegion::SanFrancisco2 => "sfo2",
DoRegion::SanFrancisco3 => "sfo3",
DoRegion::Singapore => "sgp1",
DoRegion::London => "lon1",
DoRegion::Frankfurt => "fra1",
DoRegion::Toronto => "tor1",
DoRegion::Bangalore => "blr1",
}
}
}
impl fmt::Display for Region {
impl fmt::Display for DoRegion {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Region::NewYorkCity1 => write!(f, "nyc1"),
Region::NewYorkCity2 => write!(f, "nyc2"),
Region::NewYorkCity3 => write!(f, "nyc3"),
Region::Amsterdam2 => write!(f, "ams2"),
Region::Amsterdam3 => write!(f, "ams3"),
Region::SanFrancisco1 => write!(f, "sfo1"),
Region::SanFrancisco2 => write!(f, "sfo2"),
Region::SanFrancisco3 => write!(f, "sfo3"),
Region::Singapore => write!(f, "sgp1"),
Region::London => write!(f, "lon1"),
Region::Frankfurt => write!(f, "fra1"),
Region::Toronto => write!(f, "tor1"),
Region::Bangalore => write!(f, "blr1"),
DoRegion::NewYorkCity1 => write!(f, "nyc1"),
DoRegion::NewYorkCity2 => write!(f, "nyc2"),
DoRegion::NewYorkCity3 => write!(f, "nyc3"),
DoRegion::Amsterdam2 => write!(f, "ams2"),
DoRegion::Amsterdam3 => write!(f, "ams3"),
DoRegion::SanFrancisco1 => write!(f, "sfo1"),
DoRegion::SanFrancisco2 => write!(f, "sfo2"),
DoRegion::SanFrancisco3 => write!(f, "sfo3"),
DoRegion::Singapore => write!(f, "sgp1"),
DoRegion::London => write!(f, "lon1"),
DoRegion::Frankfurt => write!(f, "fra1"),
DoRegion::Toronto => write!(f, "tor1"),
DoRegion::Bangalore => write!(f, "blr1"),
}
}
}
impl FromStr for Region {
impl FromStr for DoRegion {
type Err = ();
fn from_str(s: &str) -> Result<Region, ()> {
fn from_str(s: &str) -> Result<DoRegion, ()> {
match s {
"nyc1" => Ok(Region::NewYorkCity1),
"nyc2" => Ok(Region::NewYorkCity2),
"nyc3" => Ok(Region::NewYorkCity3),
"ams2" => Ok(Region::Amsterdam2),
"ams3" => Ok(Region::Amsterdam3),
"sfo1" => Ok(Region::SanFrancisco1),
"sfo2" => Ok(Region::SanFrancisco2),
"sfo3" => Ok(Region::SanFrancisco3),
"sgp1" => Ok(Region::Singapore),
"lon1" => Ok(Region::London),
"fra1" => Ok(Region::Frankfurt),
"tor1" => Ok(Region::Toronto),
"blr1" => Ok(Region::Bangalore),
"nyc1" => Ok(DoRegion::NewYorkCity1),
"nyc2" => Ok(DoRegion::NewYorkCity2),
"nyc3" => Ok(DoRegion::NewYorkCity3),
"ams2" => Ok(DoRegion::Amsterdam2),
"ams3" => Ok(DoRegion::Amsterdam3),
"sfo1" => Ok(DoRegion::SanFrancisco1),
"sfo2" => Ok(DoRegion::SanFrancisco2),
"sfo3" => Ok(DoRegion::SanFrancisco3),
"sgp1" => Ok(DoRegion::Singapore),
"lon1" => Ok(DoRegion::London),
"fra1" => Ok(DoRegion::Frankfurt),
"tor1" => Ok(DoRegion::Toronto),
"blr1" => Ok(DoRegion::Bangalore),
_ => Err(()),
}
}

View File

@@ -3,7 +3,8 @@ use std::env;
use serde::{Deserialize, Serialize};
use tera::Context as TeraContext;
use crate::cloud_provider::digitalocean::application::Region;
use crate::cloud_provider::aws::regions::AwsZones;
use crate::cloud_provider::digitalocean::application::DoRegion;
use crate::cloud_provider::digitalocean::do_api_common::{do_get_from_api, DoApiType};
use crate::cloud_provider::digitalocean::kubernetes::doks_api::{
get_do_latest_doks_slug_from_api, get_doks_info_from_name,
@@ -91,7 +92,7 @@ pub struct DOKS<'a> {
long_id: uuid::Uuid,
name: String,
version: String,
region: Region,
region: DoRegion,
cloud_provider: &'a dyn CloudProvider,
nodes_groups: Vec<NodeGroups>,
dns_provider: &'a dyn DnsProvider,
@@ -109,7 +110,7 @@ impl<'a> DOKS<'a> {
long_id: uuid::Uuid,
name: String,
version: String,
region: Region,
region: DoRegion,
cloud_provider: &'a dyn CloudProvider,
dns_provider: &'a dyn DnsProvider,
nodes_groups: Vec<NodeGroups>,
@@ -1151,14 +1152,18 @@ impl<'a> Kubernetes for DOKS<'a> {
self.version.as_str()
}
fn region(&self) -> &str {
self.region.as_str()
fn region(&self) -> String {
self.region.to_string()
}
fn zone(&self) -> &str {
""
}
fn aws_zones(&self) -> Option<Vec<AwsZones>> {
None
}
fn cloud_provider(&self) -> &dyn CloudProvider {
self.cloud_provider
}

View File

@@ -115,6 +115,10 @@ impl CloudProvider for DO {
}
}
fn zones(&self) -> &Vec<String> {
todo!()
}
fn credentials_environment_variables(&self) -> Vec<(&str, &str)> {
vec![(DIGITAL_OCEAN_TOKEN, self.token.as_str())]
}

View File

@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use crate::cloud_provider::digitalocean::application::Region;
use crate::cloud_provider::digitalocean::application::DoRegion;
use crate::cloud_provider::digitalocean::do_api_common::{do_get_from_api, DoApiType};
use crate::cloud_provider::digitalocean::models::vpc::{Vpc, Vpcs};
use crate::error::{SimpleError, SimpleErrorKind};
@@ -30,7 +30,7 @@ impl Default for VpcInitKind {
pub fn get_do_subnet_available_from_api(
token: &str,
desired_subnet: String,
region: Region,
region: DoRegion,
) -> Result<Option<Vpc>, SimpleError> {
// get subnets from the API
let vpcs = match do_get_from_api(token, DoApiType::Vpc, DoApiType::Vpc.api_url()) {
@@ -53,13 +53,13 @@ pub fn get_do_vpc_name_available_from_api(token: &str, desired_name: String) ->
Ok(get_do_vpc_from_name(desired_name, vpcs))
}
pub fn get_do_random_available_subnet_from_api(token: &str, region: Region) -> Result<String, SimpleError> {
pub fn get_do_random_available_subnet_from_api(token: &str, region: DoRegion) -> Result<String, SimpleError> {
let json_content = do_get_from_api(token, DoApiType::Vpc, DoApiType::Vpc.api_url())?;
let existing_vpcs = do_get_vpcs_from_api_output(&json_content)?;
get_random_available_subnet(existing_vpcs, region)
}
fn get_random_available_subnet(existing_vpcs: Vec<Vpc>, region: Region) -> Result<String, SimpleError> {
fn get_random_available_subnet(existing_vpcs: Vec<Vpc>, region: DoRegion) -> Result<String, SimpleError> {
let subnet_start = 0;
let subnet_end = 254;
@@ -100,7 +100,7 @@ fn get_do_vpc_from_name(desired_name: String, existing_vpcs: Vec<Vpc>) -> Option
fn get_do_vpc_from_subnet(
desired_subnet: String,
existing_vpcs: Vec<Vpc>,
region: Region,
region: DoRegion,
) -> Result<Option<Vpc>, SimpleError> {
let mut exists = None;
@@ -141,24 +141,24 @@ fn do_get_vpcs_from_api_output(json_content: &str) -> Result<Vec<Vpc>, SimpleErr
}
// https://docs.digitalocean.com/products/networking/vpc/
fn is_do_reserved_vpc_subnets(region: Region, subnet: &str) -> bool {
fn is_do_reserved_vpc_subnets(region: DoRegion, subnet: &str) -> bool {
// reserved DigitalOcean IPs
let mut do_all_regions_reserved_ips = vec!["10.244.0.0/16", "10.245.0.0/16", "10.246.0.0/24"];
let region_ip = match region {
Region::NewYorkCity1 => "10.10.0.0/16",
Region::NewYorkCity2 => "10.13.0.0/16",
Region::NewYorkCity3 => "10.17.0.0/16",
Region::Amsterdam2 => "10.14.0.0/16",
Region::Amsterdam3 => "10.18.0.0/16",
Region::SanFrancisco1 => "10.12.0.0/16",
Region::SanFrancisco2 => "10.46.0.0/16",
Region::SanFrancisco3 => "10.48.0.0/16",
Region::Singapore => "10.15.0.0/16",
Region::London => "10.16.0.0/16",
Region::Frankfurt => "10.19.0.0/16",
Region::Toronto => "10.20.0.0/16",
Region::Bangalore => "10.47.0.0/16",
DoRegion::NewYorkCity1 => "10.10.0.0/16",
DoRegion::NewYorkCity2 => "10.13.0.0/16",
DoRegion::NewYorkCity3 => "10.17.0.0/16",
DoRegion::Amsterdam2 => "10.14.0.0/16",
DoRegion::Amsterdam3 => "10.18.0.0/16",
DoRegion::SanFrancisco1 => "10.12.0.0/16",
DoRegion::SanFrancisco2 => "10.46.0.0/16",
DoRegion::SanFrancisco3 => "10.48.0.0/16",
DoRegion::Singapore => "10.15.0.0/16",
DoRegion::London => "10.16.0.0/16",
DoRegion::Frankfurt => "10.19.0.0/16",
DoRegion::Toronto => "10.20.0.0/16",
DoRegion::Bangalore => "10.47.0.0/16",
};
do_all_regions_reserved_ips.push(region_ip);
@@ -173,7 +173,7 @@ fn is_do_reserved_vpc_subnets(region: Region, subnet: &str) -> bool {
#[cfg(test)]
mod tests_do_vpcs {
use crate::cloud_provider::digitalocean::application::Region;
use crate::cloud_provider::digitalocean::application::DoRegion;
use crate::cloud_provider::digitalocean::network::vpc::{
do_get_vpcs_from_api_output, get_do_vpc_from_name, get_do_vpc_from_subnet, get_random_available_subnet,
is_do_reserved_vpc_subnets, VpcInitKind,
@@ -248,11 +248,11 @@ mod tests_do_vpcs {
#[test]
fn check_reserved_subnets() {
// if not reserved
assert_eq!(is_do_reserved_vpc_subnets(Region::Frankfurt, "192.168.0.0/24"), false);
assert!(!is_do_reserved_vpc_subnets(DoRegion::Frankfurt, "192.168.0.0/24"));
// if region reserved
assert!(is_do_reserved_vpc_subnets(Region::Frankfurt, "10.19.0.0/16"));
assert!(is_do_reserved_vpc_subnets(DoRegion::Frankfurt, "10.19.0.0/16"));
// if world wide reserved
assert!(is_do_reserved_vpc_subnets(Region::Frankfurt, "10.244.0.0/16"));
assert!(is_do_reserved_vpc_subnets(DoRegion::Frankfurt, "10.244.0.0/16"));
}
#[test]
@@ -275,24 +275,26 @@ mod tests_do_vpcs {
// available
assert!(
get_do_vpc_from_subnet("10.3.0.0/16".to_string(), vpcs.clone(), Region::Frankfurt)
get_do_vpc_from_subnet("10.3.0.0/16".to_string(), vpcs.clone(), DoRegion::Frankfurt)
.unwrap()
.is_none()
);
// already used
assert_eq!(
get_do_vpc_from_subnet("10.2.0.0/16".to_string(), vpcs.clone(), Region::Frankfurt)
get_do_vpc_from_subnet("10.2.0.0/16".to_string(), vpcs.clone(), DoRegion::Frankfurt)
.unwrap()
.unwrap()
.ip_range,
"10.2.0.0/16".to_string()
);
// DO reserved subnet in the same region
assert!(get_do_vpc_from_subnet("10.19.0.0/16".to_string(), vpcs.clone(), Region::Frankfurt).is_err());
assert!(get_do_vpc_from_subnet("10.19.0.0/16".to_string(), vpcs.clone(), DoRegion::Frankfurt).is_err());
// DO reserved subnet in another region
assert!(get_do_vpc_from_subnet("10.19.0.0/16".to_string(), vpcs, Region::London)
.unwrap()
.is_none());
assert!(
get_do_vpc_from_subnet("10.19.0.0/16".to_string(), vpcs, DoRegion::London)
.unwrap()
.is_none()
);
}
#[test]
@@ -309,7 +311,7 @@ mod tests_do_vpcs {
let json_content = do_get_vpc_json();
let existing_vpcs = do_get_vpcs_from_api_output(&json_content).unwrap();
assert!(get_random_available_subnet(existing_vpcs.clone(), Region::Frankfurt).is_ok());
assert!(get_random_available_subnet(existing_vpcs.clone(), DoRegion::Frankfurt).is_ok());
}
#[test]

View File

@@ -13,6 +13,7 @@ use retry::Error::Operation;
use retry::OperationResult;
use serde::{Deserialize, Serialize};
use crate::cloud_provider::aws::regions::AwsZones;
use crate::cloud_provider::environment::{Environment, EnvironmentResources};
use crate::cloud_provider::models::NodeGroups;
use crate::cloud_provider::service::CheckAction;
@@ -54,8 +55,9 @@ pub trait Kubernetes: Listen {
}
fn version(&self) -> &str;
fn region(&self) -> &str;
fn region(&self) -> String;
fn zone(&self) -> &str;
fn aws_zones(&self) -> Option<Vec<AwsZones>>;
fn cloud_provider(&self) -> &dyn CloudProvider;
fn dns_provider(&self) -> &dyn DnsProvider;
fn logger(&self) -> &dyn Logger;

View File

@@ -35,6 +35,7 @@ pub trait CloudProvider: Listen {
fn secret_access_key(&self) -> String;
fn token(&self) -> &str;
fn is_valid(&self) -> Result<(), EngineError>;
fn zones(&self) -> &Vec<String>;
/// environment variables containing credentials
fn credentials_environment_variables(&self) -> Vec<(&str, &str)>;
/// environment variables to inject to generate Terraform files from templates
@@ -72,6 +73,8 @@ impl Display for Kind {
}
}
pub trait CloudProviderZones {}
pub struct TerraformStateCredentials {
pub access_key_id: String,
pub secret_access_key: String,

View File

@@ -438,105 +438,106 @@ pub enum StorageType {
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum Region {
pub enum ScwRegion {
Paris,
Amsterdam,
Warsaw,
}
impl Region {
impl ScwRegion {
// TODO(benjaminch): improve / refactor this!
pub fn as_str(&self) -> &str {
match self {
Region::Paris => "fr-par",
Region::Amsterdam => "nl-ams",
Region::Warsaw => "pl-waw",
ScwRegion::Paris => "fr-par",
ScwRegion::Amsterdam => "nl-ams",
ScwRegion::Warsaw => "pl-waw",
}
}
}
impl fmt::Display for Region {
impl fmt::Display for ScwRegion {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Region::Paris => write!(f, "fr-par"),
Region::Amsterdam => write!(f, "nl-ams"),
Region::Warsaw => write!(f, "pl-waw"),
ScwRegion::Paris => write!(f, "fr-par"),
ScwRegion::Amsterdam => write!(f, "nl-ams"),
ScwRegion::Warsaw => write!(f, "pl-waw"),
}
}
}
impl FromStr for Region {
impl FromStr for ScwRegion {
type Err = ();
fn from_str(s: &str) -> Result<Region, ()> {
fn from_str(s: &str) -> Result<ScwRegion, ()> {
match s {
"fr-par" => Ok(Region::Paris),
"nl-ams" => Ok(Region::Amsterdam),
"pl-waw" => Ok(Region::Warsaw),
"fr-par" => Ok(ScwRegion::Paris),
"nl-ams" => Ok(ScwRegion::Amsterdam),
"pl-waw" => Ok(ScwRegion::Warsaw),
_ => Err(()),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum Zone {
pub enum ScwZone {
Paris1,
Paris2,
Amsterdam1,
Warsaw1,
}
impl Zone {
impl ScwZone {
// TODO(benjaminch): improve / refactor this!
pub fn as_str(&self) -> &str {
match self {
Zone::Paris1 => "fr-par-1",
Zone::Paris2 => "fr-par-2",
Zone::Amsterdam1 => "nl-ams-1",
Zone::Warsaw1 => "pl-waw-1",
ScwZone::Paris1 => "fr-par-1",
ScwZone::Paris2 => "fr-par-2",
ScwZone::Amsterdam1 => "nl-ams-1",
ScwZone::Warsaw1 => "pl-waw-1",
}
}
pub fn region(&self) -> Region {
pub fn region(&self) -> ScwRegion {
match self {
Zone::Paris1 => Region::Paris,
Zone::Paris2 => Region::Paris,
Zone::Amsterdam1 => Region::Amsterdam,
Zone::Warsaw1 => Region::Warsaw,
ScwZone::Paris1 => ScwRegion::Paris,
ScwZone::Paris2 => ScwRegion::Paris,
ScwZone::Amsterdam1 => ScwRegion::Amsterdam,
ScwZone::Warsaw1 => ScwRegion::Warsaw,
}
}
// TODO(benjaminch): improve / refactor this!
pub fn region_str(&self) -> &str {
pub fn region_str(&self) -> String {
match self {
Zone::Paris1 => "fr-par",
Zone::Paris2 => "fr-par",
Zone::Amsterdam1 => "nl-ams",
Zone::Warsaw1 => "pl-waw",
ScwZone::Paris1 => "fr-par",
ScwZone::Paris2 => "fr-par",
ScwZone::Amsterdam1 => "nl-ams",
ScwZone::Warsaw1 => "pl-waw",
}
.to_string()
}
}
impl fmt::Display for Zone {
impl fmt::Display for ScwZone {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Zone::Paris1 => write!(f, "fr-par-1"),
Zone::Paris2 => write!(f, "fr-par-2"),
Zone::Amsterdam1 => write!(f, "nl-ams-1"),
Zone::Warsaw1 => write!(f, "pl-waw-1"),
ScwZone::Paris1 => write!(f, "fr-par-1"),
ScwZone::Paris2 => write!(f, "fr-par-2"),
ScwZone::Amsterdam1 => write!(f, "nl-ams-1"),
ScwZone::Warsaw1 => write!(f, "pl-waw-1"),
}
}
}
impl FromStr for Zone {
impl FromStr for ScwZone {
type Err = ();
fn from_str(s: &str) -> Result<Zone, ()> {
fn from_str(s: &str) -> Result<ScwZone, ()> {
match s {
"fr-par-1" => Ok(Zone::Paris1),
"fr-par-2" => Ok(Zone::Paris2),
"nl-ams-1" => Ok(Zone::Amsterdam1),
"pl-waw-1" => Ok(Zone::Warsaw1),
"fr-par-1" => Ok(ScwZone::Paris1),
"fr-par-2" => Ok(ScwZone::Paris2),
"nl-ams-1" => Ok(ScwZone::Amsterdam1),
"pl-waw-1" => Ok(ScwZone::Warsaw1),
_ => Err(()),
}
}
@@ -544,44 +545,44 @@ impl FromStr for Zone {
#[cfg(test)]
mod tests {
use super::{Region, Zone};
use super::{ScwRegion, ScwZone};
use std::str::FromStr;
#[test]
fn test_region_to_str() {
assert_eq!("fr-par", Region::Paris.as_str());
assert_eq!("nl-ams", Region::Amsterdam.as_str());
assert_eq!("pl-waw", Region::Warsaw.as_str());
assert_eq!("fr-par", ScwRegion::Paris.as_str());
assert_eq!("nl-ams", ScwRegion::Amsterdam.as_str());
assert_eq!("pl-waw", ScwRegion::Warsaw.as_str());
}
#[test]
fn test_region_from_str() {
assert_eq!(Region::from_str("fr-par"), Ok(Region::Paris));
assert_eq!(Region::from_str("nl-ams"), Ok(Region::Amsterdam));
assert_eq!(Region::from_str("pl-waw"), Ok(Region::Warsaw));
assert_eq!(ScwRegion::from_str("fr-par"), Ok(ScwRegion::Paris));
assert_eq!(ScwRegion::from_str("nl-ams"), Ok(ScwRegion::Amsterdam));
assert_eq!(ScwRegion::from_str("pl-waw"), Ok(ScwRegion::Warsaw));
}
#[test]
fn test_zone_to_str() {
assert_eq!("fr-par-1", Zone::Paris1.as_str());
assert_eq!("fr-par-2", Zone::Paris2.as_str());
assert_eq!("nl-ams-1", Zone::Amsterdam1.as_str());
assert_eq!("pl-waw-1", Zone::Warsaw1.as_str());
assert_eq!("fr-par-1", ScwZone::Paris1.as_str());
assert_eq!("fr-par-2", ScwZone::Paris2.as_str());
assert_eq!("nl-ams-1", ScwZone::Amsterdam1.as_str());
assert_eq!("pl-waw-1", ScwZone::Warsaw1.as_str());
}
#[test]
fn test_zone_from_str() {
assert_eq!(Zone::from_str("fr-par-1"), Ok(Zone::Paris1));
assert_eq!(Zone::from_str("fr-par-2"), Ok(Zone::Paris2));
assert_eq!(Zone::from_str("nl-ams-1"), Ok(Zone::Amsterdam1));
assert_eq!(Zone::from_str("pl-waw-1"), Ok(Zone::Warsaw1));
assert_eq!(ScwZone::from_str("fr-par-1"), Ok(ScwZone::Paris1));
assert_eq!(ScwZone::from_str("fr-par-2"), Ok(ScwZone::Paris2));
assert_eq!(ScwZone::from_str("nl-ams-1"), Ok(ScwZone::Amsterdam1));
assert_eq!(ScwZone::from_str("pl-waw-1"), Ok(ScwZone::Warsaw1));
}
#[test]
fn test_zone_region() {
assert_eq!(Zone::Paris1.region(), Region::Paris);
assert_eq!(Zone::Paris2.region(), Region::Paris);
assert_eq!(Zone::Amsterdam1.region(), Region::Amsterdam);
assert_eq!(Zone::Warsaw1.region(), Region::Warsaw);
assert_eq!(ScwZone::Paris1.region(), ScwRegion::Paris);
assert_eq!(ScwZone::Paris2.region(), ScwRegion::Paris);
assert_eq!(ScwZone::Amsterdam1.region(), ScwRegion::Amsterdam);
assert_eq!(ScwZone::Warsaw1.region(), ScwRegion::Warsaw);
}
}

View File

@@ -4,7 +4,7 @@ use crate::cloud_provider::helm::{
ShellAgentContext,
};
use crate::cloud_provider::qovery::{get_qovery_app_version, EngineLocation, QoveryAgent, QoveryAppName, QoveryEngine};
use crate::cloud_provider::scaleway::application::{Region, Zone};
use crate::cloud_provider::scaleway::application::{ScwRegion, ScwZone};
use crate::cloud_provider::scaleway::kubernetes::KapsuleOptions;
use crate::error::{SimpleError, SimpleErrorKind};
use semver::Version;
@@ -23,8 +23,8 @@ pub struct ChartsConfigPrerequisites {
pub organization_long_id: uuid::Uuid,
pub cluster_id: String,
pub cluster_long_id: uuid::Uuid,
pub zone: Zone,
pub region: Region,
pub zone: ScwZone,
pub region: ScwRegion,
pub cluster_name: String,
pub cloud_provider: String,
pub test_cluster: bool,
@@ -53,7 +53,7 @@ impl ChartsConfigPrerequisites {
organization_long_id: uuid::Uuid,
cluster_id: String,
cluster_long_id: uuid::Uuid,
zone: Zone,
zone: ScwZone,
cluster_name: String,
cloud_provider: String,
test_cluster: bool,

View File

@@ -1,6 +1,7 @@
mod helm_charts;
pub mod node;
use crate::cloud_provider::aws::regions::AwsZones;
use crate::cloud_provider::environment::Environment;
use crate::cloud_provider::helm::deploy_charts_levels;
use crate::cloud_provider::kubernetes::{
@@ -9,7 +10,7 @@ use crate::cloud_provider::kubernetes::{
};
use crate::cloud_provider::models::{NodeGroups, NodeGroupsFormat};
use crate::cloud_provider::qovery::EngineLocation;
use crate::cloud_provider::scaleway::application::Zone;
use crate::cloud_provider::scaleway::application::ScwZone;
use crate::cloud_provider::scaleway::kubernetes::helm_charts::{scw_helm_charts, ChartsConfigPrerequisites};
use crate::cloud_provider::scaleway::kubernetes::node::ScwInstancesType;
use crate::cloud_provider::utilities::print_action;
@@ -116,7 +117,7 @@ pub struct Kapsule<'a> {
long_id: uuid::Uuid,
name: String,
version: String,
zone: Zone,
zone: ScwZone,
cloud_provider: &'a dyn CloudProvider,
dns_provider: &'a dyn DnsProvider,
object_storage: ScalewayOS,
@@ -134,7 +135,7 @@ impl<'a> Kapsule<'a> {
long_id: uuid::Uuid,
name: String,
version: String,
zone: Zone,
zone: ScwZone,
cloud_provider: &'a dyn CloudProvider,
dns_provider: &'a dyn DnsProvider,
nodes_groups: Vec<NodeGroups>,
@@ -1105,7 +1106,7 @@ impl<'a> Kubernetes for Kapsule<'a> {
self.version.as_str()
}
fn region(&self) -> &str {
fn region(&self) -> String {
self.zone.region_str()
}
@@ -1113,6 +1114,10 @@ impl<'a> Kubernetes for Kapsule<'a> {
self.zone.as_str()
}
fn aws_zones(&self) -> Option<Vec<AwsZones>> {
None
}
fn cloud_provider(&self) -> &dyn CloudProvider {
self.cloud_provider
}

View File

@@ -92,6 +92,10 @@ impl CloudProvider for Scaleway {
Ok(())
}
fn zones(&self) -> &Vec<String> {
todo!()
}
fn credentials_environment_variables(&self) -> Vec<(&str, &str)> {
vec![
(SCALEWAY_ACCESS_KEY, self.access_key.as_str()),

View File

@@ -322,7 +322,7 @@ pub fn default_tera_context(
context.insert("project_id", environment.project_id.as_str());
context.insert("organization_id", environment.organization_id.as_str());
context.insert("environment_id", environment.id.as_str());
context.insert("region", kubernetes.region());
context.insert("region", kubernetes.region().as_str());
context.insert("zone", kubernetes.zone());
context.insert("name", service.name());
context.insert("sanitized_name", &service.sanitized_name());

View File

@@ -778,6 +778,7 @@ where
let mut args_string: Vec<String> = vec![
"diff",
"upgrade",
"--no-color",
"--allow-unreleased",
"--kubeconfig",
kubernetes_config.as_ref().to_str().unwrap(),

View File

@@ -1,6 +1,6 @@
extern crate scaleway_api_rs;
use crate::cloud_provider::scaleway::application::Zone;
use crate::cloud_provider::scaleway::application::ScwZone;
use crate::build_platform::Image;
use crate::container_registry::docker::{docker_login, docker_manifest_inspect, docker_tag_and_push_image};
@@ -22,7 +22,7 @@ pub struct ScalewayCR {
default_project_id: String,
login: String,
secret_token: String,
zone: Zone,
zone: ScwZone,
listeners: Listeners,
}
@@ -33,7 +33,7 @@ impl ScalewayCR {
name: &str,
secret_token: &str,
default_project_id: &str,
zone: Zone,
zone: ScwZone,
) -> ScalewayCR {
ScalewayCR {
context,

View File

@@ -79,7 +79,7 @@ impl Logger for StdIoLogger {
#[cfg(test)]
mod tests {
use super::*;
use crate::cloud_provider::scaleway::application::Region;
use crate::cloud_provider::scaleway::application::ScwRegion;
use crate::cloud_provider::Kind;
use crate::errors::EngineError;
use crate::events::{EnvironmentStep, EventDetails, EventMessage, InfrastructureStep, Stage, Transmitter};
@@ -120,7 +120,7 @@ mod tests {
orga_id.clone(),
cluster_id.clone(),
execution_id.clone(),
Some(Region::Paris.as_str().to_string()),
Some(ScwRegion::Paris.as_str().to_string()),
Stage::Infrastructure(InfrastructureStep::Create),
Transmitter::Kubernetes(cluster_id.to_string(), cluster_name.to_string()),
),
@@ -141,7 +141,7 @@ mod tests {
orga_id.clone(),
cluster_id.clone(),
execution_id.clone(),
Some(Region::Paris.as_str().to_string()),
Some(ScwRegion::Paris.as_str().to_string()),
Stage::Infrastructure(InfrastructureStep::Create),
Transmitter::Kubernetes(cluster_id.to_string(), cluster_name.to_string()),
),
@@ -157,7 +157,7 @@ mod tests {
orga_id.clone(),
cluster_id.clone(),
execution_id.clone(),
Some(Region::Paris.as_str().to_string()),
Some(ScwRegion::Paris.as_str().to_string()),
Stage::Environment(EnvironmentStep::Pause),
Transmitter::Application(app_id.to_string(), app_name.to_string()),
),
@@ -173,7 +173,7 @@ mod tests {
orga_id.clone(),
cluster_id.clone(),
execution_id.clone(),
Some(Region::Paris.as_str().to_string()),
Some(ScwRegion::Paris.as_str().to_string()),
Stage::Environment(EnvironmentStep::Delete),
Transmitter::Application(app_id.to_string(), app_name.to_string()),
),

View File

@@ -2,7 +2,7 @@ use chrono::{DateTime, Utc};
use std::fs::File;
use std::path::Path;
use crate::cloud_provider::scaleway::application::Zone;
use crate::cloud_provider::scaleway::application::ScwZone;
use crate::error::{EngineError, EngineErrorCause};
use crate::models::{Context, StringPath};
use crate::object_storage::{Kind, ObjectStorage};
@@ -29,7 +29,7 @@ pub struct ScalewayOS {
name: String,
access_key: String,
secret_token: String,
zone: Zone,
zone: ScwZone,
bucket_delete_strategy: BucketDeleteStrategy,
bucket_versioning_activated: bool,
bucket_ttl_in_seconds: Option<u32>,
@@ -42,7 +42,7 @@ impl ScalewayOS {
name: String,
access_key: String,
secret_token: String,
zone: Zone,
zone: ScwZone,
bucket_delete_strategy: BucketDeleteStrategy,
bucket_versioning_activated: bool,
bucket_ttl_in_seconds: Option<u32>,

View File

@@ -11,7 +11,7 @@ use rusoto_s3::{
};
use tokio::io;
use crate::cloud_provider::digitalocean::application::Region as DoRegion;
use crate::cloud_provider::digitalocean::application::DoRegion;
use crate::error::{EngineError, EngineErrorCause};
use crate::models::{Context, StringPath};
use crate::object_storage::{Kind, ObjectStorage};

View File

@@ -19,9 +19,9 @@ checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "aho-corasick"
version = "0.7.15"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
@@ -2130,6 +2130,8 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"strum",
"strum_macros",
"sysinfo",
"tar",
"tera",
@@ -2470,14 +2472,13 @@ dependencies = [
[[package]]
name = "regex"
version = "1.4.2"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
@@ -2492,9 +2493,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.21"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remove_dir_all"
@@ -2816,6 +2817,12 @@ dependencies = [
"semver 0.9.0",
]
[[package]]
name = "rustversion"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]]
name = "ryu"
version = "1.0.5"
@@ -3151,6 +3158,25 @@ dependencies = [
"bytes 0.4.12",
]
[[package]]
name = "strum"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
[[package]]
name = "strum_macros"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
dependencies = [
"heck",
"proc-macro2 1.0.27",
"quote 1.0.8",
"rustversion",
"syn 1.0.73",
]
[[package]]
name = "subtle"
version = "2.4.0"

View File

@@ -1,7 +1,9 @@
extern crate serde;
extern crate serde_derive;
use const_format::formatcp;
use qovery_engine::cloud_provider::aws::kubernetes::{Options, VpcQoveryNetworkMode};
use qovery_engine::cloud_provider::aws::regions::AwsRegion;
use qovery_engine::cloud_provider::aws::AWS;
use qovery_engine::cloud_provider::models::NodeGroups;
use qovery_engine::cloud_provider::qovery::EngineLocation::ClientSide;
@@ -11,6 +13,7 @@ use qovery_engine::container_registry::ecr::ECR;
use qovery_engine::engine::Engine;
use qovery_engine::logger::Logger;
use qovery_engine::models::Context;
use std::str::FromStr;
use tracing::error;
use crate::cloudflare::dns_provider_cloudflare;
@@ -81,6 +84,8 @@ impl Cluster<AWS, Options> for AWS {
fn cloud_provider(context: &Context) -> Box<AWS> {
let secrets = FuncTestsSecrets::new();
let aws_region =
AwsRegion::from_str(secrets.AWS_DEFAULT_REGION.unwrap().as_str()).expect("AWS region not supported");
Box::new(AWS::new(
context.clone(),
"u8nb94c7fwxzr2jt",
@@ -99,6 +104,7 @@ impl Cluster<AWS, Options> for AWS {
.AWS_SECRET_ACCESS_KEY
.expect("AWS_SECRET_ACCESS_KEY is not set")
.as_str(),
aws_region.get_zones_to_string(),
TerraformStateCredentials {
access_key_id: secrets
.TERRAFORM_AWS_ACCESS_KEY_ID

View File

@@ -21,13 +21,14 @@ use crate::utilities::{
};
use base64;
use qovery_engine::cloud_provider::aws::kubernetes::{VpcQoveryNetworkMode, EKS};
use qovery_engine::cloud_provider::aws::regions::{AwsRegion, AwsZones};
use qovery_engine::cloud_provider::aws::AWS;
use qovery_engine::cloud_provider::digitalocean::application::Region;
use qovery_engine::cloud_provider::digitalocean::application::DoRegion;
use qovery_engine::cloud_provider::digitalocean::kubernetes::DOKS;
use qovery_engine::cloud_provider::digitalocean::DO;
use qovery_engine::cloud_provider::kubernetes::Kubernetes;
use qovery_engine::cloud_provider::models::NodeGroups;
use qovery_engine::cloud_provider::scaleway::application::Zone;
use qovery_engine::cloud_provider::scaleway::application::ScwZone;
use qovery_engine::cloud_provider::scaleway::kubernetes::Kapsule;
use qovery_engine::cloud_provider::scaleway::Scaleway;
use qovery_engine::cloud_provider::{CloudProvider, Kind};
@@ -1165,6 +1166,12 @@ pub fn get_environment_test_kubernetes<'a>(
match provider_kind {
Kind::Aws => {
let region = secrets
.AWS_DEFAULT_REGION
.as_ref()
.expect("AWS_DEFAULT_REGION is not set")
.as_str();
let aws_region = AwsRegion::from_str(region).expect("wrong AWS region name, please ensure it's correct");
k = Box::new(
EKS::new(
context.clone(),
@@ -1172,11 +1179,8 @@ pub fn get_environment_test_kubernetes<'a>(
uuid::Uuid::new_v4(),
format!("qovery-{}", context.cluster_id()).as_str(),
AWS_KUBERNETES_VERSION,
secrets
.AWS_DEFAULT_REGION
.as_ref()
.expect("AWS_DEFAULT_REGION is not set")
.as_str(),
aws_region.clone(),
aws_region.get_zones_to_string(),
cloud_provider,
dns_provider,
AWS::kubernetes_cluster_options(secrets.clone(), None),
@@ -1194,7 +1198,7 @@ pub fn get_environment_test_kubernetes<'a>(
uuid::Uuid::new_v4(),
format!("qovery-{}", context.cluster_id()),
DO_KUBERNETES_VERSION.to_string(),
Region::from_str(
DoRegion::from_str(
secrets
.clone()
.DIGITAL_OCEAN_DEFAULT_REGION
@@ -1219,7 +1223,7 @@ pub fn get_environment_test_kubernetes<'a>(
uuid::Uuid::new_v4(),
format!("qovery-{}", context.cluster_id()),
SCW_KUBERNETES_VERSION.to_string(),
Zone::from_str(
ScwZone::from_str(
secrets
.clone()
.SCALEWAY_DEFAULT_REGION
@@ -1249,6 +1253,7 @@ pub fn get_cluster_test_kubernetes<'a>(
cluster_name: String,
boot_version: String,
localisation: &str,
aws_zones: Option<Vec<AwsZones>>,
cloud_provider: &'a dyn CloudProvider,
dns_provider: &'a dyn DnsProvider,
vpc_network_mode: Option<VpcQoveryNetworkMode>,
@@ -1259,7 +1264,9 @@ pub fn get_cluster_test_kubernetes<'a>(
match provider_kind {
Kind::Aws => {
let mut options = AWS::kubernetes_cluster_options(secrets, None);
let aws_region = AwsRegion::from_str(localisation).expect("expected correct AWS region");
options.vpc_qovery_network_mode = vpc_network_mode.unwrap();
let aws_zones = aws_zones.unwrap().into_iter().map(|zone| zone.to_string()).collect();
k = Box::new(
EKS::new(
context.clone(),
@@ -1267,7 +1274,8 @@ pub fn get_cluster_test_kubernetes<'a>(
uuid::Uuid::new_v4(),
cluster_name.as_str(),
boot_version.as_str(),
localisation.clone(),
aws_region.clone(),
aws_zones,
cloud_provider,
dns_provider,
options,
@@ -1285,7 +1293,7 @@ pub fn get_cluster_test_kubernetes<'a>(
uuid::Uuid::new_v4(),
cluster_name.clone(),
boot_version,
Region::from_str(localisation.clone()).expect("Unknown region set for DOKS"),
DoRegion::from_str(localisation.clone()).expect("Unknown region set for DOKS"),
cloud_provider,
dns_provider,
DO::kubernetes_nodes(),
@@ -1303,7 +1311,7 @@ pub fn get_cluster_test_kubernetes<'a>(
uuid::Uuid::new_v4(),
cluster_name.clone(),
boot_version,
Zone::from_str(localisation.clone()).expect("Unknown zone set for Kapsule"),
ScwZone::from_str(localisation.clone()).expect("Unknown zone set for Kapsule"),
cloud_provider,
dns_provider,
Scaleway::kubernetes_nodes(),
@@ -1324,6 +1332,7 @@ pub fn cluster_test(
context: Context,
logger: Box<dyn Logger>,
localisation: &str,
aws_zones: Option<Vec<AwsZones>>,
secrets: FuncTestsSecrets,
test_type: ClusterTestType,
major_boot_version: u8,
@@ -1357,6 +1366,14 @@ pub fn cluster_test(
Kind::Do => DO::cloud_provider(&context),
Kind::Scw => Scaleway::cloud_provider(&context),
};
let mut aws_zones_string: Vec<String> = Vec::with_capacity(3);
if aws_zones.is_some() {
for zone in aws_zones.clone().unwrap() {
aws_zones_string.push(zone.to_string())
}
};
let kubernetes = get_cluster_test_kubernetes(
provider_kind.clone(),
secrets.clone(),
@@ -1365,6 +1382,7 @@ pub fn cluster_test(
cluster_name.clone(),
boot_version.clone(),
localisation.clone(),
aws_zones.clone(),
cp.as_ref(),
&dns_provider,
vpc_network_mode.clone(),
@@ -1432,6 +1450,7 @@ pub fn cluster_test(
cluster_name.clone(),
upgrade_to_version.clone(),
localisation.clone(),
aws_zones,
cp.as_ref(),
&dns_provider,
vpc_network_mode.clone(),

View File

@@ -13,7 +13,7 @@ use qovery_engine::models::{Context, Environment};
use crate::cloudflare::dns_provider_cloudflare;
use crate::common::{Cluster, ClusterDomain};
use crate::utilities::{build_platform_local_docker, FuncTestsSecrets};
use qovery_engine::cloud_provider::digitalocean::application::Region;
use qovery_engine::cloud_provider::digitalocean::application::DoRegion;
use qovery_engine::cloud_provider::qovery::EngineLocation;
use qovery_engine::logger::Logger;
@@ -22,7 +22,7 @@ pub const DO_KUBERNETES_MINOR_VERSION: u8 = 19;
pub const DO_KUBERNETES_VERSION: &'static str =
formatcp!("{}.{}", DO_KUBERNETES_MAJOR_VERSION, DO_KUBERNETES_MINOR_VERSION);
pub const DOCR_ID: &str = "registry-the-one-and-unique";
pub const DO_TEST_REGION: Region = Region::Amsterdam3;
pub const DO_TEST_REGION: DoRegion = DoRegion::Amsterdam3;
pub const DO_MANAGED_DATABASE_INSTANCE_TYPE: &str = "";
pub const DO_MANAGED_DATABASE_DISK_TYPE: &str = "";
pub const DO_SELF_HOSTED_DATABASE_INSTANCE_TYPE: &str = "";
@@ -131,7 +131,7 @@ pub fn clean_environments(
context: &Context,
environments: Vec<Environment>,
secrets: FuncTestsSecrets,
_region: Region,
_region: DoRegion,
) -> Result<(), EngineError> {
let do_cr = DOCR::new(
context.clone(),

View File

@@ -1,6 +1,6 @@
use const_format::formatcp;
use qovery_engine::build_platform::Image;
use qovery_engine::cloud_provider::scaleway::application::Zone;
use qovery_engine::cloud_provider::scaleway::application::ScwZone;
use qovery_engine::cloud_provider::scaleway::kubernetes::KapsuleOptions;
use qovery_engine::cloud_provider::scaleway::Scaleway;
use qovery_engine::cloud_provider::TerraformStateCredentials;
@@ -19,7 +19,7 @@ use qovery_engine::cloud_provider::qovery::EngineLocation;
use qovery_engine::logger::Logger;
use tracing::error;
pub const SCW_TEST_ZONE: Zone = Zone::Paris2;
pub const SCW_TEST_ZONE: ScwZone = ScwZone::Paris2;
pub const SCW_KUBERNETES_MAJOR_VERSION: u8 = 1;
pub const SCW_KUBERNETES_MINOR_VERSION: u8 = 19;
pub const SCW_KUBERNETES_VERSION: &'static str =
@@ -165,7 +165,7 @@ impl Cluster<Scaleway, KapsuleOptions> for Scaleway {
}
}
pub fn scw_object_storage(context: Context, region: Zone) -> ScalewayOS {
pub fn scw_object_storage(context: Context, region: ScwZone) -> ScalewayOS {
let secrets = FuncTestsSecrets::new();
let random_id = generate_id();
@@ -190,7 +190,7 @@ pub fn clean_environments(
context: &Context,
environments: Vec<Environment>,
secrets: FuncTestsSecrets,
zone: Zone,
zone: ScwZone,
) -> Result<(), EngineError> {
let secret_token = secrets.SCALEWAY_SECRET_KEY.unwrap();
let project_id = secrets.SCALEWAY_DEFAULT_PROJECT_ID.unwrap();

View File

@@ -28,7 +28,7 @@ use crate::scaleway::{
};
use hashicorp_vault;
use qovery_engine::build_platform::local_docker::LocalDocker;
use qovery_engine::cloud_provider::scaleway::application::Zone;
use qovery_engine::cloud_provider::scaleway::application::ScwZone;
use qovery_engine::cloud_provider::Kind;
use qovery_engine::cmd;
use qovery_engine::constants::{
@@ -44,7 +44,7 @@ use crate::digitalocean::{
DO_MANAGED_DATABASE_DISK_TYPE, DO_MANAGED_DATABASE_INSTANCE_TYPE, DO_SELF_HOSTED_DATABASE_DISK_TYPE,
DO_SELF_HOSTED_DATABASE_INSTANCE_TYPE,
};
use qovery_engine::cloud_provider::digitalocean::application::Region;
use qovery_engine::cloud_provider::digitalocean::application::DoRegion;
use qovery_engine::cmd::kubectl::{kubectl_get_pvc, kubectl_get_svc};
use qovery_engine::cmd::structs::{KubernetesList, KubernetesPod, PVC, SVC};
use qovery_engine::cmd::utilities::QoveryCommand;
@@ -534,7 +534,7 @@ where
.expect(&"DIGITAL_OCEAN_DEFAULT_REGION should be set".to_string())
.to_string();
match Region::from_str(region_raw.as_str()) {
match DoRegion::from_str(region_raw.as_str()) {
Ok(region) => {
let spaces = Spaces::new(
context.clone(),
@@ -592,7 +592,7 @@ where
}
Kind::Scw => {
// TODO(benjaminch): refactor all of this properly
let zone = Zone::from_str(secrets.clone().SCALEWAY_DEFAULT_REGION.unwrap().as_str()).unwrap();
let zone = ScwZone::from_str(secrets.clone().SCALEWAY_DEFAULT_REGION.unwrap().as_str()).unwrap();
let project_id = secrets.clone().SCALEWAY_DEFAULT_PROJECT_ID.unwrap();
let secret_access_key = secrets.clone().SCALEWAY_SECRET_KEY.unwrap();

View File

@@ -7,12 +7,15 @@ use self::test_utilities::utilities::{
use ::function_name::named;
use qovery_engine::cloud_provider::aws::kubernetes::VpcQoveryNetworkMode;
use qovery_engine::cloud_provider::aws::kubernetes::VpcQoveryNetworkMode::{WithNatGateways, WithoutNatGateways};
use qovery_engine::cloud_provider::aws::regions::{AwsRegion, AwsZones};
use qovery_engine::cloud_provider::Kind;
use std::str::FromStr;
use test_utilities::common::{cluster_test, ClusterDomain, ClusterTestType};
#[cfg(feature = "test-aws-infra")]
fn create_and_destroy_eks_cluster(
region: &str,
region: String,
zones: Vec<AwsZones>,
secrets: FuncTestsSecrets,
test_type: ClusterTestType,
major_boot_version: u8,
@@ -21,12 +24,17 @@ fn create_and_destroy_eks_cluster(
test_name: &str,
) {
engine_run_test(|| {
let region = AwsRegion::from_str(region.as_str()).expect("Wasn't able to convert the desired region");
cluster_test(
test_name,
Kind::Aws,
context(generate_id().as_str(), generate_cluster_id(region.clone()).as_str()),
context(
generate_id().as_str(),
generate_cluster_id(region.to_string().as_str()).as_str(),
),
logger(),
region,
region.to_aws_format().as_str(),
Some(zones),
secrets,
test_type,
major_boot_version,
@@ -47,10 +55,12 @@ fn create_and_destroy_eks_cluster(
#[named]
#[test]
fn create_and_destroy_eks_cluster_without_nat_gw_in_eu_west_3() {
let region = "eu-west-3";
let secrets = FuncTestsSecrets::new();
let region = secrets.AWS_DEFAULT_REGION.clone().expect("AWS region was not found");
let aws_region = AwsRegion::from_str(region.as_str()).expect("Wasn't able to convert the desired region");
create_and_destroy_eks_cluster(
&region,
region,
AwsRegion::get_zones(&aws_region),
secrets,
ClusterTestType::Classic,
AWS_KUBERNETES_MAJOR_VERSION,
@@ -64,10 +74,12 @@ fn create_and_destroy_eks_cluster_without_nat_gw_in_eu_west_3() {
#[named]
#[test]
fn create_and_destroy_eks_cluster_with_nat_gw_in_eu_west_3() {
let region = "eu-west-3";
let secrets = FuncTestsSecrets::new();
let region = secrets.AWS_DEFAULT_REGION.clone().expect("AWS region was not found");
let aws_region = AwsRegion::from_str(&region).expect("Wasn't able to convert the desired region");
create_and_destroy_eks_cluster(
&region,
region,
AwsRegion::get_zones(&aws_region),
secrets,
ClusterTestType::Classic,
AWS_KUBERNETES_MAJOR_VERSION,
@@ -81,10 +93,12 @@ fn create_and_destroy_eks_cluster_with_nat_gw_in_eu_west_3() {
#[named]
#[test]
fn create_and_destroy_eks_cluster_in_us_east_2() {
let region = "us-east-2";
let secrets = FuncTestsSecrets::new();
let region = "us-east-2".to_string();
let aws_region = AwsRegion::from_str(&region).expect("Wasn't able to convert the desired region");
create_and_destroy_eks_cluster(
&region,
region,
AwsRegion::get_zones(&aws_region),
secrets,
ClusterTestType::Classic,
AWS_KUBERNETES_MAJOR_VERSION,
@@ -100,11 +114,13 @@ fn create_and_destroy_eks_cluster_in_us_east_2() {
#[test]
#[ignore]
fn create_upgrade_and_destroy_eks_cluster_in_eu_west_3() {
let region = "eu-west-3";
let secrets = FuncTestsSecrets::new();
let region = secrets.AWS_DEFAULT_REGION.clone().expect("AWS region was not found");
let aws_region = AwsRegion::from_str(&region).expect("Wasn't able to convert the desired region");
create_and_destroy_eks_cluster(
&region,
region,
AwsRegion::get_zones(&aws_region),
secrets,
ClusterTestType::WithUpgrade,
AWS_KUBERNETES_MAJOR_VERSION,

View File

@@ -1,7 +1,9 @@
use ::function_name::named;
use qovery_engine::cloud_provider::aws::kubernetes::VpcQoveryNetworkMode::WithNatGateways;
use qovery_engine::cloud_provider::aws::regions::AwsRegion;
use qovery_engine::cloud_provider::Kind;
use qovery_engine::models::EnvironmentAction;
use std::str::FromStr;
use test_utilities::aws::{AWS_KUBERNETES_MAJOR_VERSION, AWS_KUBERNETES_MINOR_VERSION};
use test_utilities::common::{cluster_test, ClusterDomain, ClusterTestType};
use test_utilities::utilities::{context, engine_run_test, generate_cluster_id, generate_id, logger, FuncTestsSecrets};
@@ -10,11 +12,16 @@ use test_utilities::utilities::{context, engine_run_test, generate_cluster_id, g
#[named]
#[test]
fn create_upgrade_and_destroy_eks_cluster_with_env_in_eu_west_3() {
let region = "eu-west-3";
let organization_id = generate_id();
let cluster_id = generate_cluster_id(region);
let context = context(organization_id.as_str(), cluster_id.as_str());
let secrets = FuncTestsSecrets::new();
let region = secrets.AWS_DEFAULT_REGION.as_ref().expect("AWS region was not found");
let aws_region = AwsRegion::from_str(&region).expect("Wasn't able to convert the desired region");
let aws_zones = aws_region.get_zones();
let organization_id = generate_id();
let cluster_id = generate_cluster_id(aws_region.to_string().as_str());
let context = context(organization_id.as_str(), cluster_id.as_str());
let cluster_domain = format!(
"{}.{}",
cluster_id.as_str(),
@@ -34,7 +41,8 @@ fn create_upgrade_and_destroy_eks_cluster_with_env_in_eu_west_3() {
Kind::Aws,
context.clone(),
logger(),
region,
&region,
Some(aws_zones),
secrets.clone(),
ClusterTestType::Classic,
AWS_KUBERNETES_MAJOR_VERSION,

View File

@@ -6,13 +6,13 @@ use self::test_utilities::utilities::{
context, engine_run_test, generate_cluster_id, generate_id, logger, FuncTestsSecrets,
};
use ::function_name::named;
use qovery_engine::cloud_provider::digitalocean::application::Region;
use qovery_engine::cloud_provider::digitalocean::application::DoRegion;
use qovery_engine::cloud_provider::Kind;
use test_utilities::common::{cluster_test, ClusterTestType};
#[cfg(feature = "test-do-infra")]
fn create_and_destroy_doks_cluster(
region: Region,
region: DoRegion,
secrets: FuncTestsSecrets,
test_type: ClusterTestType,
major_boot_version: u8,
@@ -26,6 +26,7 @@ fn create_and_destroy_doks_cluster(
context(generate_id().as_str(), generate_cluster_id(region.as_str()).as_str()),
logger(),
region.as_str(),
None,
secrets,
test_type,
major_boot_version,
@@ -41,7 +42,7 @@ fn create_and_destroy_doks_cluster(
#[named]
#[test]
fn create_and_destroy_doks_cluster_ams_3() {
let region = Region::Amsterdam3;
let region = DoRegion::Amsterdam3;
let secrets = FuncTestsSecrets::new();
create_and_destroy_doks_cluster(
region,
@@ -58,7 +59,7 @@ fn create_and_destroy_doks_cluster_ams_3() {
#[test]
#[ignore]
fn create_upgrade_and_destroy_doks_cluster_in_nyc_3() {
let region = Region::NewYorkCity3;
let region = DoRegion::NewYorkCity3;
let secrets = FuncTestsSecrets::new();
create_and_destroy_doks_cluster(
region,

View File

@@ -1,11 +1,11 @@
use qovery_engine::cloud_provider::digitalocean::application::Region;
use qovery_engine::cloud_provider::digitalocean::application::DoRegion;
use qovery_engine::object_storage::spaces::{BucketDeleteStrategy, Spaces};
use qovery_engine::object_storage::ObjectStorage;
use tempfile::NamedTempFile;
use test_utilities::utilities::{context, generate_id, FuncTestsSecrets};
#[allow(dead_code)]
const TEST_REGION: Region = Region::Amsterdam3;
const TEST_REGION: DoRegion = DoRegion::Amsterdam3;
#[cfg(feature = "test-do-infra")]
#[test]

View File

@@ -1,5 +1,5 @@
use ::function_name::named;
use qovery_engine::cloud_provider::digitalocean::application::Region;
use qovery_engine::cloud_provider::digitalocean::application::DoRegion;
use qovery_engine::cloud_provider::Kind;
use qovery_engine::models::EnvironmentAction;
use test_utilities::common::{cluster_test, ClusterDomain, ClusterTestType};
@@ -10,11 +10,13 @@ use test_utilities::utilities::{context, engine_run_test, generate_cluster_id, g
#[named]
#[test]
fn create_upgrade_and_destroy_doks_cluster_with_env_in_ams_3() {
let region = Region::Amsterdam3;
let logger = logger();
let region = DoRegion::Amsterdam3;
let organization_id = generate_id();
let cluster_id = generate_cluster_id(region.as_str());
let context = context(organization_id.as_str(), cluster_id.as_str());
let logger = logger();
let secrets = FuncTestsSecrets::new();
let cluster_domain = format!(
"{}.{}",
@@ -36,6 +38,7 @@ fn create_upgrade_and_destroy_doks_cluster_with_env_in_ams_3() {
context.clone(),
logger,
region.as_str(),
None,
secrets.clone(),
ClusterTestType::Classic,
DO_KUBERNETES_MAJOR_VERSION,

View File

@@ -2,13 +2,13 @@ extern crate test_utilities;
use self::test_utilities::utilities::{context, FuncTestsSecrets};
use qovery_engine::build_platform::Image;
use qovery_engine::cloud_provider::scaleway::application::Zone;
use qovery_engine::cloud_provider::scaleway::application::ScwZone;
use qovery_engine::container_registry::scaleway_container_registry::ScalewayCR;
use tracing::debug;
use uuid::Uuid;
fn zones_to_test() -> Vec<Zone> {
vec![Zone::Paris1, Zone::Paris2, Zone::Amsterdam1, Zone::Warsaw1]
fn zones_to_test() -> Vec<ScwZone> {
vec![ScwZone::Paris1, ScwZone::Paris2, ScwZone::Amsterdam1, ScwZone::Warsaw1]
}
#[cfg(feature = "test-scw-infra")]

View File

@@ -6,13 +6,13 @@ use self::test_utilities::utilities::{
};
use ::function_name::named;
use qovery_engine::cloud_provider::aws::kubernetes::VpcQoveryNetworkMode;
use qovery_engine::cloud_provider::scaleway::application::Zone;
use qovery_engine::cloud_provider::scaleway::application::ScwZone;
use qovery_engine::cloud_provider::Kind;
use test_utilities::common::{cluster_test, ClusterDomain, ClusterTestType};
#[cfg(feature = "test-scw-infra")]
fn create_and_destroy_kapsule_cluster(
zone: Zone,
zone: ScwZone,
secrets: FuncTestsSecrets,
test_type: ClusterTestType,
major_boot_version: u8,
@@ -27,6 +27,7 @@ fn create_and_destroy_kapsule_cluster(
context(generate_id().as_str(), generate_cluster_id(zone.as_str()).as_str()),
logger(),
zone.as_str(),
None,
secrets,
test_type,
major_boot_version,
@@ -43,7 +44,7 @@ fn create_and_destroy_kapsule_cluster(
#[ignore]
#[test]
fn create_and_destroy_kapsule_cluster_par_1() {
let zone = Zone::Paris1;
let zone = ScwZone::Paris1;
let secrets = FuncTestsSecrets::new();
create_and_destroy_kapsule_cluster(
zone,
@@ -60,7 +61,7 @@ fn create_and_destroy_kapsule_cluster_par_1() {
#[named]
#[test]
fn create_and_destroy_kapsule_cluster_par_2() {
let zone = Zone::Paris2;
let zone = ScwZone::Paris2;
let secrets = FuncTestsSecrets::new();
create_and_destroy_kapsule_cluster(
zone,
@@ -77,7 +78,7 @@ fn create_and_destroy_kapsule_cluster_par_2() {
#[named]
#[test]
fn create_pause_and_destroy_kapsule_cluster_ams_1() {
let zone = Zone::Amsterdam1;
let zone = ScwZone::Amsterdam1;
let secrets = FuncTestsSecrets::new();
create_and_destroy_kapsule_cluster(
zone,
@@ -94,7 +95,7 @@ fn create_pause_and_destroy_kapsule_cluster_ams_1() {
#[named]
#[test]
fn create_and_destroy_kapsule_cluster_war_1() {
let zone = Zone::Warsaw1;
let zone = ScwZone::Warsaw1;
let secrets = FuncTestsSecrets::new();
create_and_destroy_kapsule_cluster(
zone,
@@ -113,7 +114,7 @@ fn create_and_destroy_kapsule_cluster_war_1() {
#[named]
#[ignore]
fn create_upgrade_and_destroy_kapsule_cluster_in_par_1() {
let zone = Zone::Paris1;
let zone = ScwZone::Paris1;
let secrets = FuncTestsSecrets::new();
create_and_destroy_kapsule_cluster(
zone,
@@ -132,7 +133,7 @@ fn create_upgrade_and_destroy_kapsule_cluster_in_par_1() {
#[named]
#[ignore]
fn create_upgrade_and_destroy_kapsule_cluster_in_par_2() {
let zone = Zone::Paris2;
let zone = ScwZone::Paris2;
let secrets = FuncTestsSecrets::new();
create_and_destroy_kapsule_cluster(
zone,
@@ -151,7 +152,7 @@ fn create_upgrade_and_destroy_kapsule_cluster_in_par_2() {
#[named]
#[ignore]
fn create_upgrade_and_destroy_kapsule_cluster_in_ams_1() {
let zone = Zone::Amsterdam1;
let zone = ScwZone::Amsterdam1;
let secrets = FuncTestsSecrets::new();
create_and_destroy_kapsule_cluster(
zone,
@@ -170,7 +171,7 @@ fn create_upgrade_and_destroy_kapsule_cluster_in_ams_1() {
#[named]
#[ignore]
fn create_upgrade_and_destroy_kapsule_cluster_in_war_1() {
let zone = Zone::Warsaw1;
let zone = ScwZone::Warsaw1;
let secrets = FuncTestsSecrets::new();
create_and_destroy_kapsule_cluster(
zone,

View File

@@ -1,5 +1,5 @@
use ::function_name::named;
use qovery_engine::cloud_provider::scaleway::application::Zone;
use qovery_engine::cloud_provider::scaleway::application::ScwZone;
use qovery_engine::cloud_provider::Kind;
use qovery_engine::models::EnvironmentAction;
use test_utilities::common::{cluster_test, ClusterDomain, ClusterTestType};
@@ -11,11 +11,11 @@ use test_utilities::utilities::{context, engine_run_test, generate_cluster_id, g
#[test]
fn create_and_destroy_kapsule_cluster_with_env_in_par_2() {
let logger = logger();
let zone = Zone::Paris2;
let zone = ScwZone::Paris2;
let secrets = FuncTestsSecrets::new();
let organization_id = generate_id();
let cluster_id = generate_cluster_id(zone.as_str());
let context = context(organization_id.as_str(), cluster_id.as_str());
let secrets = FuncTestsSecrets::new();
let cluster_domain = format!(
"{}.{}",
cluster_id.as_str(),
@@ -36,6 +36,7 @@ fn create_and_destroy_kapsule_cluster_with_env_in_par_2() {
context.clone(),
logger,
zone.as_str(),
None,
secrets.clone(),
ClusterTestType::Classic,
SCW_KUBERNETES_MAJOR_VERSION,