diff --git a/.github/workflows/backend-check.yml b/.github/workflows/backend-check.yml index 901a30cca6..7fc0874564 100644 --- a/.github/workflows/backend-check.yml +++ b/.github/workflows/backend-check.yml @@ -53,7 +53,7 @@ jobs: timeout-minutes: 16 run: | mkdir -p fake_frontend_build - FRONTEND_BUILD_DIR=$(pwd)/fake_frontend_build SQLX_OFFLINE=true cargo check --all-features + FRONTEND_BUILD_DIR=$(pwd)/fake_frontend_build SQLX_OFFLINE=true cargo check --features $(./all_features_oss.sh) check_ee: runs-on: ubicloud-standard-8 diff --git a/backend/.gitignore b/backend/.gitignore index f75b9d1eaa..2a3262acac 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -6,4 +6,5 @@ tracing.folded heaptrack* index/ windmill-api/openapi-*.* -.duckdb/* \ No newline at end of file +.duckdb/* +*ee.rs \ No newline at end of file diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 65c1fa0ec3..b0c85285ad 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -49,6 +49,7 @@ lto = "thin" [features] default = [] +private = ["windmill-api/private", "windmill-autoscaling/private", "windmill-common/private", "windmill-git-sync/private", "windmill-indexer/private", "windmill-queue/private", "windmill-worker/private"] agent_worker_server = ["windmill-api/agent_worker_server"] enterprise = ["windmill-worker/enterprise", "windmill-queue/enterprise", "windmill-api/enterprise", "dep:windmill-autoscaling", "windmill-autoscaling/enterprise", "windmill-git-sync/enterprise", "windmill-common/prometheus", "windmill-common/enterprise"] enterprise_saml = ["windmill-api/enterprise_saml", "oauth2"] @@ -94,7 +95,7 @@ php = ["windmill-worker/php"] csharp = ["windmill-worker/csharp"] nu = ["windmill-worker/nu"] java = ["windmill-worker/java"] -all_languages = [ "python", "deno_core", "rust", "mysql", "oracledb", "duckdb", "mssql", "bigquery", "csharp", "nu", "php", "java"] +all_languages = ["python", "deno_core", "rust", "mysql", "oracledb", "duckdb", "mssql", "bigquery", "csharp", "nu", "php", "java"] [patch.crates-io] diff --git a/backend/all_features_oss.sh b/backend/all_features_oss.sh new file mode 100755 index 0000000000..5871bc656f --- /dev/null +++ b/backend/all_features_oss.sh @@ -0,0 +1,20 @@ +# This script outputs all features except private. Usage : +# > cargo build --features $(./all_features_oss.sh) + +#!/bin/bash + +# Path to the Cargo.toml file +CARGO_TOML_PATH="./Cargo.toml" + +# Extract features from Cargo.toml and output them separated by commas +if [[ -f "$CARGO_TOML_PATH" ]]; then + grep -A 100 '\[features\]' "$CARGO_TOML_PATH" | \ + sed -n '/\[features\]/,/^\[/p' | \ + grep -E '^[a-zA-Z0-9_-]+' | \ + grep -v 'private' | \ + cut -d' ' -f1 | \ + paste -sd ',' - +else + echo "Cargo.toml not found at $CARGO_TOML_PATH" + exit 1 +fi \ No newline at end of file diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index d5d998a701..fcf0d6deac 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -8a2506e86b923c00522cb83b052586f705f7aa8e +70895a4a8f8891032c5b478a37ab6fafd0d4a9d0 \ No newline at end of file diff --git a/backend/src/ee.rs b/backend/src/ee_oss.rs similarity index 53% rename from backend/src/ee.rs rename to backend/src/ee_oss.rs index 91816cd1ba..4791a243a3 100644 --- a/backend/src/ee.rs +++ b/backend/src/ee_oss.rs @@ -1,8 +1,13 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::ee::*; + +#[cfg(not(feature = "private"))] pub async fn set_license_key(_license_key: String) -> () { // Implementation is not open source } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub async fn verify_license_key() -> () { // Implementation is not open source } diff --git a/backend/src/main.rs b/backend/src/main.rs index a4148d93c6..aa1b67f081 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -28,7 +28,9 @@ use uuid::Uuid; use windmill_api::HTTP_CLIENT; #[cfg(feature = "enterprise")] -use windmill_common::ee::{maybe_renew_license_key_on_start, LICENSE_KEY_ID, LICENSE_KEY_VALID}; +use windmill_common::ee_oss::{ + maybe_renew_license_key_on_start, LICENSE_KEY_ID, LICENSE_KEY_VALID, +}; use windmill_common::{ agent_workers::build_agent_http_client, @@ -49,7 +51,7 @@ use windmill_common::{ TIMEOUT_WAIT_RESULT_SETTING, }, scripts::ScriptLang, - stats_ee::schedule_stats, + stats_oss::schedule_stats, triggers::TriggerKind, utils::{hostname, rd_string, Mode, GIT_VERSION, MODE_AND_ADDONS}, worker::{ @@ -98,7 +100,9 @@ const DEFAULT_NUM_WORKERS: usize = 1; const DEFAULT_PORT: u16 = 8000; const DEFAULT_SERVER_BIND_ADDR: Ipv4Addr = Ipv4Addr::new(0, 0, 0, 0); -mod ee; +#[cfg(feature = "private")] +pub mod ee; +mod ee_oss; mod monitor; pub fn setup_deno_runtime() -> anyhow::Result<()> { @@ -552,7 +556,7 @@ Windmill Community Edition {GIT_VERSION} _ = indexer_rx.recv() => { tracing::info!("Received killpill, aborting index initialization"); }, - res = windmill_indexer::completed_runs_ee::init_index(&db) => { + res = windmill_indexer::completed_runs_oss::init_index(&db) => { let res = res?; reader = Some(res.0); writer = Some(res.1); @@ -574,7 +578,7 @@ Windmill Community Edition {GIT_VERSION} async { if let Some(db) = conn.as_sql() { if let Some(index_writer) = index_writer2 { - windmill_indexer::completed_runs_ee::run_indexer( + windmill_indexer::completed_runs_oss::run_indexer( db.clone(), index_writer, indexer_rx, @@ -596,7 +600,7 @@ Windmill Community Edition {GIT_VERSION} _ = indexer_rx.recv() => { tracing::info!("Received killpill, aborting index initialization"); }, - res = windmill_indexer::service_logs_ee::init_index(&db, killpill_tx.clone()) => { + res = windmill_indexer::service_logs_oss::init_index(&db, killpill_tx.clone()) => { let res = res?; reader = Some(res.0); writer = Some(res.1); @@ -618,7 +622,7 @@ Windmill Community Edition {GIT_VERSION} async { if let Some(db) = conn.as_sql() { if let Some(log_index_writer) = log_index_writer2 { - windmill_indexer::service_logs_ee::run_indexer( + windmill_indexer::service_logs_oss::run_indexer( db.clone(), log_index_writer, log_indexer_rx, @@ -1086,7 +1090,7 @@ Windmill Community Edition {GIT_VERSION} tracing::info!("Reloading config after 12 hours"); initial_load(&conn, tx.clone(), worker_mode, server_mode, #[cfg(feature = "parquet")] disable_s3_store).await; #[cfg(feature = "enterprise")] - ee::verify_license_key().await; + ee_oss::verify_license_key().await; } } }, diff --git a/backend/src/monitor.rs b/backend/src/monitor.rs index d2a5657c6c..7d7f064f3d 100644 --- a/backend/src/monitor.rs +++ b/backend/src/monitor.rs @@ -29,9 +29,9 @@ use windmill_api::{ }; #[cfg(feature = "enterprise")] -use windmill_common::ee::low_disk_alerts; +use windmill_common::ee_oss::low_disk_alerts; #[cfg(feature = "enterprise")] -use windmill_common::ee::{jobs_waiting_alerts, worker_groups_alerts}; +use windmill_common::ee_oss::{jobs_waiting_alerts, worker_groups_alerts}; use windmill_common::client::AuthedClient; #[cfg(feature = "oauth2")] @@ -41,7 +41,7 @@ use windmill_common::s3_helpers::reload_object_store_setting; use windmill_common::{ agent_workers::DECODED_AGENT_TOKEN, auth::create_token_for_owner, - ee::CriticalErrorChannel, + ee_oss::CriticalErrorChannel, error, flow_status::{FlowStatus, FlowStatusModule}, global_settings::{ @@ -87,9 +87,9 @@ use windmill_worker::{ use windmill_common::s3_helpers::ObjectStoreReload; #[cfg(feature = "enterprise")] -use crate::ee::verify_license_key; +use crate::ee_oss::verify_license_key; -use crate::ee::set_license_key; +use crate::ee_oss::set_license_key; #[cfg(feature = "prometheus")] lazy_static::lazy_static! { @@ -1609,7 +1609,7 @@ pub async fn reload_base_url_setting(conn: &Connection) -> error::Result<()> { if let Some(q) = q_oauth { if let Ok(v) = serde_json::from_value::< - Option>, + Option>, >(q.clone()) { v @@ -1630,7 +1630,7 @@ pub async fn reload_base_url_setting(conn: &Connection) -> error::Result<()> { { if let Some(db) = conn.as_sql() { let mut l = windmill_api::OAUTH_CLIENTS.write().await; - *l = windmill_api::oauth2_ee::build_oauth_clients(&base_url, oauths, db).await + *l = windmill_api::oauth2_oss::build_oauth_clients(&base_url, oauths, db).await .map_err(|e| tracing::error!("Error building oauth clients (is the oauth.json mounted and in correct format? Use '{}' as minimal oauth.json): {}", "{}", e)) .unwrap(); } diff --git a/backend/substitute_ee_code.sh b/backend/substitute_ee_code.sh index 28b890990b..356098fc98 100755 --- a/backend/substitute_ee_code.sh +++ b/backend/substitute_ee_code.sh @@ -4,7 +4,6 @@ script_dirpath="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root_dirpath="$(cd "${script_dirpath}/.." && pwd)" REVERT="NO" -REVERT_PREVIOUS="NO" COPY="NO" EE_CODE_DIR="../windmill-ee-private/" @@ -18,13 +17,6 @@ while [[ $# -gt 0 ]]; do REVERT="YES" shift ;; - --revert-previous) - # This is a special case of --revert that will revert to the previous commit. - REVERT="YES" - REVERT_PREVIOUS="YES" - echo "Reverting to previous commit" - shift - ;; -c|--copy) # By default, EE files are symlinked. Pass this option to do a real copy instead. # This might be necessary if you want to build the Docker Image as Docker COPY seems @@ -70,29 +62,19 @@ if [ "$REVERT" == "YES" ]; then for ee_file in $(find ${EE_CODE_DIR} -name "*ee.rs"); do ce_file="${ee_file/${EE_CODE_DIR}/}" ce_file="${root_dirpath}/backend/${ce_file}" - if [ "$REVERT_PREVIOUS" == "YES" ]; then - git checkout HEAD@{3} ${ce_file} || true - else - git restore --staged ${ce_file} || true - git restore ${ce_file} || true - fi + rm ${ce_file} done else # This replaces all files in current repo with alternative EE files in windmill-ee-private for ee_file in $(find "${EE_CODE_DIR}" -name "*ee.rs"); do - ce_file="${ee_file/${EE_CODE_DIR}/}" - ce_file="${root_dirpath}/backend/${ce_file}" - if [[ -f "${ce_file}" ]]; then - rm "${ce_file}" - if [ "$COPY" == "YES" ]; then - cp "${ee_file}" "${ce_file}" - echo "File copied '${ee_file}' -->> '${ce_file}'" - else - ln -s "${ee_file}" "${ce_file}" - echo "Symlink created '${ee_file}' -->> '${ce_file}'" - fi + ce_file="${ee_file/${EE_CODE_DIR}/}" + ce_file="${root_dirpath}/backend/${ce_file}" + if [ "$COPY" == "YES" ]; then + cp "${ee_file}" "${ce_file}" + echo "File copied '${ee_file}' -->> '${ce_file}'" else - echo "File ${ce_file} is not a file, ignoring" + ln -s "${ee_file}" "${ce_file}" + echo "Symlink created '${ee_file}' -->> '${ce_file}'" fi done fi diff --git a/backend/update_sqlx.sh b/backend/update_sqlx.sh index 11b5196ad8..24c7a57bcf 100755 --- a/backend/update_sqlx.sh +++ b/backend/update_sqlx.sh @@ -9,7 +9,7 @@ if [[ "$(uname)" == "Darwin" ]]; then sed -i '' 's/^# \(samael = { git="https:\/\/github.com\/njaremko\/samael", rev="464d015e3ae393e4b5dd00b4d6baa1b617de0dd6", features = \["xmlsec"\] }\)/\1/' Cargo.toml fi -cargo sqlx prepare --workspace -- --all-targets --all-features +cargo sqlx prepare --workspace -- --all-targets --features $(./all_features_oss.sh) ./substitute_ee_code.sh -r --dir ../windmill-ee-private # Undo the samael changes on macOS diff --git a/backend/windmill-api/Cargo.toml b/backend/windmill-api/Cargo.toml index 9f6de0c5ca..cfb175cb0f 100644 --- a/backend/windmill-api/Cargo.toml +++ b/backend/windmill-api/Cargo.toml @@ -10,6 +10,7 @@ path = "src/lib.rs" [features] default = [] +private = ["windmill-audit/private"] enterprise = ["windmill-queue/enterprise", "windmill-audit/enterprise", "windmill-git-sync/enterprise", "windmill-common/enterprise", "windmill-worker/enterprise"] stripe = [] agent_worker_server = [] diff --git a/backend/windmill-api/src/agent_workers_ee.rs b/backend/windmill-api/src/agent_workers_oss.rs similarity index 76% rename from backend/windmill-api/src/agent_workers_ee.rs rename to backend/windmill-api/src/agent_workers_oss.rs index 1b5a210d13..655058c493 100644 --- a/backend/windmill-api/src/agent_workers_ee.rs +++ b/backend/windmill-api/src/agent_workers_oss.rs @@ -1,3 +1,7 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::agent_workers_ee::*; + /* * Author: Ruben Fiszel * Copyright: Windmill Labs, Inc 2042 @@ -6,16 +10,21 @@ * LICENSE-AGPL for a copy of the license. */ +#[cfg(not(feature = "private"))] use crate::db::DB; +#[cfg(not(feature = "private"))] use axum::Router; +#[cfg(not(feature = "private"))] use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "private"))] pub fn global_service() -> Router { Router::new() } +#[cfg(not(feature = "private"))] pub fn workspaced_service( db: DB, _base_internal_url: String, @@ -36,6 +45,7 @@ pub fn workspaced_service( } #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg(not(feature = "private"))] pub struct AgentAuth { pub worker_group: String, pub suffix: Option, @@ -43,8 +53,10 @@ pub struct AgentAuth { pub exp: Option, } +#[cfg(not(feature = "private"))] pub struct AgentCache {} +#[cfg(not(feature = "private"))] impl AgentCache { pub fn new() -> Self { AgentCache {} diff --git a/backend/windmill-api/src/ai.rs b/backend/windmill-api/src/ai.rs index 6b33a70730..86e69fe233 100644 --- a/backend/windmill-api/src/ai.rs +++ b/backend/windmill-api/src/ai.rs @@ -10,7 +10,7 @@ use reqwest::{Client, RequestBuilder}; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue; use std::collections::HashMap; -use windmill_audit::{audit_ee::audit_log, ActionKind}; +use windmill_audit::{audit_oss::audit_log, ActionKind}; use windmill_common::error::{to_anyhow, Error, Result}; lazy_static::lazy_static! { diff --git a/backend/windmill-api/src/apps.rs b/backend/windmill-api/src/apps.rs index 533da11d1c..9dfe40b5b9 100644 --- a/backend/windmill-api/src/apps.rs +++ b/backend/windmill-api/src/apps.rs @@ -18,7 +18,7 @@ use crate::{ }; #[cfg(feature = "parquet")] use crate::{ - job_helpers_ee::{ + job_helpers_oss::{ download_s3_file_internal, get_random_file_name, get_s3_resource, get_workspace_s3_resource, upload_file_from_req, DownloadFileQuery, }, @@ -48,7 +48,7 @@ use sha2::{Digest, Sha256}; use sql_builder::{bind::Bind, SqlBuilder}; use sqlx::{types::Uuid, FromRow}; use std::str; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::{ apps::{AppScriptId, ListAppQuery}, diff --git a/backend/windmill-api/src/apps_ee.rs b/backend/windmill-api/src/apps_ee.rs deleted file mode 100644 index a7737664b9..0000000000 --- a/backend/windmill-api/src/apps_ee.rs +++ /dev/null @@ -1,5 +0,0 @@ -use axum::Router; - -pub fn global_unauthed_service() -> Router { - Router::new() -} diff --git a/backend/windmill-api/src/apps_oss.rs b/backend/windmill-api/src/apps_oss.rs new file mode 100644 index 0000000000..346fff9ff1 --- /dev/null +++ b/backend/windmill-api/src/apps_oss.rs @@ -0,0 +1,11 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::apps_ee::*; + +#[cfg(not(feature = "private"))] +use axum::Router; + +#[cfg(not(feature = "private"))] +pub fn global_unauthed_service() -> Router { + Router::new() +} diff --git a/backend/windmill-api/src/args.rs b/backend/windmill-api/src/args.rs index e3a2adb38f..0b8f4d5210 100644 --- a/backend/windmill-api/src/args.rs +++ b/backend/windmill-api/src/args.rs @@ -85,7 +85,7 @@ impl RawWebhookArgs { db: &DB, w_id: &str, ) -> Result>, Error> { - use crate::job_helpers_ee::{ + use crate::job_helpers_oss::{ get_random_file_name, get_workspace_s3_resource, upload_file_internal, }; use futures::TryStreamExt; diff --git a/backend/windmill-api/src/audit.rs b/backend/windmill-api/src/audit.rs index 47ba881014..336fd32881 100644 --- a/backend/windmill-api/src/audit.rs +++ b/backend/windmill-api/src/audit.rs @@ -28,7 +28,7 @@ async fn get_audit( Path((w_id, id)): Path<(String, i32)>, ) -> JsonResult { let tx = user_db.begin(&authed).await?; - let audit = windmill_audit::audit_ee::get_audit(tx, id, &w_id).await?; + let audit = windmill_audit::audit_oss::get_audit(tx, id, &w_id).await?; Ok(Json(audit)) } async fn list_audit( @@ -39,6 +39,6 @@ async fn list_audit( Query(lq): Query, ) -> JsonResult> { let tx = user_db.begin(&authed).await?; - let rows = windmill_audit::audit_ee::list_audit(tx, w_id, pagination, lq).await?; + let rows = windmill_audit::audit_oss::list_audit(tx, w_id, pagination, lq).await?; Ok(Json(rows)) } diff --git a/backend/windmill-api/src/auth.rs b/backend/windmill-api/src/auth.rs index 2936b74957..25dc0efd4a 100644 --- a/backend/windmill-api/src/auth.rs +++ b/backend/windmill-api/src/auth.rs @@ -1,5 +1,5 @@ #[cfg(feature = "enterprise")] -use crate::ee::ExternalJwks; +use crate::ee_oss::ExternalJwks; use axum::{ async_trait, extract::{FromRequestParts, OriginalUri, Query}, @@ -71,7 +71,7 @@ impl AuthCache { } #[cfg(feature = "enterprise")] _ if token.starts_with("jwt_ext_") => { - let authed_and_exp = match crate::ee::jwt_ext_auth( + let authed_and_exp = match crate::ee_oss::jwt_ext_auth( w_id.as_ref(), token.trim_start_matches("jwt_ext_"), self.ext_jwks.clone(), diff --git a/backend/windmill-api/src/capture.rs b/backend/windmill-api/src/capture.rs index 3164ebe43f..e86ee2fd28 100644 --- a/backend/windmill-api/src/capture.rs +++ b/backend/windmill-api/src/capture.rs @@ -15,7 +15,7 @@ use { #[cfg(all(feature = "enterprise", feature = "gcp_trigger"))] use { - crate::gcp_triggers_ee::{ + crate::gcp_triggers_oss::{ manage_google_subscription, process_google_push_request, validate_jwt_token, CreateUpdateConfig, SubscriptionMode, }, @@ -46,13 +46,13 @@ use serde::de::DeserializeOwned; use windmill_common::error::Error; #[cfg(all(feature = "enterprise", feature = "kafka"))] -use crate::kafka_triggers_ee::KafkaTriggerConfigConnection; +use crate::kafka_triggers_oss::KafkaTriggerConfigConnection; #[cfg(feature = "mqtt_trigger")] use crate::mqtt_triggers::{MqttClientVersion, MqttV3Config, MqttV5Config, SubscribeTopic}; #[cfg(all(feature = "enterprise", feature = "nats"))] -use crate::nats_triggers_ee::NatsTriggerConfigConnection; +use crate::nats_triggers_oss::NatsTriggerConfigConnection; #[cfg(feature = "postgres_trigger")] use { @@ -905,7 +905,7 @@ async fn gcp_payload( headers: HeaderMap, request: Request, ) -> Result { - use crate::{gcp_triggers_ee::GcpTrigger, trigger_helpers::TriggerJobArgs}; + use crate::{gcp_triggers_oss::GcpTrigger, trigger_helpers::TriggerJobArgs}; let is_flow = matches!(runnable_kind, RunnableKind::Flow); let (gcp_trigger_config, owner, email): (GcpTriggerConfig, _, _) = diff --git a/backend/windmill-api/src/configs.rs b/backend/windmill-api/src/configs.rs index e8770b2b5e..9110d104c8 100644 --- a/backend/windmill-api/src/configs.rs +++ b/backend/windmill-api/src/configs.rs @@ -14,7 +14,7 @@ use axum::{ use serde::{Deserialize, Serialize}; use sqlx::FromRow; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::{ error::{self}, diff --git a/backend/windmill-api/src/db.rs b/backend/windmill-api/src/db.rs index 85f1ee485f..71afe9cb1f 100644 --- a/backend/windmill-api/src/db.rs +++ b/backend/windmill-api/src/db.rs @@ -16,7 +16,7 @@ use sqlx::{ }; use tokio::task::JoinHandle; -use windmill_audit::audit_ee::{AuditAuthor, AuditAuthorable}; +use windmill_audit::audit_oss::{AuditAuthor, AuditAuthorable}; use windmill_common::{ db::{Authable, Authed}, error::Error, diff --git a/backend/windmill-api/src/ee.rs b/backend/windmill-api/src/ee_oss.rs similarity index 61% rename from backend/windmill-api/src/ee.rs rename to backend/windmill-api/src/ee_oss.rs index cddb639e95..3fb1271a73 100644 --- a/backend/windmill-api/src/ee.rs +++ b/backend/windmill-api/src/ee_oss.rs @@ -1,15 +1,21 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::ee::*; + +#[cfg(not(feature = "private"))] use anyhow::anyhow; -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] use std::sync::Arc; -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] use tokio::sync::RwLock; +#[cfg(not(feature = "private"))] pub async fn validate_license_key(_license_key: String) -> anyhow::Result<(String, bool)> { // Implementation is not open source Err(anyhow!("License can't be validated in Windmill CE")) } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub async fn jwt_ext_auth( _w_id: Option<&String>, _token: &str, @@ -20,10 +26,10 @@ pub async fn jwt_ext_auth( Err(anyhow!("External JWT auth is not open source")) } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub struct ExternalJwks; -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] impl ExternalJwks { pub async fn load() -> Option>> { // Implementation is not open source diff --git a/backend/windmill-api/src/flows.rs b/backend/windmill-api/src/flows.rs index e34b2cacaf..505656da47 100644 --- a/backend/windmill-api/src/flows.rs +++ b/backend/windmill-api/src/flows.rs @@ -31,7 +31,7 @@ use hyper::StatusCode; use serde::{Deserialize, Serialize}; use sql_builder::prelude::*; use sqlx::{FromRow, Postgres, Transaction}; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::utils::query_elems_from_hub; use windmill_common::worker::to_raw_value; diff --git a/backend/windmill-api/src/folders.rs b/backend/windmill-api/src/folders.rs index 5047a96cad..1e4d2e09c0 100644 --- a/backend/windmill-api/src/folders.rs +++ b/backend/windmill-api/src/folders.rs @@ -23,7 +23,7 @@ use axum::{ }; use lazy_static::lazy_static; use regex::Regex; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::{ db::UserDB, diff --git a/backend/windmill-api/src/gcp_triggers_ee.rs b/backend/windmill-api/src/gcp_triggers_oss.rs similarity index 76% rename from backend/windmill-api/src/gcp_triggers_ee.rs rename to backend/windmill-api/src/gcp_triggers_oss.rs index 0dc672580c..78005309bc 100644 --- a/backend/windmill-api/src/gcp_triggers_ee.rs +++ b/backend/windmill-api/src/gcp_triggers_oss.rs @@ -1,29 +1,38 @@ -use crate::db::{ApiAuthed, DB}; -use crate::trigger_helpers::TriggerJobArgs; -use axum::{extract::Request, Router}; -use http::HeaderMap; -use serde::{Deserialize, Serialize}; -use serde_json::value::RawValue; -use sqlx::prelude::FromRow; -use sqlx::types::Json as SqlxJson; -use std::collections::HashMap; -use windmill_common::db::UserDB; -use windmill_common::worker::to_raw_value; -use windmill_common::{ - error::{Error as WindmillError, Result as WindmillResult}, - triggers::TriggerKind, - utils::empty_as_none, +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::gcp_triggers_ee::*; + +#[cfg(not(feature = "private"))] +use { + crate::db::{ApiAuthed, DB}, + crate::trigger_helpers::TriggerJobArgs, + axum::{extract::Request, Router}, + http::HeaderMap, + serde::{Deserialize, Serialize}, + serde_json::value::RawValue, + sqlx::prelude::FromRow, + sqlx::types::Json as SqlxJson, + std::collections::HashMap, + windmill_common::db::UserDB, + windmill_common::worker::to_raw_value, + windmill_common::{ + error::{Error as WindmillError, Result as WindmillResult}, + triggers::TriggerKind, + utils::empty_as_none, + }, }; #[derive(sqlx::Type, Debug, Deserialize, Serialize)] #[serde(rename_all(serialize = "lowercase", deserialize = "lowercase"))] #[sqlx(type_name = "DELIVERY_MODE", rename_all = "lowercase")] #[allow(unused)] +#[cfg(not(feature = "private"))] pub enum DeliveryType { Pull, Push, } +#[cfg(not(feature = "private"))] impl Default for DeliveryType { fn default() -> Self { Self::Pull @@ -32,6 +41,7 @@ impl Default for DeliveryType { #[derive(FromRow, Deserialize, Serialize, Debug)] #[allow(unused)] +#[cfg(not(feature = "private"))] pub struct PushConfig { #[serde(deserialize_with = "empty_as_none")] route_path: Option, @@ -42,6 +52,7 @@ pub struct PushConfig { } #[derive(Default, Debug, Serialize, Deserialize)] #[allow(unused)] +#[cfg(not(feature = "private"))] pub struct CreateUpdateConfig { pub delivery_type: DeliveryType, #[serde(default, deserialize_with = "empty_as_none")] @@ -50,6 +61,7 @@ pub struct CreateUpdateConfig { } #[derive(Debug, Deserialize, Serialize)] +#[cfg(not(feature = "private"))] pub struct ExistingGcpSubscription { pub subscription_id: String, pub base_endpoint: String, @@ -58,15 +70,18 @@ pub struct ExistingGcpSubscription { #[derive(Debug, Deserialize, Serialize, sqlx::Type)] #[serde(rename_all = "snake_case")] #[sqlx(type_name = "GCP_SUBSCRIPTION_MODE", rename_all = "snake_case")] +#[cfg(not(feature = "private"))] pub enum SubscriptionMode { Existing, CreateUpdate, } +#[cfg(not(feature = "private"))] pub fn workspaced_service() -> Router { Router::new() } +#[cfg(not(feature = "private"))] pub fn start_consuming_gcp_pubsub_event( _db: DB, mut _killpill_rx: tokio::sync::broadcast::Receiver<()>, @@ -74,6 +89,7 @@ pub fn start_consuming_gcp_pubsub_event( // implementation is not open source } +#[cfg(not(feature = "private"))] pub async fn manage_google_subscription( _authed: ApiAuthed, _db: &DB, @@ -91,6 +107,7 @@ pub async fn manage_google_subscription( Ok(CreateUpdateConfig::default()) } +#[cfg(not(feature = "private"))] pub async fn process_google_push_request( _headers: HeaderMap, _request: Request, @@ -98,6 +115,7 @@ pub async fn process_google_push_request( Ok((String::new(), HashMap::new())) } +#[cfg(not(feature = "private"))] pub async fn validate_jwt_token( _db: &DB, _user_db: UserDB, @@ -110,11 +128,13 @@ pub async fn validate_jwt_token( Ok(()) } +#[cfg(not(feature = "private"))] pub fn gcp_push_route_handler() -> Router { Router::new() } #[derive(FromRow, Deserialize, Serialize, Debug)] +#[cfg(not(feature = "private"))] pub struct GcpTrigger { pub gcp_resource_path: String, pub subscription_id: String, @@ -135,7 +155,7 @@ pub struct GcpTrigger { pub last_server_ping: Option>, pub enabled: bool, } - +#[cfg(not(feature = "private"))] impl TriggerJobArgs for GcpTrigger { fn v1_payload_fn(payload: String) -> HashMap> { HashMap::from([("payload".to_string(), to_raw_value(&payload))]) diff --git a/backend/windmill-api/src/git_sync_ee.rs b/backend/windmill-api/src/git_sync_ee.rs deleted file mode 100644 index b72afac189..0000000000 --- a/backend/windmill-api/src/git_sync_ee.rs +++ /dev/null @@ -1,9 +0,0 @@ -use axum::routing::Router; - -pub fn workspaced_service() -> Router { - Router::new() -} - -pub fn global_service() -> Router { - Router::new() -} \ No newline at end of file diff --git a/backend/windmill-api/src/git_sync_oss.rs b/backend/windmill-api/src/git_sync_oss.rs new file mode 100644 index 0000000000..0451d88699 --- /dev/null +++ b/backend/windmill-api/src/git_sync_oss.rs @@ -0,0 +1,16 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::git_sync_ee::*; + +#[cfg(not(feature = "private"))] +use axum::routing::Router; + +#[cfg(not(feature = "private"))] +pub fn workspaced_service() -> Router { + Router::new() +} + +#[cfg(not(feature = "private"))] +pub fn global_service() -> Router { + Router::new() +} diff --git a/backend/windmill-api/src/groups.rs b/backend/windmill-api/src/groups.rs index e25d3ee7da..d5da9c25f5 100644 --- a/backend/windmill-api/src/groups.rs +++ b/backend/windmill-api/src/groups.rs @@ -14,7 +14,7 @@ use axum::{ routing::{delete, get, post}, Json, Router, }; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::worker::CLOUD_HOSTED; use windmill_common::{ diff --git a/backend/windmill-api/src/http_triggers.rs b/backend/windmill-api/src/http_triggers.rs index b17c8205ad..b75f8a6ce8 100644 --- a/backend/windmill-api/src/http_triggers.rs +++ b/backend/windmill-api/src/http_triggers.rs @@ -1,7 +1,7 @@ #[cfg(feature = "http_trigger")] use crate::http_trigger_args::{HttpMethod, RawHttpTriggerArgs}; #[cfg(feature = "parquet")] -use crate::job_helpers_ee::get_workspace_s3_resource; +use crate::job_helpers_oss::get_workspace_s3_resource; use crate::resources::try_get_resource_from_db_as; use crate::trigger_helpers::{get_runnable_format, RunnableId}; use crate::utils::{non_empty_str, ExpiringCacheEntry}; @@ -33,7 +33,7 @@ use std::borrow::Cow; use std::{collections::HashMap, sync::Arc}; use tokio::sync::{RwLock, RwLockReadGuard}; use tower_http::cors::CorsLayer; -use windmill_audit::{audit_ee::audit_log, ActionKind}; +use windmill_audit::{audit_oss::audit_log, ActionKind}; use windmill_common::error::Error; #[cfg(feature = "parquet")] use windmill_common::s3_helpers::build_object_store_client; diff --git a/backend/windmill-api/src/indexer_ee.rs b/backend/windmill-api/src/indexer_ee.rs deleted file mode 100644 index 2ccca92c27..0000000000 --- a/backend/windmill-api/src/indexer_ee.rs +++ /dev/null @@ -1,9 +0,0 @@ -use axum::Router; - -pub fn workspaced_service() -> Router { - Router::new() -} - -pub fn global_service() -> Router { - Router::new() -} diff --git a/backend/windmill-api/src/indexer_oss.rs b/backend/windmill-api/src/indexer_oss.rs new file mode 100644 index 0000000000..eee87acdcb --- /dev/null +++ b/backend/windmill-api/src/indexer_oss.rs @@ -0,0 +1,16 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::indexer_ee::*; + +#[cfg(not(feature = "private"))] +use axum::Router; + +#[cfg(not(feature = "private"))] +pub fn workspaced_service() -> Router { + Router::new() +} + +#[cfg(not(feature = "private"))] +pub fn global_service() -> Router { + Router::new() +} diff --git a/backend/windmill-api/src/job_helpers_ee.rs b/backend/windmill-api/src/job_helpers_oss.rs similarity index 70% rename from backend/windmill-api/src/job_helpers_ee.rs rename to backend/windmill-api/src/job_helpers_oss.rs index 4e14d16c5f..53d4a796a1 100644 --- a/backend/windmill-api/src/job_helpers_ee.rs +++ b/backend/windmill-api/src/job_helpers_oss.rs @@ -1,34 +1,45 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::job_helpers_ee::*; + +#[cfg(not(feature = "private"))] use axum::Router; +#[cfg(not(feature = "private"))] use serde::Serialize; +#[cfg(not(feature = "private"))] use uuid::Uuid; +#[cfg(not(feature = "private"))] use windmill_common::s3_helpers::StorageResourceType; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] use crate::db::{ApiAuthed, DB}; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] use object_store::{ObjectStore, PutMultipartOpts}; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] use std::sync::Arc; +#[cfg(not(feature = "private"))] use windmill_common::error; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] use windmill_common::{db::UserDB, s3_helpers::ObjectStoreResource}; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] use bytes::Bytes; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] use futures::Stream; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] use axum::response::Response; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] use serde::Deserialize; #[derive(Serialize)] +#[cfg(not(feature = "private"))] pub struct UploadFileResponse { pub file_key: String, } #[derive(Deserialize)] +#[cfg(not(feature = "private"))] pub struct LoadImagePreviewQuery { #[allow(dead_code)] pub file_key: String, @@ -37,6 +48,7 @@ pub struct LoadImagePreviewQuery { } #[derive(Deserialize)] +#[cfg(not(feature = "private"))] pub struct DownloadFileQuery { #[allow(dead_code)] pub file_key: String, @@ -46,11 +58,12 @@ pub struct DownloadFileQuery { pub s3_resource_path: Option, } +#[cfg(not(feature = "private"))] pub fn workspaced_service() -> Router { Router::new() } -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] pub async fn get_workspace_s3_resource<'c>( _authed: &ApiAuthed, _db: &DB, @@ -63,10 +76,12 @@ pub async fn get_workspace_s3_resource<'c>( Ok((None, None)) } +#[cfg(not(feature = "private"))] pub fn get_random_file_name(_file_extension: Option) -> String { unimplemented!("Not implemented in Windmill's Open Source repository") } +#[cfg(not(feature = "private"))] pub async fn get_s3_resource<'c>( _authed: &ApiAuthed, _db: &DB, @@ -82,7 +97,7 @@ pub async fn get_s3_resource<'c>( )) } -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] pub async fn upload_file_from_req( _s3_client: Arc, _file_key: &str, @@ -94,7 +109,7 @@ pub async fn upload_file_from_req( )) } -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] pub async fn upload_file_internal( _s3_client: Arc, _file_key: &str, @@ -106,7 +121,7 @@ pub async fn upload_file_internal( )) } -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] pub async fn download_s3_file_internal( _authed: ApiAuthed, _db: &DB, diff --git a/backend/windmill-api/src/jobs.rs b/backend/windmill-api/src/jobs.rs index cf9e7d06de..5ac7348ef9 100644 --- a/backend/windmill-api/src/jobs.rs +++ b/backend/windmill-api/src/jobs.rs @@ -64,7 +64,7 @@ use sqlx::types::JsonRawValue; use sqlx::{types::Uuid, FromRow, Postgres, Transaction}; use tower_http::cors::{Any, CorsLayer}; use urlencoding::encode; -use windmill_audit::audit_ee::{audit_log, AuditAuthor}; +use windmill_audit::audit_oss::{audit_log, AuditAuthor}; use windmill_audit::ActionKind; use windmill_common::worker::{to_raw_value, CUSTOM_TAGS_PER_WORKSPACE}; use windmill_common::{ @@ -3183,7 +3183,7 @@ async fn check_tag_available_for_workspace( #[cfg(feature = "enterprise")] pub async fn check_license_key_valid() -> error::Result<()> { - use windmill_common::ee::LICENSE_KEY_VALID; + use windmill_common::ee_oss::LICENSE_KEY_VALID; let valid = *LICENSE_KEY_VALID.read().await; if !valid { diff --git a/backend/windmill-api/src/kafka_triggers_ee.rs b/backend/windmill-api/src/kafka_triggers_oss.rs similarity index 76% rename from backend/windmill-api/src/kafka_triggers_ee.rs rename to backend/windmill-api/src/kafka_triggers_oss.rs index 0a24151ae3..9d698e2fbf 100644 --- a/backend/windmill-api/src/kafka_triggers_ee.rs +++ b/backend/windmill-api/src/kafka_triggers_oss.rs @@ -1,14 +1,24 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::kafka_triggers_ee::*; + +#[cfg(not(feature = "private"))] use crate::db::DB; +#[cfg(not(feature = "private"))] use axum::Router; +#[cfg(not(feature = "private"))] use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] +#[cfg(not(feature = "private"))] pub struct KafkaResourceSecurity {} +#[cfg(not(feature = "private"))] pub fn workspaced_service() -> Router { Router::new() } +#[cfg(not(feature = "private"))] pub fn start_kafka_consumers( _db: DB, mut _killpill_rx: tokio::sync::broadcast::Receiver<()>, @@ -17,9 +27,11 @@ pub fn start_kafka_consumers( } #[derive(Serialize, Deserialize)] +#[cfg(not(feature = "private"))] pub enum KafkaTriggerConfigConnection {} #[derive(Serialize, Clone)] +#[cfg(not(feature = "private"))] pub struct KafkaTrigger { pub workspace_id: String, pub path: String, @@ -39,4 +51,4 @@ pub struct KafkaTrigger { #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, pub enabled: bool, -} \ No newline at end of file +} diff --git a/backend/windmill-api/src/lib.rs b/backend/windmill-api/src/lib.rs index d79639f0ab..366f4f8700 100644 --- a/backend/windmill-api/src/lib.rs +++ b/backend/windmill-api/src/lib.rs @@ -8,15 +8,15 @@ use crate::db::ApiAuthed; #[cfg(feature = "enterprise")] -use crate::ee::ExternalJwks; +use crate::ee_oss::ExternalJwks; #[cfg(feature = "embedding")] use crate::embeddings::load_embeddings_db; #[cfg(feature = "oauth2")] -use crate::oauth2_ee::AllClients; +use crate::oauth2_oss::AllClients; #[cfg(feature = "oauth2")] -use crate::oauth2_ee::SlackVerifier; +use crate::oauth2_oss::SlackVerifier; #[cfg(feature = "smtp")] -use crate::smtp_server_ee::SmtpServer; +use crate::smtp_server_oss::SmtpServer; #[cfg(feature = "mcp")] use crate::mcp::{setup_mcp_server, Runner as McpRunner}; @@ -28,7 +28,7 @@ use crate::{ }; #[cfg(feature = "agent_worker_server")] -use agent_workers_ee::AgentCache; +use agent_workers_oss::AgentCache; use anyhow::Context; use argon2::Argon2; @@ -58,11 +58,13 @@ use windmill_common::db::UserDB; use windmill_common::worker::CLOUD_HOSTED; use windmill_common::{utils::GIT_VERSION, BASE_URL, INSTANCE_NAME}; -use crate::scim_ee::has_scim_token; +use crate::scim_oss::has_scim_token; use windmill_common::error::AppError; +#[cfg(all(feature = "agent_worker_server", feature = "private"))] +pub mod agent_workers_ee; #[cfg(feature = "agent_worker_server")] -mod agent_workers_ee; +mod agent_workers_oss; mod ai; mod apps; pub mod args; @@ -73,7 +75,9 @@ mod concurrency_groups; mod configs; mod db; mod drafts; +#[cfg(feature = "private")] pub mod ee; +pub mod ee_oss; pub mod embeddings; mod favorite; mod flows; @@ -86,56 +90,90 @@ mod http_trigger_args; mod http_trigger_auth; #[cfg(feature = "http_trigger")] pub mod http_triggers; -mod indexer_ee; +#[cfg(feature = "private")] +pub mod indexer_ee; +mod indexer_oss; mod inputs; mod integration; #[cfg(feature = "postgres_trigger")] mod postgres_triggers; mod approvals; +#[cfg(all(feature = "enterprise", feature = "private"))] +pub mod apps_ee; #[cfg(feature = "enterprise")] -mod apps_ee; +mod apps_oss; +#[cfg(all(feature = "enterprise", feature = "gcp_trigger", feature = "private"))] +pub mod gcp_triggers_ee; #[cfg(all(feature = "enterprise", feature = "gcp_trigger"))] -mod gcp_triggers_ee; +mod gcp_triggers_oss; +#[cfg(all(feature = "enterprise", feature = "private"))] +pub mod git_sync_ee; #[cfg(feature = "enterprise")] -mod git_sync_ee; +mod git_sync_oss; +#[cfg(all(feature = "parquet", feature = "private"))] +pub mod job_helpers_ee; #[cfg(feature = "parquet")] -mod job_helpers_ee; +mod job_helpers_oss; pub mod job_metrics; pub mod jobs; +#[cfg(all(feature = "enterprise", feature = "kafka", feature = "private"))] +pub mod kafka_triggers_ee; #[cfg(all(feature = "enterprise", feature = "kafka"))] -mod kafka_triggers_ee; +mod kafka_triggers_oss; #[cfg(feature = "mqtt_trigger")] mod mqtt_triggers; +#[cfg(all(feature = "enterprise", feature = "nats", feature = "private"))] +pub mod nats_triggers_ee; #[cfg(all(feature = "enterprise", feature = "nats"))] -mod nats_triggers_ee; -#[cfg(feature = "oauth2")] +mod nats_triggers_oss; +#[cfg(all(feature = "oauth2", feature = "private"))] pub mod oauth2_ee; -mod oidc_ee; +#[cfg(feature = "oauth2")] +pub mod oauth2_oss; +#[cfg(feature = "private")] +pub mod oidc_ee; +mod oidc_oss; mod raw_apps; mod resources; -mod saml_ee; +#[cfg(feature = "private")] +pub mod saml_ee; +mod saml_oss; mod schedule; -mod scim_ee; +#[cfg(feature = "private")] +pub mod scim_ee; +mod scim_oss; mod scripts; mod service_logs; mod settings; mod slack_approvals; +#[cfg(all(feature = "smtp", feature = "private"))] +pub mod smtp_server_ee; #[cfg(feature = "smtp")] -mod smtp_server_ee; +mod smtp_server_oss; +#[cfg(all(feature = "enterprise", feature = "sqs_trigger", feature = "private"))] +pub mod sqs_triggers_ee; #[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] -mod sqs_triggers_ee; -mod teams_approvals_ee; +mod sqs_triggers_oss; +#[cfg(feature = "private")] +pub mod teams_approvals_ee; +mod teams_approvals_oss; mod trigger_helpers; mod static_assets; +#[cfg(all(feature = "stripe", feature = "enterprise", feature = "private"))] +pub mod stripe_ee; #[cfg(all(feature = "stripe", feature = "enterprise"))] -mod stripe_ee; -mod teams_ee; +mod stripe_oss; +#[cfg(feature = "private")] +pub mod teams_ee; +mod teams_oss; mod tracing_init; mod triggers; mod users; -mod users_ee; +#[cfg(feature = "private")] +pub mod users_ee; +mod users_oss; mod utils; mod variables; pub mod webhook_util; @@ -143,9 +181,11 @@ pub mod webhook_util; mod websocket_triggers; mod workers; mod workspaces; -mod workspaces_ee; +#[cfg(feature = "private")] +pub mod workspaces_ee; mod workspaces_export; mod workspaces_extra; +mod workspaces_oss; #[cfg(feature = "mcp")] mod mcp; @@ -218,9 +258,9 @@ type IndexReader = (); type ServiceLogIndexReader = (); #[cfg(feature = "tantivy")] -type IndexReader = windmill_indexer::completed_runs_ee::IndexReader; +type IndexReader = windmill_indexer::completed_runs_oss::IndexReader; #[cfg(feature = "tantivy")] -type ServiceLogIndexReader = windmill_indexer::service_logs_ee::ServiceLogIndexReader; +type ServiceLogIndexReader = windmill_indexer::service_logs_oss::ServiceLogIndexReader; pub async fn run_server( db: DB, @@ -278,7 +318,7 @@ pub async fn run_server( .allow_headers([http::header::CONTENT_TYPE, http::header::AUTHORIZATION]) .allow_origin(Any); - let sp_extension = Arc::new(saml_ee::build_sp_extension().await?); + let sp_extension = Arc::new(saml_oss::build_sp_extension().await?); if server_mode { #[cfg(feature = "embedding")] @@ -317,7 +357,7 @@ pub async fn run_server( let job_helpers_service = { #[cfg(feature = "parquet")] { - job_helpers_ee::workspaced_service() + job_helpers_oss::workspaced_service() } #[cfg(not(feature = "parquet"))] @@ -329,7 +369,7 @@ pub async fn run_server( let kafka_triggers_service = { #[cfg(all(feature = "enterprise", feature = "kafka"))] { - kafka_triggers_ee::workspaced_service() + kafka_triggers_oss::workspaced_service() } #[cfg(not(all(feature = "enterprise", feature = "kafka")))] @@ -341,7 +381,7 @@ pub async fn run_server( let nats_triggers_service = { #[cfg(all(feature = "enterprise", feature = "nats"))] { - nats_triggers_ee::workspaced_service() + nats_triggers_oss::workspaced_service() } #[cfg(not(all(feature = "enterprise", feature = "nats")))] @@ -365,7 +405,7 @@ pub async fn run_server( let gcp_triggers_service = { #[cfg(all(feature = "enterprise", feature = "gcp_trigger"))] { - gcp_triggers_ee::workspaced_service() + gcp_triggers_oss::workspaced_service() } #[cfg(not(all(feature = "enterprise", feature = "gcp_trigger")))] @@ -377,7 +417,7 @@ pub async fn run_server( let sqs_triggers_service = { #[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] { - sqs_triggers_ee::workspaced_service() + sqs_triggers_oss::workspaced_service() } #[cfg(not(all(feature = "enterprise", feature = "sqs_trigger")))] @@ -432,13 +472,13 @@ pub async fn run_server( #[cfg(all(feature = "enterprise", feature = "kafka"))] { let kafka_killpill_rx = killpill_rx.resubscribe(); - kafka_triggers_ee::start_kafka_consumers(db.clone(), kafka_killpill_rx); + kafka_triggers_oss::start_kafka_consumers(db.clone(), kafka_killpill_rx); } #[cfg(all(feature = "enterprise", feature = "nats"))] { let nats_killpill_rx = killpill_rx.resubscribe(); - nats_triggers_ee::start_nats_consumers(db.clone(), nats_killpill_rx); + nats_triggers_oss::start_nats_consumers(db.clone(), nats_killpill_rx); } #[cfg(feature = "postgres_trigger")] @@ -456,13 +496,13 @@ pub async fn run_server( #[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] { let sqs_killpill_rx = killpill_rx.resubscribe(); - sqs_triggers_ee::start_sqs(db.clone(), sqs_killpill_rx); + sqs_triggers_oss::start_sqs(db.clone(), sqs_killpill_rx); } #[cfg(all(feature = "enterprise", feature = "gcp_trigger"))] { let gcp_killpill_rx = killpill_rx.resubscribe(); - gcp_triggers_ee::start_consuming_gcp_pubsub_event(db.clone(), gcp_killpill_rx); + gcp_triggers_oss::start_consuming_gcp_pubsub_event(db.clone(), gcp_killpill_rx); } } @@ -497,7 +537,7 @@ pub async fn run_server( #[cfg(feature = "agent_worker_server")] let (agent_workers_router, agent_workers_bg_processor, agent_workers_killpill_tx) = if server_mode { - agent_workers_ee::workspaced_service(db.clone(), _base_internal_url.clone()) + agent_workers_oss::workspaced_service(db.clone(), _base_internal_url.clone()) } else { (Router::new(), vec![], None) }; @@ -535,7 +575,7 @@ pub async fn run_server( .nest("/oauth", { #[cfg(feature = "oauth2")] { - oauth2_ee::workspaced_service() + oauth2_oss::workspaced_service() } #[cfg(not(feature = "oauth2"))] @@ -552,7 +592,7 @@ pub async fn run_server( ) .nest("/variables", variables::workspaced_service()) .nest("/workspaces", workspaces::workspaced_service()) - .nest("/oidc", oidc_ee::workspaced_service()) + .nest("/oidc", oidc_oss::workspaced_service()) .nest("/http_triggers", http_triggers_service) .nest("/websocket_triggers", websocket_triggers_service) .nest("/kafka_triggers", kafka_triggers_service) @@ -584,17 +624,17 @@ pub async fn run_server( .nest("/jobs", jobs::global_root_service()) .nest( "/srch/w/:workspace_id/index", - indexer_ee::workspaced_service(), + indexer_oss::workspaced_service(), ) - .nest("/srch/index", indexer_ee::global_service()) - .nest("/oidc", oidc_ee::global_service()) + .nest("/srch/index", indexer_oss::global_service()) + .nest("/oidc", oidc_oss::global_service()) .nest( "/saml", - saml_ee::global_service().layer(Extension(Arc::clone(&sp_extension))), + saml_oss::global_service().layer(Extension(Arc::clone(&sp_extension))), ) .nest( "/scim", - scim_ee::global_service() + scim_oss::global_service() .route_layer(axum::middleware::from_fn(has_scim_token)), ) .nest("/concurrency_groups", concurrency_groups::global_service()) @@ -602,7 +642,7 @@ pub async fn run_server( .nest("/apps_u", { #[cfg(feature = "enterprise")] { - apps_ee::global_unauthed_service() + apps_oss::global_unauthed_service() } #[cfg(not(feature = "enterprise"))] @@ -621,7 +661,7 @@ pub async fn run_server( .nest("/agent_workers", { #[cfg(feature = "agent_worker_server")] { - agent_workers_ee::global_service().layer(Extension(agent_cache.clone())) + agent_workers_oss::global_service().layer(Extension(agent_cache.clone())) } #[cfg(not(feature = "agent_worker_server"))] { @@ -646,7 +686,7 @@ pub async fn run_server( .nest("/teams", { #[cfg(feature = "enterprise")] { - teams_ee::teams_service() + teams_oss::teams_service() } #[cfg(not(feature = "enterprise"))] @@ -660,12 +700,12 @@ pub async fn run_server( ) .route( "/w/:workspace_id/jobs/teams_approval/:job_id", - get(teams_approvals_ee::request_teams_approval), + get(teams_approvals_oss::request_teams_approval), ) .nest("/w/:workspace_id/github_app", { #[cfg(feature = "enterprise")] { - git_sync_ee::workspaced_service() + git_sync_oss::workspaced_service() } #[cfg(not(feature = "enterprise"))] @@ -674,7 +714,7 @@ pub async fn run_server( .nest("/github_app", { #[cfg(feature = "enterprise")] { - git_sync_ee::global_service() + git_sync_oss::global_service() } #[cfg(not(feature = "enterprise"))] @@ -695,7 +735,7 @@ pub async fn run_server( .nest("/oauth", { #[cfg(feature = "oauth2")] { - oauth2_ee::global_service().layer(Extension(Arc::clone(&sp_extension))) + oauth2_oss::global_service().layer(Extension(Arc::clone(&sp_extension))) } #[cfg(not(feature = "oauth2"))] @@ -721,7 +761,7 @@ pub async fn run_server( { #[cfg(all(feature = "enterprise", feature = "gcp_trigger"))] { - gcp_triggers_ee::gcp_push_route_handler() + gcp_triggers_oss::gcp_push_route_handler() } #[cfg(not(all(feature = "enterprise", feature = "gcp_trigger")))] { @@ -842,7 +882,7 @@ async fn ee_license() -> &'static str { #[cfg(feature = "enterprise")] async fn ee_license() -> String { - use windmill_common::ee::{LICENSE_KEY_ID, LICENSE_KEY_VALID}; + use windmill_common::ee_oss::{LICENSE_KEY_ID, LICENSE_KEY_VALID}; if *LICENSE_KEY_VALID.read().await { LICENSE_KEY_ID.read().await.clone() diff --git a/backend/windmill-api/src/mqtt_triggers.rs b/backend/windmill-api/src/mqtt_triggers.rs index 9f3fd19827..70b78ca913 100644 --- a/backend/windmill-api/src/mqtt_triggers.rs +++ b/backend/windmill-api/src/mqtt_triggers.rs @@ -39,7 +39,7 @@ use sql_builder::{bind::Bind, SqlBuilder}; use sqlx::{FromRow, Type}; use std::collections::HashMap; use std::time::Duration; -use windmill_audit::{audit_ee::audit_log, ActionKind}; +use windmill_audit::{audit_oss::audit_log, ActionKind}; use windmill_common::{ db::UserDB, error::{self, JsonResult}, diff --git a/backend/windmill-api/src/nats_triggers_ee.rs b/backend/windmill-api/src/nats_triggers_oss.rs similarity index 79% rename from backend/windmill-api/src/nats_triggers_ee.rs rename to backend/windmill-api/src/nats_triggers_oss.rs index 649d3a3837..28bf1e70e2 100644 --- a/backend/windmill-api/src/nats_triggers_ee.rs +++ b/backend/windmill-api/src/nats_triggers_oss.rs @@ -1,22 +1,34 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::nats_triggers_ee::*; + +#[cfg(not(feature = "private"))] use crate::db::DB; +#[cfg(not(feature = "private"))] use axum::Router; +#[cfg(not(feature = "private"))] use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "private"))] #[derive(Serialize, Deserialize)] pub struct NatsResourceAuth {} +#[cfg(not(feature = "private"))] pub fn workspaced_service() -> Router { Router::new() } +#[cfg(not(feature = "private"))] pub fn start_nats_consumers(_db: DB, mut _killpill_rx: tokio::sync::broadcast::Receiver<()>) -> () { // implementation is not open source } #[derive(Serialize, Deserialize)] +#[cfg(not(feature = "private"))] pub enum NatsTriggerConfigConnection {} #[derive(Serialize, Clone)] +#[cfg(not(feature = "private"))] pub struct NatsTrigger { pub workspace_id: String, pub path: String, @@ -40,4 +52,4 @@ pub struct NatsTrigger { #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, pub enabled: bool, -} \ No newline at end of file +} diff --git a/backend/windmill-api/src/oauth2_ee.rs b/backend/windmill-api/src/oauth2_oss.rs similarity index 76% rename from backend/windmill-api/src/oauth2_ee.rs rename to backend/windmill-api/src/oauth2_oss.rs index 49d2155cf3..04e0e1b202 100644 --- a/backend/windmill-api/src/oauth2_ee.rs +++ b/backend/windmill-api/src/oauth2_oss.rs @@ -1,3 +1,7 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::oauth2_ee::*; + /* * Author: Ruben Fiszel * Copyright: Windmill Labs, Inc 2022 @@ -6,39 +10,50 @@ * LICENSE-AGPL for a copy of the license. */ +#[cfg(not(feature = "private"))] use std::{collections::HashMap, fmt::Debug}; +#[cfg(not(feature = "private"))] use axum::{routing::get, Json, Router}; +#[cfg(not(feature = "private"))] use hmac::Mac; -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] use itertools::Itertools; -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] use oauth2::{Client as OClient, *}; +#[cfg(not(feature = "private"))] use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "private"))] use sqlx::{Postgres, Transaction}; -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] use windmill_common::more_serde::maybe_number_opt; -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] use crate::OAUTH_CLIENTS; +#[cfg(not(feature = "private"))] use windmill_common::error; +#[cfg(not(feature = "private"))] use windmill_common::oauth2::*; +#[cfg(not(feature = "private"))] use crate::db::DB; +#[cfg(not(feature = "private"))] use std::str; +#[cfg(not(feature = "private"))] pub fn global_service() -> Router { Router::new() .route("/list_logins", get(list_logins)) .route("/list_connects", get(list_connects)) } +#[cfg(not(feature = "private"))] pub fn workspaced_service() -> Router { Router::new() } -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] #[derive(Debug, Clone)] pub struct ClientWithScopes { _client: OClient, @@ -48,9 +63,10 @@ pub struct ClientWithScopes { _allowed_domains: Option>, _userinfo_url: Option, } -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] pub type BasicClientsMap = HashMap; +#[cfg(not(feature = "private"))] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct OAuthConfig { auth_url: String, @@ -62,6 +78,7 @@ pub struct OAuthConfig { req_body_auth: Option, } +#[cfg(not(feature = "private"))] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct OAuthClient { id: String, @@ -71,7 +88,7 @@ pub struct OAuthClient { login_config: Option, } -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] #[derive(Debug)] pub struct AllClients { pub logins: BasicClientsMap, @@ -79,7 +96,7 @@ pub struct AllClients { pub slack: Option, } -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] pub async fn build_oauth_clients( _base_url: &str, _oauths_from_config: Option>, @@ -93,7 +110,7 @@ pub async fn build_oauth_clients( }); } -#[cfg(feature = "oauth2")] +#[cfg(all(feature = "oauth2", not(feature = "private")))] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct TokenResponse { access_token: AccessToken, @@ -107,17 +124,20 @@ pub struct TokenResponse { scope: Option>, } +#[cfg(not(feature = "private"))] #[derive(Serialize)] struct Logins { oauth: Vec, saml: Option, } +#[cfg(not(feature = "private"))] async fn list_logins() -> error::JsonResult { // Implementation is not open source return Ok(Json(Logins { oauth: vec![], saml: None })); } -#[cfg(feature = "oauth2")] +#[allow(unused)] +#[cfg(all(feature = "oauth2", not(feature = "private")))] async fn list_connects() -> error::JsonResult> { Ok(Json( (&OAUTH_CLIENTS.read().await.connects) @@ -127,12 +147,14 @@ async fn list_connects() -> error::JsonResult> { )) } -#[cfg(not(feature = "oauth2"))] -async fn list_connects() -> error::JsonResult> { +#[allow(unused)] +#[cfg(not(all(feature = "oauth2", not(feature = "private"))))] +async fn list_connects() -> windmill_common::error::JsonResult> { // Implementation is not open source - return Ok(Json(vec![])); + return Ok(axum::Json(vec![])); } +#[cfg(not(feature = "private"))] pub async fn _refresh_token<'c>( _tx: Transaction<'c, Postgres>, _path: &str, @@ -146,6 +168,7 @@ pub async fn _refresh_token<'c>( )) } +#[cfg(not(feature = "private"))] pub async fn check_nb_of_user(db: &DB) -> error::Result<()> { let nb_users_sso = sqlx::query_scalar!("SELECT COUNT(*) FROM password WHERE login_type != 'password'",) @@ -171,10 +194,11 @@ pub async fn check_nb_of_user(db: &DB) -> error::Result<()> { } #[derive(Clone, Debug)] +#[cfg(not(feature = "private"))] pub struct SlackVerifier { _mac: HmacSha256, } - +#[cfg(not(feature = "private"))] impl SlackVerifier { pub fn new>(secret: S) -> anyhow::Result { HmacSha256::new_from_slice(secret.as_ref()) diff --git a/backend/windmill-api/src/oidc_ee.rs b/backend/windmill-api/src/oidc_oss.rs similarity index 68% rename from backend/windmill-api/src/oidc_ee.rs rename to backend/windmill-api/src/oidc_oss.rs index 248b990f54..4042c2a53b 100644 --- a/backend/windmill-api/src/oidc_ee.rs +++ b/backend/windmill-api/src/oidc_oss.rs @@ -1,3 +1,7 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::oidc_ee::*; + /* * Author: Ruben Fiszel * Copyright: Windmill Labs, Inc 2023 @@ -6,12 +10,15 @@ * LICENSE-AGPL for a copy of the license. */ +#[cfg(not(feature = "private"))] use axum::Router; +#[cfg(not(feature = "private"))] pub fn global_service() -> Router { Router::new() } +#[cfg(not(feature = "private"))] pub fn workspaced_service() -> Router { Router::new() } diff --git a/backend/windmill-api/src/postgres_triggers/handler.rs b/backend/windmill-api/src/postgres_triggers/handler.rs index 9beafadbf2..f48072c8c3 100644 --- a/backend/windmill-api/src/postgres_triggers/handler.rs +++ b/backend/windmill-api/src/postgres_triggers/handler.rs @@ -19,7 +19,7 @@ use rust_postgres::types::Type; use serde::{Deserialize, Deserializer, Serialize}; use sql_builder::{bind::Bind, SqlBuilder}; use sqlx::{postgres::types::Oid, Connection, FromRow, PgConnection}; -use windmill_audit::{audit_ee::audit_log, ActionKind}; +use windmill_audit::{audit_oss::audit_log, ActionKind}; use windmill_common::{ db::UserDB, error::{self, Error, JsonResult, Result}, @@ -298,9 +298,9 @@ async fn create_custom_slot_and_publication_inner( let mut tx = pg_connection.begin().await?; let publication_name = format!("windmill_trigger_{}", generate_random_string()); let replication_slot_name = publication_name.clone(); - + create_logical_replication_slot(&mut tx, &replication_slot_name).await?; - + create_pg_publication( &mut tx, &publication_name, @@ -949,7 +949,7 @@ pub async fn alter_publication( .await?; let mut tx = pg_connection.begin().await?; - + let publication = get_publication_scope_and_transaction(&mut tx, &publication_name).await?; update_pg_publication( diff --git a/backend/windmill-api/src/raw_apps.rs b/backend/windmill-api/src/raw_apps.rs index bb2763b73d..3a895bab97 100644 --- a/backend/windmill-api/src/raw_apps.rs +++ b/backend/windmill-api/src/raw_apps.rs @@ -22,7 +22,7 @@ use serde::{Deserialize, Serialize}; use sql_builder::{bind::Bind, SqlBuilder}; use sqlx::FromRow; use std::str; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::{ apps::ListAppQuery, diff --git a/backend/windmill-api/src/resources.rs b/backend/windmill-api/src/resources.rs index 8a2fab0434..d2d58c918d 100644 --- a/backend/windmill-api/src/resources.rs +++ b/backend/windmill-api/src/resources.rs @@ -26,7 +26,7 @@ use serde_json::{value::RawValue, Value}; use sql_builder::{bind::Bind, quote, SqlBuilder}; use sqlx::{FromRow, Postgres, Transaction}; use uuid::Uuid; -use windmill_audit::audit_ee::{audit_log, AuditAuthor}; +use windmill_audit::audit_oss::{audit_log, AuditAuthor}; use windmill_audit::ActionKind; use windmill_common::{ db::UserDB, diff --git a/backend/windmill-api/src/saml_ee.rs b/backend/windmill-api/src/saml_oss.rs similarity index 75% rename from backend/windmill-api/src/saml_ee.rs rename to backend/windmill-api/src/saml_oss.rs index b3f1d4653c..0f4f4aa7f6 100644 --- a/backend/windmill-api/src/saml_ee.rs +++ b/backend/windmill-api/src/saml_oss.rs @@ -7,18 +7,27 @@ */ #![allow(non_snake_case)] +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::saml_ee::*; + +#[cfg(not(feature = "private"))] use axum::{routing::post, Router}; +#[cfg(not(feature = "private"))] pub struct ServiceProviderExt(); +#[cfg(not(feature = "private"))] pub async fn build_sp_extension() -> anyhow::Result { return Ok(ServiceProviderExt()); } +#[cfg(not(feature = "private"))] pub fn global_service() -> Router { Router::new().route("/acs", post(acs)) } +#[cfg(not(feature = "private"))] pub async fn acs() -> String { // Implementation is not open source as it is a Windmill Enterprise Edition feature "SAML available only in enterprise version".to_string() diff --git a/backend/windmill-api/src/schedule.rs b/backend/windmill-api/src/schedule.rs index 90d91c846c..3cb13798d9 100644 --- a/backend/windmill-api/src/schedule.rs +++ b/backend/windmill-api/src/schedule.rs @@ -22,7 +22,7 @@ use serde::{Deserialize, Serialize}; use sql_builder::{prelude::Bind, SqlBuilder}; use sqlx::{Postgres, Transaction}; use std::str::FromStr; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::{ db::UserDB, diff --git a/backend/windmill-api/src/scim_ee.rs b/backend/windmill-api/src/scim_oss.rs similarity index 72% rename from backend/windmill-api/src/scim_ee.rs rename to backend/windmill-api/src/scim_oss.rs index f11097f874..5210411466 100644 --- a/backend/windmill-api/src/scim_ee.rs +++ b/backend/windmill-api/src/scim_oss.rs @@ -1,3 +1,7 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::scim_ee::*; + /* * Author: Ruben Fiszel * Copyright: Windmill Labs, Inc 2023 @@ -6,17 +10,22 @@ * LICENSE-AGPL for a copy of the license. */ +#[cfg(not(feature = "private"))] use axum::{middleware::Next, response::Response, routing::get, Router}; +#[cfg(not(feature = "private"))] use hyper::Request; +#[cfg(not(feature = "private"))] pub fn global_service() -> Router { Router::new().route("/ee", get(ee)) } +#[cfg(not(feature = "private"))] pub async fn ee() -> String { return "Enterprise Edition".to_string(); } +#[cfg(not(feature = "private"))] pub async fn has_scim_token(_request: Request, _next: Next) -> Response { //Not implemented in open-source version todo!() diff --git a/backend/windmill-api/src/scripts.rs b/backend/windmill-api/src/scripts.rs index a827fa5079..27ab296700 100644 --- a/backend/windmill-api/src/scripts.rs +++ b/backend/windmill-api/src/scripts.rs @@ -38,7 +38,7 @@ use std::{ hash::{Hash, Hasher}, sync::Arc, }; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_worker::process_relative_imports; diff --git a/backend/windmill-api/src/settings.rs b/backend/windmill-api/src/settings.rs index b589713b91..9dfb687e51 100644 --- a/backend/windmill-api/src/settings.rs +++ b/backend/windmill-api/src/settings.rs @@ -10,7 +10,7 @@ use std::time::Duration; use crate::{ db::{ApiAuthed, DB}, - ee::validate_license_key, + ee_oss::validate_license_key, utils::{generate_instance_username_for_all_users, require_super_admin}, HTTP_CLIENT, }; @@ -29,9 +29,9 @@ use crate::utils::require_devops_role; use serde::Deserialize; #[cfg(feature = "enterprise")] -use windmill_common::ee::{send_critical_alert, CriticalAlertKind, CriticalErrorChannel}; +use windmill_common::ee_oss::{send_critical_alert, CriticalAlertKind, CriticalErrorChannel}; use windmill_common::{ - email_ee::send_email, + email_oss::send_email, error::{self, JsonResult, Result}, global_settings::{ AUTOMATE_USERNAME_CREATION_SETTING, CRITICAL_ALERT_MUTE_UI_SETTING, EMAIL_DOMAIN_SETTING, @@ -326,10 +326,10 @@ async fn list_global_settings() -> JsonResult { pub async fn send_stats(Extension(db): Extension, authed: ApiAuthed) -> Result { require_super_admin(&db, &authed.email).await?; - windmill_common::stats_ee::send_stats( + windmill_common::stats_oss::send_stats( &HTTP_CLIENT, &db, - windmill_common::stats_ee::SendStatsReason::Manual, + windmill_common::stats_oss::SendStatsReason::Manual, ) .await?; @@ -390,11 +390,11 @@ pub async fn renew_license_key( authed: ApiAuthed, ) -> Result { require_super_admin(&db, &authed.email).await?; - let result = windmill_common::ee::renew_license_key( + let result = windmill_common::ee_oss::renew_license_key( &HTTP_CLIENT, &db, license_key, - windmill_common::ee::RenewReason::Manual, + windmill_common::ee_oss::RenewReason::Manual, ) .await; @@ -424,7 +424,7 @@ pub async fn create_customer_portal_session( Query(LicenseQuery { license_key }): Query, ) -> Result { let url = - windmill_common::ee::create_customer_portal_session(&HTTP_CLIENT, license_key).await?; + windmill_common::ee_oss::create_customer_portal_session(&HTTP_CLIENT, license_key).await?; return Ok(url); } diff --git a/backend/windmill-api/src/smtp_server_ee.rs b/backend/windmill-api/src/smtp_server_oss.rs similarity index 69% rename from backend/windmill-api/src/smtp_server_ee.rs rename to backend/windmill-api/src/smtp_server_oss.rs index 48e274f6a1..7d2b72c7f1 100644 --- a/backend/windmill-api/src/smtp_server_ee.rs +++ b/backend/windmill-api/src/smtp_server_oss.rs @@ -1,7 +1,15 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::smtp_server_ee::*; + +#[cfg(not(feature = "private"))] use crate::{auth::AuthCache, db::DB}; +#[cfg(not(feature = "private"))] use std::{net::SocketAddr, sync::Arc}; +#[cfg(not(feature = "private"))] use windmill_common::db::UserDB; +#[cfg(not(feature = "private"))] pub struct SmtpServer { pub auth_cache: Arc, pub db: DB, @@ -9,6 +17,7 @@ pub struct SmtpServer { pub base_internal_url: String, } +#[cfg(not(feature = "private"))] impl SmtpServer { pub async fn start_listener_thread(self: Arc, _addr: SocketAddr) -> anyhow::Result<()> { let _ = self.auth_cache; diff --git a/backend/windmill-api/src/sqs_triggers_ee.rs b/backend/windmill-api/src/sqs_triggers_oss.rs similarity index 75% rename from backend/windmill-api/src/sqs_triggers_ee.rs rename to backend/windmill-api/src/sqs_triggers_oss.rs index da9b288f6b..6e01641a5e 100644 --- a/backend/windmill-api/src/sqs_triggers_ee.rs +++ b/backend/windmill-api/src/sqs_triggers_oss.rs @@ -1,18 +1,28 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::sqs_triggers_ee::*; + +#[cfg(not(feature = "private"))] use crate::db::DB; +#[cfg(not(feature = "private"))] use axum::Router; +#[cfg(not(feature = "private"))] use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "private"))] use windmill_common::auth::aws::AwsAuthResourceType; - +#[cfg(not(feature = "private"))] pub fn workspaced_service() -> Router { Router::new() } +#[cfg(not(feature = "private"))] pub fn start_sqs(_db: DB, mut _killpill_rx: tokio::sync::broadcast::Receiver<()>) -> () { // implementation is not open source } #[derive(Debug, Clone, Deserialize, Serialize)] +#[cfg(not(feature = "private"))] pub struct SqsTrigger { pub queue_url: String, pub aws_auth_resource_type: AwsAuthResourceType, @@ -30,4 +40,4 @@ pub struct SqsTrigger { pub server_id: Option, pub last_server_ping: Option>, pub enabled: bool, -} \ No newline at end of file +} diff --git a/backend/windmill-api/src/stripe_ee.rs b/backend/windmill-api/src/stripe_ee.rs deleted file mode 100644 index 6934cad3bc..0000000000 --- a/backend/windmill-api/src/stripe_ee.rs +++ /dev/null @@ -1,5 +0,0 @@ -use axum::Router; - -pub fn add_stripe_routes(router: Router) -> Router { - return router; -} diff --git a/backend/windmill-api/src/stripe_oss.rs b/backend/windmill-api/src/stripe_oss.rs new file mode 100644 index 0000000000..206a78dc53 --- /dev/null +++ b/backend/windmill-api/src/stripe_oss.rs @@ -0,0 +1,11 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::stripe_ee::*; + +#[cfg(not(feature = "private"))] +use axum::Router; + +#[cfg(not(feature = "private"))] +pub fn add_stripe_routes(router: Router) -> Router { + return router; +} diff --git a/backend/windmill-api/src/teams_approvals_ee.rs b/backend/windmill-api/src/teams_approvals_oss.rs similarity index 51% rename from backend/windmill-api/src/teams_approvals_ee.rs rename to backend/windmill-api/src/teams_approvals_oss.rs index 05698b98e3..df5826aa71 100644 --- a/backend/windmill-api/src/teams_approvals_ee.rs +++ b/backend/windmill-api/src/teams_approvals_oss.rs @@ -1,7 +1,14 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::teams_approvals_ee::*; + +#[cfg(not(feature = "private"))] use hyper::StatusCode; +#[cfg(not(feature = "private"))] use windmill_common::error::Error; +#[cfg(not(feature = "private"))] pub async fn request_teams_approval() -> Result { Err(Error::InternalErr("enterprise feature only".to_string())) -} \ No newline at end of file +} diff --git a/backend/windmill-api/src/teams_ee.rs b/backend/windmill-api/src/teams_oss.rs similarity index 70% rename from backend/windmill-api/src/teams_ee.rs rename to backend/windmill-api/src/teams_oss.rs index 46cbe72059..95d4883690 100644 --- a/backend/windmill-api/src/teams_ee.rs +++ b/backend/windmill-api/src/teams_oss.rs @@ -1,39 +1,50 @@ -use http::status::StatusCode; -#[cfg(feature = "enterprise")] +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::teams_ee::*; + +#[cfg(all(feature = "enterprise", not(feature = "private")))] use axum::Router; +#[cfg(not(feature = "private"))] +use http::status::StatusCode; +#[cfg(not(feature = "private"))] use windmill_common::error::Error; +#[cfg(not(feature = "private"))] pub async fn edit_teams_command() -> Result { return Err(Error::BadRequest( "Teams only available on enterprise".to_string(), )); } +#[cfg(not(feature = "private"))] pub async fn workspaces_list_available_teams_ids() -> Result { return Err(Error::BadRequest( "Teams only available on enterprise".to_string(), )); } +#[cfg(not(feature = "private"))] pub async fn connect_teams() -> Result { return Err(Error::BadRequest( "Teams only available on enterprise".to_string(), )); } +#[cfg(not(feature = "private"))] pub async fn run_teams_message_test_job() -> Result { return Err(Error::BadRequest( "Teams only available on enterprise".to_string(), )); } +#[cfg(not(feature = "private"))] pub async fn workspaces_list_available_teams_channels() -> Result { return Err(Error::BadRequest( "Teams only available on enterprise".to_string(), )); } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub fn teams_service() -> Router { Router::new() -} \ No newline at end of file +} diff --git a/backend/windmill-api/src/users.rs b/backend/windmill-api/src/users.rs index 5bc7ce9c4d..da77337703 100644 --- a/backend/windmill-api/src/users.rs +++ b/backend/windmill-api/src/users.rs @@ -42,7 +42,7 @@ use sqlx::FromRow; use time::OffsetDateTime; use tower_cookies::{Cookie, Cookies}; use tracing::Instrument; -use windmill_audit::audit_ee::{audit_log, AuditAuthor}; +use windmill_audit::audit_oss::{audit_log, AuditAuthor}; use windmill_audit::ActionKind; use windmill_common::auth::fetch_authed_from_permissioned_as; use windmill_common::global_settings::AUTOMATE_USERNAME_CREATION_SETTING; @@ -1508,7 +1508,7 @@ async fn create_user( Extension(argon2): Extension>>, Json(nu): Json, ) -> Result<(StatusCode, String)> { - crate::users_ee::create_user(authed, db, webhook, argon2, nu).await + crate::users_oss::create_user(authed, db, webhook, argon2, nu).await } async fn delete_workspace_user( @@ -1582,7 +1582,7 @@ async fn set_password( Json(ep): Json, ) -> Result { let email = authed.email.clone(); - crate::users_ee::set_password(db, argon2, authed, &email, ep).await + crate::users_oss::set_password(db, argon2, authed, &email, ep).await } async fn set_password_of_user( @@ -1593,7 +1593,7 @@ async fn set_password_of_user( Json(ep): Json, ) -> Result { require_super_admin(&db, &authed.email).await?; - crate::users_ee::set_password(db, argon2, authed, &email, ep).await + crate::users_oss::set_password(db, argon2, authed, &email, ep).await } async fn set_login_type( diff --git a/backend/windmill-api/src/users_ee.rs b/backend/windmill-api/src/users_oss.rs similarity index 71% rename from backend/windmill-api/src/users_ee.rs rename to backend/windmill-api/src/users_oss.rs index 7a11239a2f..88a12eb710 100644 --- a/backend/windmill-api/src/users_ee.rs +++ b/backend/windmill-api/src/users_oss.rs @@ -1,15 +1,27 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::users_ee::*; + +#[cfg(not(feature = "private"))] use std::sync::Arc; +#[cfg(not(feature = "private"))] use crate::db::ApiAuthed; +#[cfg(not(feature = "private"))] use crate::users::{EditPassword, NewUser}; +#[cfg(not(feature = "private"))] use crate::{db::DB, webhook_util::WebhookShared}; +#[cfg(not(feature = "private"))] use argon2::Argon2; +#[cfg(not(feature = "private"))] use http::StatusCode; +#[cfg(not(feature = "private"))] use windmill_common::error::{Error, Result}; +#[cfg(not(feature = "private"))] pub async fn create_user( _authed: ApiAuthed, _db: DB, @@ -22,6 +34,7 @@ pub async fn create_user( )) } +#[cfg(not(feature = "private"))] pub async fn set_password( _db: DB, _argon2: Arc>, @@ -34,6 +47,7 @@ pub async fn set_password( )) } +#[cfg(not(feature = "private"))] pub fn send_email_if_possible(_subject: &str, _content: &str, _to: &str) { tracing::warn!( "send_email_if_possible is not implemented in Windmill's Open Source repository" diff --git a/backend/windmill-api/src/variables.rs b/backend/windmill-api/src/variables.rs index e810f95750..7dc6a85b49 100644 --- a/backend/windmill-api/src/variables.rs +++ b/backend/windmill-api/src/variables.rs @@ -20,7 +20,7 @@ use axum::{ use hyper::StatusCode; use serde_json::Value; -use windmill_audit::audit_ee::{audit_log, AuditAuthorable}; +use windmill_audit::audit_oss::{audit_log, AuditAuthorable}; use windmill_audit::ActionKind; use windmill_common::{ db::UserDB, @@ -186,7 +186,7 @@ async fn get_variable( #[cfg(feature = "oauth2")] { Some( - crate::oauth2_ee::_refresh_token( + crate::oauth2_oss::_refresh_token( tx, &variable.path, &w_id, @@ -653,7 +653,7 @@ pub async fn get_value_internal<'c>( if variable.is_expired.unwrap_or(false) && variable.account.is_some() { #[cfg(feature = "oauth2")] { - crate::oauth2_ee::_refresh_token( + crate::oauth2_oss::_refresh_token( tx, &variable.path, &w_id, diff --git a/backend/windmill-api/src/websocket_triggers.rs b/backend/windmill-api/src/websocket_triggers.rs index 8bd165844c..8c263b1f62 100644 --- a/backend/windmill-api/src/websocket_triggers.rs +++ b/backend/windmill-api/src/websocket_triggers.rs @@ -20,7 +20,7 @@ use std::{collections::HashMap, fmt}; use tokio::net::TcpStream; use tokio_tungstenite::{connect_async, tungstenite::Message, MaybeTlsStream, WebSocketStream}; use uuid::Uuid; -use windmill_audit::{audit_ee::audit_log, ActionKind}; +use windmill_audit::{audit_oss::audit_log, ActionKind}; use windmill_common::{ db::UserDB, error::{self, to_anyhow, JsonResult}, diff --git a/backend/windmill-api/src/workspaces.rs b/backend/windmill-api/src/workspaces.rs index 75c9a8d034..b8e8a813f3 100644 --- a/backend/windmill-api/src/workspaces.rs +++ b/backend/windmill-api/src/workspaces.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; use crate::ai::{AIConfig, AI_REQUEST_CACHE}; use crate::db::ApiAuthed; -use crate::users_ee::send_email_if_possible; +use crate::users_oss::send_email_if_possible; use crate::utils::get_instance_username_or_create_pending; use crate::BASE_URL; use crate::{ @@ -30,7 +30,7 @@ use chrono::Utc; use regex::Regex; use uuid::Uuid; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::db::UserDB; use windmill_common::s3_helpers::LargeFileStorage; @@ -58,7 +58,7 @@ use sqlx::{FromRow, Postgres, Transaction}; use windmill_common::oauth2::InstanceEvent; use windmill_common::utils::not_found_if_none; -use crate::teams_ee::{ +use crate::teams_oss::{ connect_teams, edit_teams_command, run_teams_message_test_job, workspaces_list_available_teams_channels, workspaces_list_available_teams_ids, }; @@ -145,7 +145,7 @@ pub fn workspaced_service() -> Router { #[cfg(all(feature = "stripe", feature = "enterprise"))] { - crate::stripe_ee::add_stripe_routes(router) + crate::stripe_oss::add_stripe_routes(router) } #[cfg(not(feature = "stripe"))] @@ -640,7 +640,7 @@ async fn edit_auto_invite( Path(w_id): Path, Json(ea): Json, ) -> Result { - crate::workspaces_ee::edit_auto_invite(authed, db, w_id, ea).await + crate::workspaces_oss::edit_auto_invite(authed, db, w_id, ea).await } async fn edit_webhook( diff --git a/backend/windmill-api/src/workspaces_export.rs b/backend/windmill-api/src/workspaces_export.rs index cd2be0f708..b3ad6dbdd7 100644 --- a/backend/windmill-api/src/workspaces_export.rs +++ b/backend/windmill-api/src/workspaces_export.rs @@ -622,7 +622,7 @@ pub(crate) async fn tarball_workspace( #[cfg(all(feature = "enterprise", feature = "kafka"))] { let kafka_triggers = sqlx::query_as!( - crate::kafka_triggers_ee::KafkaTrigger, + crate::kafka_triggers_oss::KafkaTrigger, "SELECT * FROM kafka_trigger WHERE workspace_id = $1", &w_id @@ -644,7 +644,7 @@ pub(crate) async fn tarball_workspace( #[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] { let sqs_triggers = sqlx::query_as!( - crate::sqs_triggers_ee::SqsTrigger, + crate::sqs_triggers_oss::SqsTrigger, r#" SELECT aws_auth_resource_type AS "aws_auth_resource_type: _", @@ -684,7 +684,7 @@ pub(crate) async fn tarball_workspace( #[cfg(all(feature = "enterprise", feature = "gcp_trigger"))] { let gcp_triggers = sqlx::query_as!( - crate::gcp_triggers_ee::GcpTrigger, + crate::gcp_triggers_oss::GcpTrigger, r#" SELECT gcp_resource_path, @@ -726,7 +726,7 @@ pub(crate) async fn tarball_workspace( #[cfg(all(feature = "enterprise", feature = "nats"))] { let nats_triggers = sqlx::query_as!( - crate::nats_triggers_ee::NatsTrigger, + crate::nats_triggers_oss::NatsTrigger, "SELECT * FROM nats_trigger WHERE workspace_id = $1", &w_id diff --git a/backend/windmill-api/src/workspaces_extra.rs b/backend/windmill-api/src/workspaces_extra.rs index 07570df5c3..51a224d0e2 100644 --- a/backend/windmill-api/src/workspaces_extra.rs +++ b/backend/windmill-api/src/workspaces_extra.rs @@ -8,7 +8,7 @@ use axum::{ Json, }; -use windmill_audit::audit_ee::audit_log; +use windmill_audit::audit_oss::audit_log; use windmill_audit::ActionKind; use windmill_common::worker::CLOUD_HOSTED; diff --git a/backend/windmill-api/src/workspaces_ee.rs b/backend/windmill-api/src/workspaces_oss.rs similarity index 70% rename from backend/windmill-api/src/workspaces_ee.rs rename to backend/windmill-api/src/workspaces_oss.rs index aa8799e233..4f55539da1 100644 --- a/backend/windmill-api/src/workspaces_ee.rs +++ b/backend/windmill-api/src/workspaces_oss.rs @@ -1,8 +1,14 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::workspaces_ee::*; + +#[cfg(not(feature = "private"))] use crate::{ db::{ApiAuthed, DB}, workspaces::EditAutoInvite, }; +#[cfg(not(feature = "private"))] pub async fn edit_auto_invite( _authed: ApiAuthed, _db: DB, diff --git a/backend/windmill-audit/Cargo.toml b/backend/windmill-audit/Cargo.toml index 8b202b4abf..5a9ea376b6 100644 --- a/backend/windmill-audit/Cargo.toml +++ b/backend/windmill-audit/Cargo.toml @@ -10,6 +10,7 @@ path = "./src/lib.rs" [features] enterprise = ["windmill-common/enterprise"] +private = [] [dependencies] serde.workspace = true diff --git a/backend/windmill-audit/src/audit_ee.rs b/backend/windmill-audit/src/audit_oss.rs similarity index 78% rename from backend/windmill-audit/src/audit_ee.rs rename to backend/windmill-audit/src/audit_oss.rs index 97a8e6bbcf..d29daaa7ae 100644 --- a/backend/windmill-audit/src/audit_ee.rs +++ b/backend/windmill-audit/src/audit_oss.rs @@ -1,3 +1,7 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::audit_ee::*; + /* * Author: Ruben Fiszel * Copyright: Windmill Labs, Inc 2022 @@ -5,23 +9,26 @@ * Please see the included NOTICE for copyright information and * LICENSE-AGPL for a copy of the license. */ -use std::collections::HashMap; - -use windmill_common::{ - error::{Error, Result}, - utils::Pagination, +#[cfg(not(feature = "private"))] +use { + crate::{ActionKind, AuditLog, ListAuditLogQuery}, + sqlx::{Postgres, Transaction}, + std::collections::HashMap, + windmill_common::{ + error::{Error, Result}, + utils::Pagination, + }, }; -use crate::{ActionKind, AuditLog, ListAuditLogQuery}; -use sqlx::{Postgres, Transaction}; - #[derive(Clone)] +#[cfg(not(feature = "private"))] pub struct AuditAuthor { pub username: String, pub email: String, pub username_override: Option, } +#[cfg(not(feature = "private"))] impl AuditAuthorable for AuditAuthor { fn email(&self) -> &str { &self.email @@ -36,12 +43,14 @@ impl AuditAuthorable for AuditAuthor { } } +#[cfg(not(feature = "private"))] pub trait AuditAuthorable { fn username(&self) -> &str; fn email(&self) -> &str; fn username_override(&self) -> Option<&str>; } +#[cfg(not(feature = "private"))] #[tracing::instrument(level = "trace", skip_all)] pub async fn audit_log<'c, E: sqlx::Executor<'c, Database = Postgres>>( _db: E, @@ -56,6 +65,7 @@ pub async fn audit_log<'c, E: sqlx::Executor<'c, Database = Postgres>>( Ok(()) } +#[cfg(not(feature = "private"))] pub async fn list_audit( _tx: Transaction<'_, Postgres>, _w_id: String, @@ -66,6 +76,7 @@ pub async fn list_audit( return Ok(vec![]); } +#[cfg(not(feature = "private"))] pub async fn get_audit(tx: Transaction<'_, Postgres>, _id: i32, _w_id: &str) -> Result { // Implementation is not open source as Audit logs is a Windmill Enterprise Edition feature tx.commit().await?; diff --git a/backend/windmill-audit/src/lib.rs b/backend/windmill-audit/src/lib.rs index 10894798fb..15bda522c1 100644 --- a/backend/windmill-audit/src/lib.rs +++ b/backend/windmill-audit/src/lib.rs @@ -1,7 +1,9 @@ use serde::{Deserialize, Serialize}; use sqlx::FromRow; +#[cfg(feature = "private")] pub mod audit_ee; +pub mod audit_oss; #[derive(sqlx::Type, Serialize, Deserialize, Debug)] #[sqlx(type_name = "ACTION_KIND", rename_all = "lowercase")] diff --git a/backend/windmill-autoscaling/Cargo.toml b/backend/windmill-autoscaling/Cargo.toml index fbebaf0fd7..7e4bc623ad 100644 --- a/backend/windmill-autoscaling/Cargo.toml +++ b/backend/windmill-autoscaling/Cargo.toml @@ -10,6 +10,7 @@ path = "./src/lib.rs" [features] enterprise = ["windmill-queue/enterprise", "windmill-common/enterprise"] +private = [] default = [] [dependencies] diff --git a/backend/windmill-autoscaling/src/autoscaling_ee.rs b/backend/windmill-autoscaling/src/autoscaling_ee.rs deleted file mode 100644 index 1c9defbede..0000000000 --- a/backend/windmill-autoscaling/src/autoscaling_ee.rs +++ /dev/null @@ -1,6 +0,0 @@ -use windmill_common::DB; - -pub async fn apply_all_autoscaling(_db: &DB) -> anyhow::Result<()> { - // Autoscaling is an ee feature - Ok(()) -} diff --git a/backend/windmill-autoscaling/src/autoscaling_oss.rs b/backend/windmill-autoscaling/src/autoscaling_oss.rs new file mode 100644 index 0000000000..c9cbdc3ee0 --- /dev/null +++ b/backend/windmill-autoscaling/src/autoscaling_oss.rs @@ -0,0 +1,12 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::autoscaling_ee::*; + +#[cfg(not(feature = "private"))] +use windmill_common::DB; + +#[cfg(not(feature = "private"))] +pub async fn apply_all_autoscaling(_db: &DB) -> anyhow::Result<()> { + // Autoscaling is an ee feature + Ok(()) +} diff --git a/backend/windmill-autoscaling/src/lib.rs b/backend/windmill-autoscaling/src/lib.rs index 28b9319244..1b9d6b94bf 100644 --- a/backend/windmill-autoscaling/src/lib.rs +++ b/backend/windmill-autoscaling/src/lib.rs @@ -1,2 +1,4 @@ -mod autoscaling_ee; -pub use autoscaling_ee::*; +#[cfg(feature = "private")] +pub mod autoscaling_ee; +mod autoscaling_oss; +pub use autoscaling_oss::*; diff --git a/backend/windmill-common/Cargo.toml b/backend/windmill-common/Cargo.toml index 17764b1253..6a7a3b124b 100644 --- a/backend/windmill-common/Cargo.toml +++ b/backend/windmill-common/Cargo.toml @@ -7,6 +7,7 @@ edition.workspace = true [features] default = [] enterprise = [] +private = [] jemalloc = ["dep:tikv-jemalloc-ctl"] tantivy = [] prometheus = ["dep:prometheus"] diff --git a/backend/windmill-common/src/ee.rs b/backend/windmill-common/src/ee_oss.rs similarity index 63% rename from backend/windmill-common/src/ee.rs rename to backend/windmill-common/src/ee_oss.rs index 7acb430f1b..51b1efd2e2 100644 --- a/backend/windmill-common/src/ee.rs +++ b/backend/windmill-common/src/ee_oss.rs @@ -1,24 +1,35 @@ -#[cfg(feature = "enterprise")] +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::ee::*; + +#[cfg(all(feature = "enterprise", not(feature = "private")))] use crate::db::DB; -use crate::ee::LicensePlan::Community; -#[cfg(feature = "enterprise")] +#[cfg(not(feature = "private"))] +use crate::ee_oss::LicensePlan::Community; +#[cfg(all(feature = "enterprise", not(feature = "private")))] use crate::error; +#[cfg(not(feature = "private"))] use serde::Deserialize; +#[cfg(not(feature = "private"))] use std::sync::Arc; +#[cfg(not(feature = "private"))] use tokio::sync::RwLock; +#[cfg(not(feature = "private"))] lazy_static::lazy_static! { pub static ref LICENSE_KEY_VALID: Arc> = Arc::new(RwLock::new(true)); pub static ref LICENSE_KEY_ID: Arc> = Arc::new(RwLock::new("".to_string())); pub static ref LICENSE_KEY: Arc> = Arc::new(RwLock::new("".to_string())); } +#[cfg(not(feature = "private"))] pub enum LicensePlan { Community, Pro, Enterprise, } +#[cfg(not(feature = "private"))] pub async fn get_license_plan() -> LicensePlan { // Implementation is not open source return Community; @@ -26,6 +37,7 @@ pub async fn get_license_plan() -> LicensePlan { #[derive(Deserialize)] #[serde(untagged)] +#[cfg(not(feature = "private"))] pub enum CriticalErrorChannel { Email { email: String }, Slack { slack_channel: String }, @@ -33,6 +45,7 @@ pub enum CriticalErrorChannel { } #[derive(Deserialize)] +#[cfg(not(feature = "private"))] pub struct TeamsChannel { pub team_id: String, pub team_name: String, @@ -40,6 +53,7 @@ pub struct TeamsChannel { pub channel_name: String, } +#[cfg(not(feature = "private"))] pub enum CriticalAlertKind { #[cfg(feature = "enterprise")] CriticalError, @@ -47,7 +61,7 @@ pub enum CriticalAlertKind { RecoveredCriticalError, } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub async fn send_critical_alert( _error_message: String, _db: &DB, @@ -56,7 +70,7 @@ pub async fn send_critical_alert( ) { } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub async fn maybe_renew_license_key_on_start( _http_client: &reqwest::Client, _db: &crate::db::DB, @@ -66,14 +80,14 @@ pub async fn maybe_renew_license_key_on_start( force_renew_now } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub enum RenewReason { Manual, Schedule, OnStart, } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub async fn renew_license_key( _http_client: &reqwest::Client, _db: &crate::db::DB, @@ -84,7 +98,7 @@ pub async fn renew_license_key( "".to_string() } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub async fn create_customer_portal_session( _http_client: &reqwest::Client, _key: Option, @@ -93,14 +107,18 @@ pub async fn create_customer_portal_session( Ok("".to_string()) } -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub async fn worker_groups_alerts(_db: &DB) {} -#[cfg(feature = "enterprise")] +#[cfg(all(feature = "enterprise", not(feature = "private")))] pub async fn jobs_waiting_alerts(_db: &DB) {} -#[cfg(feature = "enterprise")] -pub async fn low_disk_alerts(_db: &DB, _server_mode: bool, _worker_mode: bool, _workers: Vec) { +#[cfg(all(feature = "enterprise", not(feature = "private")))] +pub async fn low_disk_alerts( + _db: &DB, + _server_mode: bool, + _worker_mode: bool, + _workers: Vec, +) { // Implementation is not open source } - diff --git a/backend/windmill-common/src/email_ee.rs b/backend/windmill-common/src/email_oss.rs similarity index 61% rename from backend/windmill-common/src/email_ee.rs rename to backend/windmill-common/src/email_oss.rs index 42aebbeec3..e6a340523e 100644 --- a/backend/windmill-common/src/email_ee.rs +++ b/backend/windmill-common/src/email_oss.rs @@ -1,5 +1,11 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::email_ee::*; + +#[cfg(not(feature = "private"))] use crate::server::Smtp; +#[cfg(not(feature = "private"))] pub async fn send_email( _subject: &str, _content: &str, diff --git a/backend/windmill-common/src/job_s3_helpers_ee.rs b/backend/windmill-common/src/job_s3_helpers_oss.rs similarity index 76% rename from backend/windmill-common/src/job_s3_helpers_ee.rs rename to backend/windmill-common/src/job_s3_helpers_oss.rs index d5d6ac4052..b7ebd57f3e 100644 --- a/backend/windmill-common/src/job_s3_helpers_ee.rs +++ b/backend/windmill-common/src/job_s3_helpers_oss.rs @@ -1,5 +1,11 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::job_s3_helpers_ee::*; + +#[cfg(not(feature = "private"))] use crate::s3_helpers::{ObjectStoreResource, StorageResourceType}; +#[cfg(not(feature = "private"))] pub async fn get_s3_resource_internal<'c>( _resource_type: StorageResourceType, _s3_resource_value_raw: serde_json::Value, @@ -9,11 +15,13 @@ pub async fn get_s3_resource_internal<'c>( todo!() } +#[cfg(not(feature = "private"))] pub enum TokenGenerator<'c> { AsClient(&'c crate::client::AuthedClient), AsServerInstance(), } +#[cfg(not(feature = "private"))] impl<'c> TokenGenerator<'c> { pub async fn gen_token( &self, @@ -24,7 +32,7 @@ impl<'c> TokenGenerator<'c> { } } -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", not(feature = "private")))] pub(crate) async fn generate_s3_aws_oidc_resource<'c>( _clone: crate::s3_helpers::S3AwsOidcResource, _token_generator: TokenGenerator<'c>, diff --git a/backend/windmill-common/src/lib.rs b/backend/windmill-common/src/lib.rs index 6d92cd8f55..315916d0d4 100644 --- a/backend/windmill-common/src/lib.rs +++ b/backend/windmill-common/src/lib.rs @@ -19,7 +19,7 @@ use std::{ use tokio::sync::broadcast; -use ee::CriticalErrorChannel; +use ee_oss::CriticalErrorChannel; use error::Error; use scripts::ScriptLang; use sqlx::{Pool, Postgres}; @@ -32,8 +32,12 @@ pub mod bench; pub mod cache; pub mod client; pub mod db; +#[cfg(feature = "private")] pub mod ee; +pub mod ee_oss; +#[cfg(feature = "private")] pub mod email_ee; +pub mod email_oss; pub mod error; pub mod external_ip; pub mod flow_status; @@ -41,25 +45,35 @@ pub mod flows; pub mod global_settings; pub mod indexer; pub mod job_metrics; -#[cfg(feature = "parquet")] +#[cfg(all(feature = "parquet", feature = "private"))] pub mod job_s3_helpers_ee; +#[cfg(feature = "parquet")] +pub mod job_s3_helpers_oss; -#[cfg(all(feature = "enterprise", feature = "openidconnect"))] +#[cfg(all(feature = "enterprise", feature = "openidconnect", feature = "private"))] pub mod oidc_ee; +#[cfg(all(feature = "enterprise", feature = "openidconnect"))] +pub mod oidc_oss; pub mod jobs; pub mod jwt; pub mod more_serde; pub mod oauth2; +#[cfg(feature = "private")] pub mod otel_ee; +pub mod otel_oss; pub mod queue; pub mod s3_helpers; pub mod schedule; pub mod schema; pub mod scripts; pub mod server; +#[cfg(feature = "private")] pub mod stats_ee; +pub mod stats_oss; +#[cfg(feature = "private")] pub mod teams_ee; +pub mod teams_oss; pub mod tracing_init; pub mod users; pub mod utils; diff --git a/backend/windmill-common/src/oidc_ee.rs b/backend/windmill-common/src/oidc_ee.rs deleted file mode 100644 index e7a157b04d..0000000000 --- a/backend/windmill-common/src/oidc_ee.rs +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Author: Ruben Fiszel - * Copyright: Windmill Labs, Inc 2023 - * This file and its contents are licensed under the AGPLv3 License. - * Please see the included NOTICE for copyright information and - * LICENSE-AGPL for a copy of the license. - */ - -use serde::{Deserialize, Serialize}; -use tokio::sync::RwLock; -#[cfg(all(feature = "enterprise", feature = "openidconnect"))] -use { - crate::db::DB, - crate::{auth::IdToken as WindmillIdToken, error::Result}, - anyhow, - openidconnect::{ - core::{CoreJwsSigningAlgorithm, CoreRsaPrivateSigningKey}, - IssuerUrl, JsonWebKeyId, - }, - std::process::Command, -}; - -#[cfg(feature = "openidconnect")] -use openidconnect::AdditionalClaims; - -#[cfg(feature = "openidconnect")] -impl AdditionalClaims for JobClaim {} - -#[cfg(feature = "openidconnect")] -impl AdditionalClaims for WorkspaceClaim {} - -#[cfg(feature = "openidconnect")] -impl AdditionalClaims for InstanceClaim {} - -#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -pub struct WorkspaceClaim { - pub workspace: String, -} - -#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -pub struct InstanceClaim {} - -#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -pub struct JobClaim { - pub job_id: String, - pub path: Option, - pub flow_path: Option, - pub groups: Vec, - pub username: String, - pub email: String, - pub workspace: String, -} - -lazy_static::lazy_static! { - static ref PRIVATE_KEY: RwLock> = RwLock::new(None); -} - -pub async fn generate_id_token( - db: Option<&DB>, - claim: T, - audience: &str, - identifier: String, - email: Option, -) -> Result { - use chrono::{Duration, Utc}; - use openidconnect::{ - core::{CoreGenderClaim, CoreJweContentEncryptionAlgorithm}, - Audience, EndUserEmail, IdToken, IdTokenClaims, StandardClaims, SubjectIdentifier, - }; - - let private_key = get_private_key(db).await?; - - let issue_url = format!("{}/api/oidc/", crate::BASE_URL.read().await.clone()); - let issue_time = Utc::now(); - let expiration = issue_time + Duration::try_hours(48).unwrap(); - let id_token = IdToken::< - T, - CoreGenderClaim, - CoreJweContentEncryptionAlgorithm, - CoreJwsSigningAlgorithm, - >::new( - IdTokenClaims::::new( - // Specify the issuer URL for the OpenID Connect Provider. - IssuerUrl::new(issue_url) - .map_err(|e| anyhow::anyhow!("Failed to generate IssueUrl: {}", e))?, - // The audience is usually a single entry with the client ID of the client for whom - // the ID token is intended. This is a required claim. - vec![Audience::new(audience.to_string())], - // The ID token expiration is usually much shorter than that of the access or refresh - // tokens issued to clients. - expiration, - // The issue time is usually the current time. - issue_time, - // Set the standard claims defined by the OpenID Connect Core spec. - StandardClaims::new( - // Stable subject identifiers are recommended in place of e-mail addresses or other - // potentially unstable identifiers. This is the only required claim. - SubjectIdentifier::new(identifier), - ) - // Optional: specify the user's e-mail address. This should only be provided if the - // client has been granted the 'profile' or 'email' scopes. - .set_email(email.map(|x| EndUserEmail::new(x))) - // Optional: specify whether the provider has verified the user's e-mail address. - .set_email_verified(Some(true)), - // OpenID Connect Providers may supply custom claims by providing a struct that - // implements the AdditionalClaims trait. This requires manually using the - // generic IdTokenClaims struct rather than the CoreIdTokenClaims type alias, - // however. - claim, - ), - // The private key used for signing the ID token. For confidential clients (those able - // to maintain a client secret), a CoreHmacKey can also be used, in conjunction - // with one of the CoreJwsSigningAlgorithm::HmacSha* signing algorithms. When using an - // HMAC-based signing algorithm, the UTF-8 representation of the client secret should - // be used as the HMAC key. - &CoreRsaPrivateSigningKey::from_pem( - &private_key, - Some(JsonWebKeyId::new("windmill".to_string())), - ) - .map_err(|e| anyhow::anyhow!("Invalid private key: {}", e))?, - // Uses the RS256 signature algorithm. This crate supports any RS*, PS*, or HS* - // signature algorithm. - CoreJwsSigningAlgorithm::RsaSsaPkcs1V15Sha256, - // When returning the ID token alongside an access token (e.g., in the Authorization Code - // flow), it is recommended to pass the access token here to set the `at_hash` claim - // automatically. - None, - // When returning the ID token alongside an authorization code (e.g., in the implicit - // flow), it is recommended to pass the authorization code here to set the `c_hash` claim - // automatically. - None, - ) - .map_err(|e| anyhow::anyhow!("Failed to generate token: {}", e))?; - - Ok(WindmillIdToken::new(id_token.to_string(), expiration)) -} - -#[cfg(all(feature = "enterprise", feature = "openidconnect"))] -pub async fn get_private_key(db: Option<&DB>) -> anyhow::Result { - if let Some(key) = PRIVATE_KEY.read().await.clone() { - return Ok(key); - } else if let Some(db) = db { - let key = sqlx::query_scalar!( - "SELECT value->>'private_key' FROM global_settings WHERE name = 'rsa_keys'", - ) - .fetch_optional(db) - .await? - .flatten(); - - let key = key.filter(|s| !s.is_empty()); - - if let Some(key) = key { - return Ok(key); - } else { - let keys = gen_pems(db).await?; - return Ok(keys.private_key); - } - } else { - return Err(anyhow::anyhow!("Private key not found and no db provided")); - } -} - -#[cfg(all(feature = "enterprise", feature = "openidconnect"))] -#[derive(Debug, Clone, serde::Serialize)] -struct Keys { - private_key: String, -} - -#[cfg(all(feature = "enterprise", feature = "openidconnect"))] -async fn gen_pems(db: &DB) -> anyhow::Result { - use anyhow::anyhow; - - let private_key_cmd = Command::new("openssl") - .arg("genrsa") - .arg("--traditional") - .arg("2048") - .output() - .expect("failed to execute process"); - - let private_key = String::from_utf8(private_key_cmd.stdout)?; - - tracing::debug!("Generated private key: {}", private_key); - - if private_key.is_empty() { - return Err(anyhow!("Failed to generate RSA key: key is empty")); - } - - let keys = Keys { private_key }; - - sqlx::query!( - r#"INSERT INTO global_settings (name, value) VALUES ('rsa_keys', $1)"#, - serde_json::to_value(&keys).unwrap() - ) - .execute(db) - .await?; - - Ok(keys) -} diff --git a/backend/windmill-common/src/oidc_oss.rs b/backend/windmill-common/src/oidc_oss.rs new file mode 100644 index 0000000000..0a42cee2ed --- /dev/null +++ b/backend/windmill-common/src/oidc_oss.rs @@ -0,0 +1,92 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::oidc_ee::*; + +/* + * Author: Ruben Fiszel + * Copyright: Windmill Labs, Inc 2023 + * This file and its contents are licensed under the AGPLv3 License. + * Please see the included NOTICE for copyright information and + * LICENSE-AGPL for a copy of the license. + */ + +#[cfg(not(feature = "private"))] +use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "private"))] +use tokio::sync::RwLock; +#[cfg(all( + feature = "enterprise", + feature = "openidconnect", + not(feature = "private") +))] +use { + crate::db::DB, + crate::{ + auth::IdToken as WindmillIdToken, + error::{Error, Result}, + }, + anyhow, +}; + +#[cfg(all(feature = "openidconnect", not(feature = "private")))] +use openidconnect::AdditionalClaims; + +#[cfg(all(feature = "openidconnect", not(feature = "private")))] +impl AdditionalClaims for JobClaim {} + +#[cfg(all(feature = "openidconnect", not(feature = "private")))] +impl AdditionalClaims for WorkspaceClaim {} + +#[cfg(all(feature = "openidconnect", not(feature = "private")))] +impl AdditionalClaims for InstanceClaim {} + +#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] +#[cfg(not(feature = "private"))] +pub struct WorkspaceClaim { + pub workspace: String, +} + +#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] +#[cfg(not(feature = "private"))] +pub struct InstanceClaim {} + +#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] +#[cfg(not(feature = "private"))] +pub struct JobClaim { + pub job_id: String, + pub path: Option, + pub flow_path: Option, + pub groups: Vec, + pub username: String, + pub email: String, + pub workspace: String, +} + +#[cfg(not(feature = "private"))] +lazy_static::lazy_static! { + static ref PRIVATE_KEY: RwLock> = RwLock::new(None); +} + +#[cfg(not(feature = "private"))] +pub async fn generate_id_token( + _db: Option<&DB>, + _claim: T, + _audience: &str, + _identifier: String, + _email: Option, +) -> Result { + Err(Error::internal_err( + "Not implemented in Windmill's Open Source repository".to_string(), + )) +} + +#[cfg(all( + feature = "enterprise", + feature = "openidconnect", + not(feature = "private") +))] +pub async fn get_private_key(_db: Option<&DB>) -> anyhow::Result { + Err(anyhow::anyhow!( + "Not implemented in Windmill's Open Source repository" + )) +} diff --git a/backend/windmill-common/src/otel_ee.rs b/backend/windmill-common/src/otel_oss.rs similarity index 60% rename from backend/windmill-common/src/otel_ee.rs rename to backend/windmill-common/src/otel_oss.rs index f3ada162f6..9225915636 100644 --- a/backend/windmill-common/src/otel_ee.rs +++ b/backend/windmill-common/src/otel_oss.rs @@ -1,3 +1,7 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::otel_ee::*; + /* * Author: Ruben Fiszel * Copyright: Windmill Labs, Inc 2022 @@ -6,43 +10,51 @@ * LICENSE-AGPL for a copy of the license. */ +#[cfg(not(feature = "private"))] use crate::{jobs::QueuedJob, utils::Mode}; +#[cfg(not(feature = "private"))] use uuid::Uuid; +#[cfg(not(feature = "private"))] pub fn set_span_parent(_span: &tracing::Span, _rj: &Uuid) {} -#[cfg(not(all(feature = "otel", feature = "enterprise")))] +#[cfg(all( + not(all(feature = "otel", feature = "enterprise")), + not(feature = "private") +))] pub(crate) type OtelProvider = Option<()>; -#[cfg(all(feature = "otel", feature = "enterprise"))] +#[cfg(all(feature = "otel", feature = "enterprise", not(feature = "private")))] pub(crate) type OtelProvider = Option; -#[cfg(not(feature = "otel"))] +#[cfg(all(not(feature = "otel"), not(feature = "private")))] pub fn otel_ctx() -> () {} -#[cfg(feature = "otel")] +#[cfg(all(feature = "otel", not(feature = "private")))] #[inline(always)] pub fn otel_ctx() -> opentelemetry::Context { opentelemetry::Context::current() } -#[cfg(not(feature = "otel"))] +#[cfg(all(not(feature = "otel"), not(feature = "private")))] impl FutureExt for T {} -#[cfg(not(feature = "otel"))] +#[cfg(all(not(feature = "otel"), not(feature = "private")))] pub trait FutureExt: Sized { fn with_context(self, _otel_cx: ()) -> Self { self } } +#[cfg(not(feature = "private"))] use tracing_subscriber::EnvFilter; +#[cfg(not(feature = "private"))] pub(crate) fn init_logs_bridge(_mode: &Mode, _hostname: &str, _env: &str) -> Option { None } -#[cfg(all(feature = "otel", feature = "enterprise"))] +#[cfg(all(feature = "otel", feature = "enterprise", not(feature = "private")))] pub(crate) fn init_otlp_tracer( _mode: &Mode, _hostname: &str, @@ -51,8 +63,10 @@ pub(crate) fn init_otlp_tracer( None } +#[cfg(not(feature = "private"))] pub(crate) fn init_meter_provider(_mode: &Mode, _hostname: &str, _env: &str) -> OtelProvider { None } +#[cfg(not(feature = "private"))] pub fn add_root_flow_job_to_otlp(_queued_job: &QueuedJob, _success: bool) {} diff --git a/backend/windmill-common/src/s3_helpers.rs b/backend/windmill-common/src/s3_helpers.rs index 7e7c48851e..171958f5cd 100644 --- a/backend/windmill-common/src/s3_helpers.rs +++ b/backend/windmill-common/src/s3_helpers.rs @@ -147,7 +147,7 @@ pub enum ObjectStoreReload { #[cfg(feature = "parquet")] pub async fn reload_object_store_setting(db: &crate::DB) -> ObjectStoreReload { use crate::{ - ee::{get_license_plan, LicensePlan}, + ee_oss::{get_license_plan, LicensePlan}, global_settings::{load_value_from_global_settings, OBJECT_STORE_CONFIG_SETTING}, s3_helpers::ObjectSettings, }; @@ -613,8 +613,8 @@ pub async fn build_object_store_from_settings( build_azure_blob_client(&azure_blob_resource).map(|x| ExpirableObjectStore::from(x)) } ObjectSettings::AwsOidc(ref s3_aws_oidc_settings) => { - let token_generator = crate::job_s3_helpers_ee::TokenGenerator::AsServerInstance(); - let res = crate::job_s3_helpers_ee::generate_s3_aws_oidc_resource( + let token_generator = crate::job_s3_helpers_oss::TokenGenerator::AsServerInstance(); + let res = crate::job_s3_helpers_oss::generate_s3_aws_oidc_resource( s3_aws_oidc_settings.clone(), token_generator, init_private_key, diff --git a/backend/windmill-common/src/stats_ee.rs b/backend/windmill-common/src/stats_oss.rs similarity index 73% rename from backend/windmill-common/src/stats_ee.rs rename to backend/windmill-common/src/stats_oss.rs index 5d2dc82b82..829e6e3a5b 100644 --- a/backend/windmill-common/src/stats_ee.rs +++ b/backend/windmill-common/src/stats_oss.rs @@ -1,17 +1,26 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::stats_ee::*; + +#[cfg(not(feature = "private"))] use sqlx::Postgres; +#[cfg(not(feature = "private"))] use crate::{error::Result, scripts::ScriptLang, DB}; +#[cfg(not(feature = "private"))] pub async fn get_disable_stats_setting(_db: &DB) -> bool { // stats details are closed source false } +#[cfg(not(feature = "private"))] pub async fn schedule_stats(_db: &DB, _http_client: &reqwest::Client) -> () { // stats details are closed source } +#[cfg(not(feature = "private"))] #[derive(Debug, sqlx::FromRow, serde::Serialize)] struct JobsUsage { language: Option, @@ -19,12 +28,14 @@ struct JobsUsage { count: i64, } +#[cfg(not(feature = "private"))] pub enum SendStatsReason { Manual, Schedule, OnStart, } +#[cfg(not(feature = "private"))] pub async fn send_stats( _http_client: &reqwest::Client, _db: &DB, @@ -34,11 +45,13 @@ pub async fn send_stats( Ok(()) } +#[cfg(not(feature = "private"))] pub struct ActiveUserUsage { pub author_count: Option, pub operator_count: Option, } +#[cfg(not(feature = "private"))] pub async fn get_user_usage<'c, E: sqlx::Executor<'c, Database = Postgres>>( _db: E, ) -> Result { diff --git a/backend/windmill-common/src/teams_ee.rs b/backend/windmill-common/src/teams_ee.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/backend/windmill-common/src/teams_oss.rs b/backend/windmill-common/src/teams_oss.rs new file mode 100644 index 0000000000..347ad8e6d7 --- /dev/null +++ b/backend/windmill-common/src/teams_oss.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::teams_ee::*; + + diff --git a/backend/windmill-common/src/tracing_init.rs b/backend/windmill-common/src/tracing_init.rs index 5ed5cec752..77194ac0a9 100644 --- a/backend/windmill-common/src/tracing_init.rs +++ b/backend/windmill-common/src/tracing_init.rs @@ -48,7 +48,7 @@ pub fn initialize_tracing( hostname: &str, mode: &Mode, environment: &str, -) -> (WorkerGuard, crate::otel_ee::OtelProvider) { +) -> (WorkerGuard, crate::otel_oss::OtelProvider) { let style = std::env::var("RUST_LOG_STYLE").unwrap_or_else(|_| "auto".into()); let rust_log_env = std::env::var("RUST_LOG"); @@ -70,16 +70,16 @@ pub fn initialize_tracing( LevelFilter::INFO }; - let meter_provider = crate::otel_ee::init_meter_provider(mode, hostname, environment); + let meter_provider = crate::otel_oss::init_meter_provider(mode, hostname, environment); #[cfg(all(feature = "otel", feature = "enterprise"))] - let opentelemetry = crate::otel_ee::init_otlp_tracer(mode, hostname, environment) + let opentelemetry = crate::otel_oss::init_otlp_tracer(mode, hostname, environment) .map(|x| tracing_opentelemetry::layer().with_tracer(x)); #[cfg(not(all(feature = "otel", feature = "enterprise")))] let opentelemetry: Option = None; - let logs_bridge = crate::otel_ee::init_logs_bridge(&mode, hostname, environment); + let logs_bridge = crate::otel_oss::init_logs_bridge(&mode, hostname, environment); use tracing_appender::rolling::{RollingFileAppender, Rotation}; diff --git a/backend/windmill-common/src/utils.rs b/backend/windmill-common/src/utils.rs index 3f1a1bd385..abd0840795 100644 --- a/backend/windmill-common/src/utils.rs +++ b/backend/windmill-common/src/utils.rs @@ -7,9 +7,9 @@ */ use crate::auth::is_devops_email; -use crate::ee::LICENSE_KEY_ID; +use crate::ee_oss::LICENSE_KEY_ID; #[cfg(feature = "enterprise")] -use crate::ee::{send_critical_alert, CriticalAlertKind}; +use crate::ee_oss::{send_critical_alert, CriticalAlertKind}; use crate::error::{to_anyhow, Error, Result}; use crate::global_settings::UNIQUE_ID_SETTING; use crate::DB; diff --git a/backend/windmill-git-sync/Cargo.toml b/backend/windmill-git-sync/Cargo.toml index d5a8412fae..6a0499639a 100644 --- a/backend/windmill-git-sync/Cargo.toml +++ b/backend/windmill-git-sync/Cargo.toml @@ -9,6 +9,7 @@ name = "windmill_git_sync" path = "./src/lib.rs" [features] +private = [] enterprise = ["windmill-queue/enterprise", "windmill-common/enterprise"] default = [] diff --git a/backend/windmill-git-sync/src/git_sync_ee.rs b/backend/windmill-git-sync/src/git_sync_oss.rs similarity index 69% rename from backend/windmill-git-sync/src/git_sync_ee.rs rename to backend/windmill-git-sync/src/git_sync_oss.rs index cc245d3d0c..70e2b53640 100644 --- a/backend/windmill-git-sync/src/git_sync_ee.rs +++ b/backend/windmill-git-sync/src/git_sync_oss.rs @@ -1,7 +1,14 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::git_sync_ee::*; + +#[cfg(not(feature = "private"))] use windmill_common::error::Result; +#[cfg(not(feature = "private"))] use crate::{DeployedObject, DB}; +#[cfg(not(feature = "private"))] pub async fn handle_deployment_metadata<'c>( _email: &str, _created_by: &str, diff --git a/backend/windmill-git-sync/src/lib.rs b/backend/windmill-git-sync/src/lib.rs index f1e0ed6ee3..d4e4ebf71f 100644 --- a/backend/windmill-git-sync/src/lib.rs +++ b/backend/windmill-git-sync/src/lib.rs @@ -10,9 +10,11 @@ use sqlx::{Pool, Postgres}; use windmill_common::scripts::ScriptHash; +#[cfg(feature = "private")] pub mod git_sync_ee; +pub mod git_sync_oss; -pub use git_sync_ee::handle_deployment_metadata; +pub use git_sync_oss::handle_deployment_metadata; pub type DB = Pool; #[derive(Clone, Debug)] diff --git a/backend/windmill-indexer/Cargo.toml b/backend/windmill-indexer/Cargo.toml index 14ab53beef..ea95d6237d 100644 --- a/backend/windmill-indexer/Cargo.toml +++ b/backend/windmill-indexer/Cargo.toml @@ -11,6 +11,7 @@ path = "src/lib.rs" [features] default = [] parquet = ["dep:object_store"] +private = [] enterprise = [] [dependencies] diff --git a/backend/windmill-indexer/src/completed_runs_ee.rs b/backend/windmill-indexer/src/completed_runs_oss.rs similarity index 66% rename from backend/windmill-indexer/src/completed_runs_ee.rs rename to backend/windmill-indexer/src/completed_runs_oss.rs index f5c6c98cf8..083f8744fa 100644 --- a/backend/windmill-indexer/src/completed_runs_ee.rs +++ b/backend/windmill-indexer/src/completed_runs_oss.rs @@ -1,17 +1,28 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::completed_runs_ee::*; + +#[cfg(not(feature = "private"))] use anyhow::anyhow; +#[cfg(not(feature = "private"))] use sqlx::{Pool, Postgres}; +#[cfg(not(feature = "private"))] use windmill_common::error::Error; +#[cfg(not(feature = "private"))] #[derive(Clone)] pub struct IndexReader; +#[cfg(not(feature = "private"))] #[derive(Clone)] pub struct IndexWriter; +#[cfg(not(feature = "private"))] pub async fn init_index(_db: &Pool) -> Result<(IndexReader, IndexWriter), Error> { Err(anyhow!("Cannot initialize index: not in EE").into()) } +#[cfg(not(feature = "private"))] pub async fn run_indexer( _db: Pool, mut _index_writer: IndexWriter, diff --git a/backend/windmill-indexer/src/indexer_ee.rs b/backend/windmill-indexer/src/indexer_ee.rs deleted file mode 100644 index 8b13789179..0000000000 --- a/backend/windmill-indexer/src/indexer_ee.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/backend/windmill-indexer/src/indexer_oss.rs b/backend/windmill-indexer/src/indexer_oss.rs new file mode 100644 index 0000000000..198c14e526 --- /dev/null +++ b/backend/windmill-indexer/src/indexer_oss.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::indexer_ee::*; + + diff --git a/backend/windmill-indexer/src/lib.rs b/backend/windmill-indexer/src/lib.rs index 59c6a627f7..6c13b551d1 100644 --- a/backend/windmill-indexer/src/lib.rs +++ b/backend/windmill-indexer/src/lib.rs @@ -1,3 +1,9 @@ +#[cfg(feature = "private")] pub mod completed_runs_ee; +pub mod completed_runs_oss; +#[cfg(feature = "private")] pub mod indexer_ee; +pub mod indexer_oss; +#[cfg(feature = "private")] pub mod service_logs_ee; +pub mod service_logs_oss; diff --git a/backend/windmill-indexer/src/service_logs_ee.rs b/backend/windmill-indexer/src/service_logs_oss.rs similarity index 68% rename from backend/windmill-indexer/src/service_logs_ee.rs rename to backend/windmill-indexer/src/service_logs_oss.rs index e04575d3f5..b6e9017f88 100644 --- a/backend/windmill-indexer/src/service_logs_ee.rs +++ b/backend/windmill-indexer/src/service_logs_oss.rs @@ -1,13 +1,24 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::service_logs_ee::*; + +#[cfg(not(feature = "private"))] use anyhow::anyhow; +#[cfg(not(feature = "private"))] use sqlx::{Pool, Postgres}; +#[cfg(not(feature = "private"))] use windmill_common::error::Error; +#[cfg(not(feature = "private"))] use windmill_common::KillpillSender; #[derive(Clone)] +#[cfg(not(feature = "private"))] pub struct ServiceLogIndexReader; #[derive(Clone)] +#[cfg(not(feature = "private"))] pub struct ServiceLogIndexWriter; +#[cfg(not(feature = "private"))] pub async fn init_index( _db: &Pool, mut _killpill_tx: KillpillSender, @@ -15,6 +26,7 @@ pub async fn init_index( Err(anyhow!("Cannot initialize index: not in EE").into()) } +#[cfg(not(feature = "private"))] pub async fn run_indexer( _db: Pool, mut _index_writer: ServiceLogIndexWriter, diff --git a/backend/windmill-queue/Cargo.toml b/backend/windmill-queue/Cargo.toml index a90fa6ccf7..4458e8aa99 100644 --- a/backend/windmill-queue/Cargo.toml +++ b/backend/windmill-queue/Cargo.toml @@ -10,6 +10,7 @@ path = "src/lib.rs" [features] default = [] +private = [] enterprise = ["windmill-common/enterprise"] cloud = [] benchmark = ["windmill-common/benchmark"] diff --git a/backend/windmill-queue/src/jobs.rs b/backend/windmill-queue/src/jobs.rs index de64071c42..7f7863c927 100644 --- a/backend/windmill-queue/src/jobs.rs +++ b/backend/windmill-queue/src/jobs.rs @@ -25,7 +25,7 @@ use sqlx::{types::Json, FromRow, Pool, Postgres, Transaction}; use tokio::{sync::RwLock, time::sleep}; use ulid::Ulid; use uuid::Uuid; -use windmill_audit::audit_ee::{audit_log, AuditAuthor}; +use windmill_audit::audit_oss::{audit_log, AuditAuthor}; use windmill_audit::ActionKind; #[cfg(feature = "benchmark")] @@ -71,7 +71,7 @@ use windmill_common::BASE_URL; use windmill_common::users::SUPERADMIN_SYNC_EMAIL; use crate::flow_status::{update_flow_status_in_progress, update_workflow_as_code_status}; -use crate::jobs_ee::update_concurrency_counter; +use crate::jobs_oss::update_concurrency_counter; use crate::schedule::{get_schedule_opt, push_scheduled_job}; use crate::tags::per_workspace_tag; diff --git a/backend/windmill-queue/src/jobs_ee.rs b/backend/windmill-queue/src/jobs_oss.rs similarity index 67% rename from backend/windmill-queue/src/jobs_ee.rs rename to backend/windmill-queue/src/jobs_oss.rs index ea1f86b529..987a56bf0d 100644 --- a/backend/windmill-queue/src/jobs_ee.rs +++ b/backend/windmill-queue/src/jobs_oss.rs @@ -1,7 +1,15 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::jobs_ee::*; + +#[cfg(not(feature = "private"))] use chrono::{DateTime, Utc}; +#[cfg(not(feature = "private"))] use uuid::Uuid; +#[cfg(not(feature = "private"))] use windmill_common::DB; +#[cfg(not(feature = "private"))] #[allow(dead_code)] pub(crate) async fn update_concurrency_counter( _db: &DB, diff --git a/backend/windmill-queue/src/lib.rs b/backend/windmill-queue/src/lib.rs index 2496bdf818..9b6025e515 100644 --- a/backend/windmill-queue/src/lib.rs +++ b/backend/windmill-queue/src/lib.rs @@ -7,7 +7,9 @@ */ mod jobs; +#[cfg(feature = "private")] pub mod jobs_ee; +pub mod jobs_oss; pub mod schedule; pub use jobs::*; pub mod flow_status; diff --git a/backend/windmill-queue/src/schedule.rs b/backend/windmill-queue/src/schedule.rs index bb7d5df906..294ece7509 100644 --- a/backend/windmill-queue/src/schedule.rs +++ b/backend/windmill-queue/src/schedule.rs @@ -13,7 +13,7 @@ use sqlx::{PgExecutor, Postgres, Transaction}; use std::collections::HashMap; use std::str::FromStr; use windmill_common::db::Authed; -use windmill_common::ee::LICENSE_KEY_VALID; +use windmill_common::ee_oss::LICENSE_KEY_VALID; use windmill_common::flows::Retry; use windmill_common::get_latest_flow_version_info_for_path; use windmill_common::jobs::JobPayload; diff --git a/backend/windmill-worker/Cargo.toml b/backend/windmill-worker/Cargo.toml index 6a6a0abf01..a3b36a5c04 100644 --- a/backend/windmill-worker/Cargo.toml +++ b/backend/windmill-worker/Cargo.toml @@ -10,6 +10,7 @@ path = "src/lib.rs" [features] default = [] +private = [] prometheus = ["dep:prometheus", "windmill-common/prometheus"] enterprise = ["windmill-queue/enterprise", "windmill-git-sync/enterprise", "windmill-common/enterprise", "dep:pem", "dep:tokio-util"] mssql = ["dep:tiberius"] diff --git a/backend/windmill-worker/src/common.rs b/backend/windmill-worker/src/common.rs index 9955256d13..45f03ee056 100644 --- a/backend/windmill-worker/src/common.rs +++ b/backend/windmill-worker/src/common.rs @@ -728,7 +728,7 @@ async fn get_workspace_s3_resource_path( storage: Option<&String>, ) -> windmill_common::error::Result> { use windmill_common::{ - job_s3_helpers_ee::get_s3_resource_internal, s3_helpers::StorageResourceType, + job_s3_helpers_oss::get_s3_resource_internal, s3_helpers::StorageResourceType, }; let raw_lfs_opt = if let Some(storage) = storage { @@ -786,7 +786,7 @@ async fn get_workspace_s3_resource_path( get_s3_resource_internal( rt, s3_resource_value_raw, - windmill_common::job_s3_helpers_ee::TokenGenerator::AsClient(client), + windmill_common::job_s3_helpers_oss::TokenGenerator::AsClient(client), db, ) .await @@ -1209,8 +1209,8 @@ pub async fn par_install_language_dependencies<'a>( } #[cfg(all(feature = "enterprise", feature = "parquet"))] let is_not_pro = !matches!( - windmill_common::ee::get_license_plan().await, - windmill_common::ee::LicensePlan::Pro + windmill_common::ee_oss::get_license_plan().await, + windmill_common::ee_oss::LicensePlan::Pro ); #[cfg(all(feature = "enterprise", feature = "parquet"))] if is_not_pro && matches!(install_fn, InstallStrategy::AllAtOnce(_)) { diff --git a/backend/windmill-worker/src/handle_child.rs b/backend/windmill-worker/src/handle_child.rs index 3eb9e95dc9..498e0b3c0d 100644 --- a/backend/windmill-worker/src/handle_child.rs +++ b/backend/windmill-worker/src/handle_child.rs @@ -53,7 +53,7 @@ use futures::{ use crate::common::{resolve_job_timeout, OccupancyMetrics}; use crate::job_logger::{append_job_logs, append_with_limit}; -use crate::job_logger_ee::process_streaming_log_lines; +use crate::job_logger_oss::process_streaming_log_lines; use crate::worker_utils::{ping_job_status, update_worker_ping_from_job}; use crate::{MAX_RESULT_SIZE, MAX_WAIT_FOR_SIGINT, MAX_WAIT_FOR_SIGTERM}; diff --git a/backend/windmill-worker/src/job_logger.rs b/backend/windmill-worker/src/job_logger.rs index f4abd1d0c2..626dfbce44 100644 --- a/backend/windmill-worker/src/job_logger.rs +++ b/backend/windmill-worker/src/job_logger.rs @@ -13,10 +13,10 @@ use std::sync::Arc; use uuid::Uuid; #[cfg(not(all(feature = "enterprise", feature = "parquet")))] -use crate::job_logger_ee::default_disk_log_storage; +use crate::job_logger_oss::default_disk_log_storage; #[cfg(all(feature = "enterprise", feature = "parquet"))] -use crate::job_logger_ee::s3_storage; +use crate::job_logger_oss::s3_storage; pub enum CompactLogs { #[cfg(not(all(feature = "enterprise", feature = "parquet")))] diff --git a/backend/windmill-worker/src/job_logger_ee.rs b/backend/windmill-worker/src/job_logger_oss.rs similarity index 68% rename from backend/windmill-worker/src/job_logger_ee.rs rename to backend/windmill-worker/src/job_logger_oss.rs index 22772878ee..3ee3d29a3a 100644 --- a/backend/windmill-worker/src/job_logger_ee.rs +++ b/backend/windmill-worker/src/job_logger_oss.rs @@ -1,13 +1,14 @@ -use std::io; -use std::sync::atomic::AtomicU32; -use std::sync::Arc; +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::job_logger_ee::*; -use uuid::Uuid; -use windmill_common::DB; +#[cfg(not(feature = "private"))] +use { + crate::job_logger::CompactLogs, std::io, std::sync::atomic::AtomicU32, std::sync::Arc, + uuid::Uuid, windmill_common::DB, +}; -use crate::job_logger::CompactLogs; - -#[cfg(all(feature = "enterprise", feature = "parquet"))] +#[cfg(all(feature = "enterprise", feature = "parquet", not(feature = "private")))] pub(crate) async fn s3_storage( _job_id: &Uuid, _w_id: &str, @@ -19,6 +20,7 @@ pub(crate) async fn s3_storage( tracing::info!("Logs length of {_job_id} has exceeded a threshold. Implementation to store excess on s3 in not OSS"); } +#[cfg(not(feature = "private"))] #[allow(dead_code)] pub(crate) async fn default_disk_log_storage( job_id: &Uuid, @@ -32,6 +34,7 @@ pub(crate) async fn default_disk_log_storage( tracing::info!("Logs length of {job_id} has exceeded a threshold. Implementation to store excess on disk in not OSS"); } +#[cfg(not(feature = "private"))] pub(crate) fn process_streaming_log_lines( r: Result, io::Error>, _stderr: bool, diff --git a/backend/windmill-worker/src/lib.rs b/backend/windmill-worker/src/lib.rs index fa6eb10960..653381ed14 100644 --- a/backend/windmill-worker/src/lib.rs +++ b/backend/windmill-worker/src/lib.rs @@ -27,7 +27,9 @@ mod go_executor; mod graphql_executor; mod handle_child; pub mod job_logger; -mod job_logger_ee; +#[cfg(feature = "private")] +pub mod job_logger_ee; +mod job_logger_oss; mod js_eval; #[cfg(feature = "mysql")] mod mysql_executor; @@ -35,7 +37,9 @@ mod mysql_executor; mod nu_executor; #[cfg(feature = "oracledb")] mod oracledb_executor; -mod otel_ee; +#[cfg(feature = "private")] +pub mod otel_ee; +mod otel_oss; mod pg_executor; #[cfg(feature = "php")] mod php_executor; diff --git a/backend/windmill-worker/src/otel_ee.rs b/backend/windmill-worker/src/otel_ee.rs deleted file mode 100644 index 311ffd6355..0000000000 --- a/backend/windmill-worker/src/otel_ee.rs +++ /dev/null @@ -1,3 +0,0 @@ -use windmill_queue::MiniPulledJob; - -pub fn add_root_flow_job_to_otlp(_queued_job: &MiniPulledJob, _success: bool) {} diff --git a/backend/windmill-worker/src/otel_oss.rs b/backend/windmill-worker/src/otel_oss.rs new file mode 100644 index 0000000000..2f65c534b4 --- /dev/null +++ b/backend/windmill-worker/src/otel_oss.rs @@ -0,0 +1,9 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::otel_ee::*; + +#[cfg(not(feature = "private"))] +use windmill_queue::MiniPulledJob; + +#[cfg(not(feature = "private"))] +pub fn add_root_flow_job_to_otlp(_queued_job: &MiniPulledJob, _success: bool) {} diff --git a/backend/windmill-worker/src/python_executor.rs b/backend/windmill-worker/src/python_executor.rs index 76ee967656..3a4898acc1 100644 --- a/backend/windmill-worker/src/python_executor.rs +++ b/backend/windmill-worker/src/python_executor.rs @@ -20,7 +20,7 @@ use tokio::{ }; use uuid::Uuid; #[cfg(all(feature = "enterprise", feature = "parquet", unix))] -use windmill_common::ee::{get_license_plan, LicensePlan}; +use windmill_common::ee_oss::{get_license_plan, LicensePlan}; use windmill_common::{ error::{ self, diff --git a/backend/windmill-worker/src/result_processor.rs b/backend/windmill-worker/src/result_processor.rs index 342c53a301..2fc9e32bb7 100644 --- a/backend/windmill-worker/src/result_processor.rs +++ b/backend/windmill-worker/src/result_processor.rs @@ -12,7 +12,7 @@ use std::{ }; use tracing::{field, Instrument}; #[cfg(not(feature = "otel"))] -use windmill_common::otel_ee::FutureExt; +use windmill_common::otel_oss::FutureExt; use uuid::Uuid; @@ -41,7 +41,7 @@ use windmill_queue::{add_completed_job, add_completed_job_error}; use crate::{ bash_executor::ANSI_ESCAPE_RE, common::{error_to_value, read_result, save_in_cache}, - otel_ee::add_root_flow_job_to_otlp, + otel_oss::add_root_flow_job_to_otlp, worker_flow::update_flow_status_after_job_completion, JobCompletedReceiver, JobCompletedSender, SameWorkerSender, SendResult, UpdateFlow, INIT_SCRIPT_TAG, @@ -76,7 +76,7 @@ async fn process_jc( } else { jc.job.id }; - windmill_common::otel_ee::set_span_parent(&span, &rj); + windmill_common::otel_oss::set_span_parent(&span, &rj); if let Some(lg) = jc.job.script_lang.as_ref() { span.record("language", lg.as_str()); @@ -276,7 +276,7 @@ pub fn start_background_processor( async fn send_job_completed(job_completed_tx: JobCompletedSender, jc: JobCompleted) { job_completed_tx .send_job(jc, true) - .with_context(windmill_common::otel_ee::otel_ctx()) + .with_context(windmill_common::otel_oss::otel_ctx()) .await .expect("send job completed") } @@ -312,7 +312,7 @@ pub async fn process_result( duration, }, ) - .with_context(windmill_common::otel_ee::otel_ctx()) + .with_context(windmill_common::otel_oss::otel_ctx()) .await; Ok(true) } @@ -374,7 +374,7 @@ pub async fn process_result( duration, }, ) - .with_context(windmill_common::otel_ee::otel_ctx()) + .with_context(windmill_common::otel_oss::otel_ctx()) .await; Ok(false) } diff --git a/backend/windmill-worker/src/worker.rs b/backend/windmill-worker/src/worker.rs index e15c24ef70..a9e6d9015d 100644 --- a/backend/windmill-worker/src/worker.rs +++ b/backend/windmill-worker/src/worker.rs @@ -27,7 +27,7 @@ use windmill_common::{ }; #[cfg(feature = "enterprise")] -use windmill_common::ee::LICENSE_KEY_VALID; +use windmill_common::ee_oss::LICENSE_KEY_VALID; use anyhow::Result; use const_format::concatcp; @@ -1526,7 +1526,7 @@ pub async fn run_worker( span.record("root_job", root_job.to_string().as_str()); } - windmill_common::otel_ee::set_span_parent(&span, &rj); + windmill_common::otel_oss::set_span_parent(&span, &rj); // span.context().span().add_event_with_timestamp("job created".to_string(), arc_job.created_at.into(), vec![]); match handle_queued_job( diff --git a/backend/windmill-worker/src/worker_flow.rs b/backend/windmill-worker/src/worker_flow.rs index 6c0b133828..e846ea35db 100644 --- a/backend/windmill-worker/src/worker_flow.rs +++ b/backend/windmill-worker/src/worker_flow.rs @@ -66,7 +66,7 @@ use windmill_queue::{ type DB = sqlx::Pool; -use windmill_audit::audit_ee::{audit_log, AuditAuthor}; +use windmill_audit::audit_oss::{audit_log, AuditAuthor}; use windmill_audit::ActionKind; use windmill_queue::{canceled_job_to_result, push};