Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions migrations/8__add_google_cloud_provider.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
INSERT INTO providers (id, display_name, required_variables, supports_spot) VALUES
('gcp', 'Google Cloud Platform', 'GOOGLE_APPLICATION_CREDENTIALS', 1);
14 changes: 13 additions & 1 deletion src/integrations/cloud_interface.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::database::models::{Cluster, InstanceType, MachineImage, Node};
use crate::integrations::providers::{aws::AwsInterface, vultr::VultrInterface};
use crate::integrations::providers::{aws::AwsInterface, gcp::GcpInterface, vultr::VultrInterface};
use crate::utils::ProgressTracker;

use anyhow::{Error, Result};
Expand Down Expand Up @@ -59,13 +59,15 @@ pub trait CloudResourceManager {
pub enum CloudProvider {
Aws(AwsInterface),
Vultr(VultrInterface),
Gcp(GcpInterface),
}

impl CloudInfoProvider for CloudProvider {
async fn fetch_regions(&self, tracker: &ProgressTracker) -> Result<Vec<String>, Error> {
match self {
CloudProvider::Aws(aws) => aws.fetch_regions(tracker).await,
CloudProvider::Vultr(vultr) => vultr.fetch_regions(tracker).await,
CloudProvider::Gcp(gcp) => gcp.fetch_regions(tracker).await,
}
}

Expand All @@ -77,6 +79,7 @@ impl CloudInfoProvider for CloudProvider {
match self {
CloudProvider::Aws(aws) => aws.fetch_zones(region, tracker).await,
CloudProvider::Vultr(vultr) => vultr.fetch_zones(region, tracker).await,
CloudProvider::Gcp(gcp) => gcp.fetch_zones(region, tracker).await,
}
}

Expand All @@ -88,6 +91,7 @@ impl CloudInfoProvider for CloudProvider {
match self {
CloudProvider::Aws(aws) => aws.fetch_instance_types(region, tracker).await,
CloudProvider::Vultr(vultr) => vultr.fetch_instance_types(region, tracker).await,
CloudProvider::Gcp(gcp) => gcp.fetch_instance_types(region, tracker).await,
}
}

Expand All @@ -102,6 +106,7 @@ impl CloudInfoProvider for CloudProvider {
CloudProvider::Vultr(vultr) => {
vultr.fetch_prices(region, instance_types, tracker).await
}
CloudProvider::Gcp(gcp) => gcp.fetch_prices(region, instance_types, tracker).await,
}
}

Expand All @@ -113,6 +118,7 @@ impl CloudInfoProvider for CloudProvider {
match self {
CloudProvider::Aws(aws) => aws.fetch_machine_image(region, image_id).await,
CloudProvider::Vultr(vultr) => vultr.fetch_machine_image(region, image_id).await,
CloudProvider::Gcp(gcp) => gcp.fetch_machine_image(region, image_id).await,
}
}
}
Expand All @@ -127,6 +133,7 @@ impl CloudResourceManager for CloudProvider {
match self {
CloudProvider::Aws(aws) => aws.spawn_cluster(pool, cluster, nodes).await,
CloudProvider::Vultr(vultr) => vultr.spawn_cluster(pool, cluster, nodes).await,
CloudProvider::Gcp(gcp) => gcp.spawn_cluster(pool, cluster, nodes).await,
}
}

Expand All @@ -139,6 +146,7 @@ impl CloudResourceManager for CloudProvider {
match self {
CloudProvider::Aws(aws) => aws.terminate_cluster(pool, cluster, nodes).await,
CloudProvider::Vultr(vultr) => vultr.terminate_cluster(pool, cluster, nodes).await,
CloudProvider::Gcp(gcp) => gcp.terminate_cluster(pool, cluster, nodes).await,
}
}

Expand All @@ -158,6 +166,10 @@ impl CloudResourceManager for CloudProvider {
.simulate_cluster_failure(pool, cluster, node_private_ip)
.await
}
CloudProvider::Gcp(gcp) => {
gcp.simulate_cluster_failure(pool, cluster, node_private_ip)
.await
}
}
}
}
20 changes: 20 additions & 0 deletions src/integrations/providers/gcp/interface.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use crate::database::models::{ConfigVar, ConfigVarFinder};

use anyhow::{Result, bail};
use reqwest::{Client as HttpClient, header};
use serde_json::Value as JsonValue;
use tracing::error;

pub struct GcpInterface {
pub config_vars: Vec<ConfigVar>,
}

/// TODO: Decide over using the Rust SDK or the REST API...
/// Rust SDK: https://github.com/googleapis/google-cloud-rust/tree/main
/// REST API: https://cloud.google.com/compute/docs/authentication?hl=pt-br#rest
///
/// If using the API, check the Vultr code for an example on how to use the `reqwest` http
/// client for requests.
/// If using the Rust SDK, check the SDK own documentation and the AWS code to get an idea of
/// how to implement this method.
impl GcpInterface {}
5 changes: 5 additions & 0 deletions src/integrations/providers/gcp/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod interface;
mod resource_catalog;
mod resource_manager;

pub use interface::GcpInterface;
39 changes: 39 additions & 0 deletions src/integrations/providers/gcp/resource_catalog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::database::models::{InstanceType, MachineImage};
use crate::integrations::CloudInfoProvider;
use crate::utils::ProgressTracker;

use anyhow::{Result, bail};
use std::collections::HashMap;

use super::interface::GcpInterface;

impl CloudInfoProvider for GcpInterface {
async fn fetch_regions(&self, _tracker: &ProgressTracker) -> Result<Vec<String>> {
bail!("Not implemented")
}

async fn fetch_zones(&self, _region: &str, _tracker: &ProgressTracker) -> Result<Vec<String>> {
bail!("Not implemented")
}

async fn fetch_instance_types(
&self,
_region: &str,
_tracker: &ProgressTracker,
) -> Result<Vec<InstanceType>> {
bail!("Not implemented")
}

async fn fetch_prices(
&self,
_region: &str,
_instance_types: &[String],
_tracker: &ProgressTracker,
) -> Result<HashMap<String, f64>> {
bail!("Not implemented")
}

async fn fetch_machine_image(&self, _region: &str, _image_id: &str) -> Result<MachineImage> {
bail!("Not implemented")
}
}
36 changes: 36 additions & 0 deletions src/integrations/providers/gcp/resource_manager.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use crate::database::models::{Cluster, Node};
use crate::integrations::CloudResourceManager;

use anyhow::{Result, bail};
use sqlx::sqlite::SqlitePool;

use super::interface::GcpInterface;

impl CloudResourceManager for GcpInterface {
async fn spawn_cluster(
&self,
_pool: &SqlitePool,
_cluster: Cluster,
_nodes: Vec<Node>,
) -> Result<()> {
bail!("Not implemented")
}

async fn terminate_cluster(
&self,
_pool: &SqlitePool,
_cluster: Cluster,
_nodes: Vec<Node>,
) -> Result<()> {
bail!("Not implemented")
}

async fn simulate_cluster_failure(
&self,
_pool: &SqlitePool,
_cluster: Cluster,
_node_private_ip: &str,
) -> Result<()> {
bail!("Not implemented")
}
}
1 change: 1 addition & 0 deletions src/integrations/providers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod aws;
pub mod gcp;
pub mod vultr;