Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dummy Pr 3200 #3234

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4051561
- create enterprise features crate
laststylebender14 Dec 5, 2024
d70c376
- add crate to tailcall
laststylebender14 Dec 5, 2024
23ed3a0
- add checks for enterprise features
laststylebender14 Dec 5, 2024
babff21
- lint changes
laststylebender14 Dec 5, 2024
1739e8e
- handle validation errors.
laststylebender14 Dec 5, 2024
813b894
- typo fix
laststylebender14 Dec 5, 2024
901e925
Merge branch 'main' into feat/gate-enterprise-features-with-keygen
laststylebender14 Dec 5, 2024
15b6918
- ref keygen-rs from fork.
laststylebender14 Dec 5, 2024
e9585cb
Merge branch 'feat/gate-enterprise-features-with-keygen' of https://g…
laststylebender14 Dec 5, 2024
438794e
- make enterprise-features optional
laststylebender14 Dec 5, 2024
b3a6909
- typo fix
laststylebender14 Dec 5, 2024
e1f2f62
- update commit id for fork
laststylebender14 Dec 5, 2024
bd3fa00
- rename crate to `tailcall-enterprise`
laststylebender14 Dec 5, 2024
4431307
- rename method and add better docs.
laststylebender14 Dec 6, 2024
75ae607
- use enum based errors
laststylebender14 Dec 6, 2024
8937ef7
- add postgres client
laststylebender14 Dec 6, 2024
64c2c51
- remove secrets
laststylebender14 Dec 6, 2024
9a7ca4c
Merge branch 'main' into feat/gate-enterprise-features-with-keygen
laststylebender14 Dec 6, 2024
c80289f
- update the refs for keygen as pr is merged.
laststylebender14 Dec 10, 2024
f9cf9fe
Merge branch 'main' into feat/gate-enterprise-features-with-keygen
laststylebender14 Dec 10, 2024
7287ed5
Merge branch 'main' into feat/gate-enterprise-features-with-keygen
tusharmath Dec 24, 2024
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
357 changes: 338 additions & 19 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ tailcall-http-cache = { path = "tailcall-http-cache", optional = true }
tailcall-version = { path = "./tailcall-version", optional = true }
genai = { git = "https://github.com/laststylebender14/rust-genai.git", rev = "63a542ce20132503c520f4e07108e0d768f243c3", optional = true }
ctrlc = { version = "3.4.5", optional = true }
tailcall-enterprise = { path = "./tailcall-enterprise", optional = true }

# dependencies safe for wasm:

Expand Down Expand Up @@ -237,6 +238,7 @@ cli = [
"dep:tailcall-version",
"dep:genai",
"dep:ctrlc",
"dep:tailcall-enterprise",
]

# Feature flag to enable all default features.
Expand All @@ -262,7 +264,8 @@ members = [
"tailcall-wasm",
"tailcall-hasher",
"tailcall-http-cache",
"tailcall-version",
"tailcall-version",
"tailcall-enterprise",
]

# Boost execution_spec snapshot diffing performance
Expand Down
12 changes: 12 additions & 0 deletions src/cli/tc/start.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use anyhow::Result;
use tailcall_enterprise::Enterprise;
use tracing::info;

use super::helpers::log_endpoint_set;
use crate::cli::fmt::Fmt;
Expand All @@ -12,6 +14,16 @@
let config_module = config_reader.read_all(&file_paths).await?;
log_endpoint_set(&config_module.extensions().endpoint_set);
Fmt::log_n_plus_one(false, config_module.config());

// config module understand the configuration and the features enabled in the
// configuration.
if config_module.is_enterprise_features_enabled() {
let enterprise = Enterprise::try_new().await?;
if enterprise.is_validated() {
info!("TAILCALL_TOKEN validated successfully. Enabling all enterprise features")
}
}

Check warning on line 25 in src/cli/tc/start.rs

View check run for this annotation

Codecov / codecov/patch

src/cli/tc/start.rs#L17-L25

Added lines #L17 - L25 were not covered by tests

let server = Server::new(config_module);
server.fork_start().await?;
Ok(())
Expand Down
12 changes: 12 additions & 0 deletions src/core/config/config_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
use tailcall_valid::{Valid, Validator};

use super::LinkType;
use crate::core::config::Config;
use crate::core::macros::MergeRight;
use crate::core::merge_right::MergeRight;
Expand Down Expand Up @@ -53,6 +54,17 @@
ConfigModule { cache: Cache::from(config), extensions }
}

/// Identifies if an enterprise feature is being used
pub fn is_enterprise_features_enabled(&self) -> bool {
let js_capability_enabled = self
.config()
.links
.iter()
.any(|link| matches!(link.type_of, LinkType::Script));
let telemetry_capability_enabled = self.config().telemetry.is_enabled();
js_capability_enabled || telemetry_capability_enabled
}

Check warning on line 66 in src/core/config/config_module.rs

View check run for this annotation

Codecov / codecov/patch

src/core/config/config_module.rs#L58-L66

Added lines #L58 - L66 were not covered by tests

pub fn set_extensions(mut self, extensions: Extensions) -> Self {
self.extensions = extensions;
self
Expand Down
4 changes: 4 additions & 0 deletions src/core/config/directives/telemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@
}

