diff --git a/README.md b/README.md index 591fb59e..c3d17197 100644 --- a/README.md +++ b/README.md @@ -56,14 +56,54 @@ TODO TODO #### Rust lib -Initialize Kubernetes on AWS +Initialize EKS (AWS Kubernetes) and ECR (AWS container registry) on AWS ```rust -let x = "TODO"; +let engine = Engine::new( + context, + local_docker, + ecr, + aws, + cloudflare, +); + +let session = match engine.session() { + Ok(session) => session, + Err(config_error) => panic!("configuration error {:?}", config_error), +}; + +let mut tx = session.transaction(); +tx.create_kubernetes(&eks); + +match tx.commit() { + TransactionResult::Ok => println!("OK"), + TransactionResult::Rollback(commit_err) => println!("ERROR but rollback OK"), + TransactionResult::UnrecoverableError(commit_err, rollback_err) => println!("FATAL ERROR") +}; ``` Deploy an app on AWS ```rust -let y = "TODO"; +let engine = Engine::new( + context, + local_docker, + ecr, + aws, + cloudflare, +); + +let session = match engine.session() { + Ok(session) => session, + Err(config_error) => panic!("configuration error {:?}", config_error), +}; + +let mut tx = session.transaction(); +tx.create_kubernetes(&eks); + +match tx.commit() { + TransactionResult::Ok => println!("OK"), + TransactionResult::Rollback(commit_err) => println!("ERROR but rollback OK"), + TransactionResult::UnrecoverableError(commit_err, rollback_err) => println!("FATAL ERROR") +}; ``` ## Documentation diff --git a/examples/create_simple_infrastructure_on_aws.rs b/examples/create_simple_infrastructure_on_aws.rs new file mode 100644 index 00000000..fb4de7f4 --- /dev/null +++ b/examples/create_simple_infrastructure_on_aws.rs @@ -0,0 +1,140 @@ +use chrono::Utc; +use qovery_engine::build_platform::local_docker::LocalDocker; +use qovery_engine::cloud_provider::aws::kubernetes::node::Node; +use qovery_engine::cloud_provider::aws::kubernetes::{Options, EKS}; +use qovery_engine::cloud_provider::aws::AWS; +use qovery_engine::cloud_provider::TerraformStateCredentials; +use qovery_engine::container_registry::ecr::ECR; +use qovery_engine::dns_provider::cloudflare::Cloudflare; +use qovery_engine::engine::Engine; +use qovery_engine::error::ConfigurationError; +use qovery_engine::models::{ + Action, Application, Context, Environment, EnvironmentAction, GitCredentials, Kind, +}; +use qovery_engine::session::Session; +use qovery_engine::transaction::TransactionResult; + +fn main() { + let context = Context::new("unique-id", "/tmp/qovery-workspace", "lib", None, None); + + // build image with Docker + let local_docker = LocalDocker::new(context.clone(), "local-docker-id", "local-docker-name"); + + // use ECR as Container Registry + let ecr = ECR::new( + context.clone(), + "ecr-id", + "ecr-name", + "YOUR AWS ACCESS KEY", + "YOUR AWS SECRET ACCESS KEY", + "us-east-1", + ); + + // use cloudflare as DNS provider + let cloudflare = Cloudflare::new( + context.clone(), + "cloudflare-id", + "cloudflare-name", + "tld.io", + "YOUR CLOUDFLARE TOKEN", + "YOUR CLOUDFLARE EMAIL", + ); + + // use AWS + let aws = AWS::new( + context.clone(), + "aws-id", + "organization-id", + "eks-name", + "YOUR AWS ACCESS KEY", + "YOUR AWS SECRET ACCESS KEY", + TerraformStateCredentials::new( + "YOUR AWS ACCESS KEY", + "YOUR AWS SECRET ACCESS KEY", + "us-east-1", + ), + ); + + let nodes = vec![Node::new(2, 4), Node::new(2, 4), Node::new(2, 4)]; + + // use Kubernetes + let eks = EKS::new( + context.clone(), + "eks-id", + "eks-name", + "1.16", + "us-east-1", + &aws, + &cloudflare, + Options::default(), + nodes, + ); + + let engine = Engine::new( + context, + Box::new(local_docker), + Box::new(ecr), + Box::new(aws), + Box::new(cloudflare), + ); + + let session = match engine.session() { + Ok(session) => session, + Err(config_error) => match config_error { + ConfigurationError::BuildPlatform(_) => panic!("build platform config error"), + ConfigurationError::ContainerRegistry(_) => panic!("container registry config error"), + ConfigurationError::CloudProvider(_) => panic!("cloud provider config error"), + ConfigurationError::DnsProvider(_) => panic!("dns provider config error"), + }, + }; + + let mut tx = session.transaction(); + tx.create_kubernetes(&eks); + + let environment = Environment { + execution_id: "unique-id".to_string(), + id: "environment-id".to_string(), + kind: Kind::Production, + owner_id: "owner-id".to_string(), + project_id: "project-id".to_string(), + organization_id: "organization-id".to_string(), + action: Action::Create, + applications: vec![Application { + id: "app-id-1".to_string(), + name: "app-name-1".to_string(), + action: Action::Create, + git_url: "https://github.com/Qovery/node-simple-example.git".to_string(), + git_credentials: GitCredentials { + login: "github-login".to_string(), + access_token: "github-access-token".to_string(), + expired_at: Utc::now(), + }, + branch: "main".to_string(), + commit_id: "238f7f0454783defa4946613bc17ebbf4ccc514a".to_string(), + dockerfile_path: "Dockerfile".to_string(), + private_port: Some(3000), + total_cpus: "256m".to_string(), + cpu_burst: "500m".to_string(), + total_ram_in_mib: 256, + total_instances: 1, + storage: vec![], + environment_variables: vec![], + }], + routers: vec![], + databases: vec![], + external_services: vec![], + clone_from_environment_id: None, + }; + + tx.deploy_environment(&eks, &EnvironmentAction::Environment(environment)); + + match tx.commit() { + TransactionResult::Ok => println!("infrastructure initialization OK"), + TransactionResult::Rollback(commit_err) => { + println!("infrastructure initialization ERROR and rollback OK") + } + TransactionResult::UnrecoverableError(commit_err, rollback_err) => { + println!("infrastructure initialization ERROR and rollback FAILED") + } + }; +} diff --git a/examples/simple_deployment_on_aws.rs b/examples/simple_deployment_on_aws.rs deleted file mode 100644 index 2e83beac..00000000 --- a/examples/simple_deployment_on_aws.rs +++ /dev/null @@ -1,17 +0,0 @@ -use qovery_engine::build_platform::local_docker::LocalDocker; -use qovery_engine::models::Context; - -fn main() { - let context = Context::new("unique-id", "/tmp/qovery-workspace", "lib", None, None); - - // build image with Docker - let local_docker = LocalDocker::new(context, "local-docker", "local-docker-name"); - - // use ECR as Container Registry - - // use cloudflare as DNS provider - - // use Kubernetes 1.16 - - // use AWS -} diff --git a/src/cloud_provider/mod.rs b/src/cloud_provider/mod.rs index 9dfd64c8..66d20c52 100644 --- a/src/cloud_provider/mod.rs +++ b/src/cloud_provider/mod.rs @@ -78,6 +78,16 @@ pub struct TerraformStateCredentials { pub region: String, } +impl TerraformStateCredentials { + pub fn new(access_key_id: &str, secret_access_key: &str, region: &str) -> Self { + TerraformStateCredentials { + access_key_id: access_key_id.to_string(), + secret_access_key: secret_access_key.to_string(), + region: region.to_string(), + } + } +} + pub enum DeploymentTarget<'a> { // ManagedService = Managed by the Cloud Provider (eg. RDS, DynamoDB...) ManagedServices(&'a dyn Kubernetes, &'a Environment), diff --git a/src/dns_provider/cloudflare.rs b/src/dns_provider/cloudflare.rs index 42d56e99..ee021249 100644 --- a/src/dns_provider/cloudflare.rs +++ b/src/dns_provider/cloudflare.rs @@ -15,19 +15,19 @@ pub struct Cloudflare { impl Cloudflare { pub fn new( context: Context, - id: String, - name: String, - domain: String, - cloudflare_api_token: String, - cloudflare_email: String, + id: &str, + name: &str, + domain: &str, + cloudflare_api_token: &str, + cloudflare_email: &str, ) -> Self { Cloudflare { context, - id, - name, - domain, - cloudflare_api_token, - cloudflare_email, + id: id.to_string(), + name: name.to_string(), + domain: domain.to_string(), + cloudflare_api_token: cloudflare_api_token.to_string(), + cloudflare_email: cloudflare_email.to_string(), } } } diff --git a/src/engine.rs b/src/engine.rs index a2f7d76e..37ea671c 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -3,7 +3,7 @@ use std::borrow::Borrow; use crate::build_platform::BuildPlatform; use crate::cloud_provider::CloudProvider; use crate::container_registry::ContainerRegistry; -use crate::dns_provider::DnsProvider; +use crate::dns_provider::{DnsProvider, DnsProviderError}; use crate::error::ConfigurationError; use crate::models::Context; use crate::session::Session; @@ -76,6 +76,13 @@ impl<'a> Engine { } } + match self.dns_provider.is_valid() { + Ok(_) => {} + Err(err) => { + return Err(ConfigurationError::DnsProvider(err)); + } + } + Ok(()) } diff --git a/src/error.rs b/src/error.rs index 51780c59..702fbb35 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,10 +1,12 @@ use crate::build_platform::error::BuildPlatformError; use crate::cloud_provider::CloudProviderError; use crate::container_registry::ContainerRegistryError; +use crate::dns_provider::DnsProviderError; #[derive(Debug)] pub enum ConfigurationError { BuildPlatform(BuildPlatformError), ContainerRegistry(ContainerRegistryError), CloudProvider(CloudProviderError), + DnsProvider(DnsProviderError), } diff --git a/test_utilities/src/cloudflare.rs b/test_utilities/src/cloudflare.rs index c526533d..47792ca6 100644 --- a/test_utilities/src/cloudflare.rs +++ b/test_utilities/src/cloudflare.rs @@ -16,10 +16,10 @@ pub fn cloudflare_domain() -> String { pub fn dns_provider_cloudflare(context: &Context) -> Cloudflare { Cloudflare::new( context.clone(), - "qoverytestdnsclo".to_string(), - "Qovery Test Cloudflare".to_string(), - cloudflare_domain(), - cloudflare_token(), // Cloudflare name: Qovery test - cloudflare_id(), + "qoverytestdnsclo", + "Qovery Test Cloudflare", + cloudflare_domain().as_str(), + cloudflare_token().as_str(), // Cloudflare name: Qovery test + cloudflare_id().as_str(), ) }