impl Telemetry {
pub fn is_enabled(&self) -> bool {
self.export.is_some()
}

Check warning on line 102 in src/core/config/directives/telemetry.rs

View check run for this annotation

Codecov / codecov/patch

src/core/config/directives/telemetry.rs#L100-L102

Added lines #L100 - L102 were not covered by tests

pub fn merge_right(mut self, other: Self) -> Self {
self.export = match (&self.export, other.export) {
(None, None) => None,
Expand Down
13 changes: 13 additions & 0 deletions tailcall-enterprise/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "tailcall-enterprise"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = { workspace = true }
reqwest = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
postgrest = "1.6.0"
keygen-rs = "0.3.1"
123 changes: 123 additions & 0 deletions tailcall-enterprise/src/enterprise.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#![allow(dead_code)]
use std::env;

use keygen_rs::config::KeygenConfig;
use keygen_rs::errors::Error;
use postgrest::Postgrest;
use serde::Deserialize;
use thiserror::Error;

const TOKEN_NAME: &str = "TAILCALL_TOKEN";

// Supabase configurations
const TABLE_NAME: &str = "---Add-Table-Name-Here---";
const ANON_KEY: &str = "---Add-Anonymous-Key-Here---";
const API_URL: &str = "---Add-Api-Url-Here---";

#[derive(Error, Debug)]
pub enum EnterpriseError {
#[error("TAILCALL_TOKEN is not provided. Please connect via https://tailcall.run/contact/ if you haven't already got a token.")]
TokenNotProvided,
#[error("Failed to fetch public key: {0}")]
PublicKeyFetchError(String),
#[error("Failed to parse public key: {0}")]
PublicKeyParsingError(String),
#[error(transparent)]
KeygenError(#[from] Box<Error>),
#[error(transparent)]
DatabaseClientError(#[from] reqwest::Error),
}

#[derive(Debug)]
pub struct Enterprise {
license_key: Option<String>,
config: Option<KeygenConfig>,
}

#[derive(Deserialize, Debug)]

Check warning on line 37 in tailcall-enterprise/src/enterprise.rs

View check run for this annotation

Codecov / codecov/patch

tailcall-enterprise/src/enterprise.rs#L37

Added line #L37 was not covered by tests
struct KeygenData {
public_key: String,
account: String,
product: String,
api_url: String,
api_version: String,
api_prefix: String,
}

impl From<KeygenData> for KeygenConfig {
fn from(data: KeygenData) -> Self {
KeygenConfig {
public_key: Some(data.public_key),
account: data.account,
product: data.product,
api_url: data.api_url,
api_version: data.api_version,
api_prefix: data.api_prefix,
..Default::default()
}
}

Check warning on line 58 in tailcall-enterprise/src/enterprise.rs

View check run for this annotation

Codecov / codecov/patch

tailcall-enterprise/src/enterprise.rs#L48-L58

Added lines #L48 - L58 were not covered by tests
}

impl Enterprise {
pub fn is_validated(&self) -> bool {
self.config.is_some() && self.license_key.is_some()
}

Check warning on line 64 in tailcall-enterprise/src/enterprise.rs

View check run for this annotation

Codecov / codecov/patch

tailcall-enterprise/src/enterprise.rs#L62-L64

Added lines #L62 - L64 were not covered by tests

pub async fn try_new() -> Result<Self, EnterpriseError> {
match env::var(TOKEN_NAME) {
Ok(signed_key) => {
let keygen_data = Self::fetch_public_key().await?;
let mut config: KeygenConfig = keygen_data.into();
config.license_key = Some(signed_key.clone());
keygen_rs::config::set_config(config);
let _signed_key_result =
keygen_rs::verify(keygen_rs::license::SchemeCode::Ed25519Sign, &signed_key)
.map_err(|e| match e {
Error::LicenseKeyMissing => EnterpriseError::TokenNotProvided,
_ => EnterpriseError::KeygenError(Box::new(e)),
})?;
Ok(Self {
license_key: Some(signed_key),
config: Some(keygen_rs::config::get_config()),
})

Check warning on line 82 in tailcall-enterprise/src/enterprise.rs

View check run for this annotation

Codecov / codecov/patch

tailcall-enterprise/src/enterprise.rs#L68-L82

Added lines #L68 - L82 were not covered by tests
}
Err(_) => Err(EnterpriseError::TokenNotProvided),
}
}

async fn fetch_public_key() -> Result<KeygenData, EnterpriseError> {
let client = Postgrest::new(API_URL).insert_header("apiKey", ANON_KEY);

Check warning on line 89 in tailcall-enterprise/src/enterprise.rs

View check run for this annotation

Codecov / codecov/patch

tailcall-enterprise/src/enterprise.rs#L88-L89

Added lines #L88 - L89 were not covered by tests
// pick the latest key from the database.
let result = client
.from(TABLE_NAME)
.select("*")
.order("id.desc")
.limit(1)
.single()
.execute()
.await?;
let body = result.json::<KeygenData>().await?;
Ok(body)
}

Check warning on line 101 in tailcall-enterprise/src/enterprise.rs

View check run for this annotation

Codecov / codecov/patch

tailcall-enterprise/src/enterprise.rs#L91-L101

Added lines #L91 - L101 were not covered by tests
}

#[cfg(test)]
mod tests {
use std::env;

use super::*;

#[tokio::test]
async fn test_no_token_provided() {
env::remove_var(TOKEN_NAME);
let result = Enterprise::try_new().await;
assert!(result.is_err());
}

#[tokio::test]
async fn test_invalid_token() {
env::set_var(TOKEN_NAME, "invalid-token");
let result = Enterprise::try_new().await;
assert!(result.is_err());
}
}
3 changes: 3 additions & 0 deletions tailcall-enterprise/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod enterprise;

pub use enterprise::Enterprise;
Loading