EE Refactor (#5844)

* app compiles with every ee substituted

* Replace all oss files content

* Revert "Replace all oss files content"

This reverts commit ea4017d59f.

* delete all ee

* hide all _ee files under private flag

* hide every oss stuff when private flag set

* pub use *

* gitignore and substitute script

* pub mod for ee needed for ee repo

* small mistakes

* remove oidc_oss impl

* ee ref (temp)

* ee ref

* fix --all-features selecting private in OSS CI

* ee repo ref

* allow unused
This commit is contained in:
Diego Imbert
2025-06-02 22:12:33 +02:00
committed by GitHub
parent 64f35d050f
commit 0e316239dd
109 changed files with 851 additions and 523 deletions
+1 -1
View File
@@ -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
+2 -1
View File
@@ -6,4 +6,5 @@ tracing.folded
heaptrack*
index/
windmill-api/openapi-*.*
.duckdb/*
.duckdb/*
*ee.rs
+2 -1
View File
@@ -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]
+20
View File
@@ -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
+1 -1
View File
@@ -1 +1 @@
8a2506e86b923c00522cb83b052586f705f7aa8e
70895a4a8f8891032c5b478a37ab6fafd0d4a9d0
+6 -1
View File
@@ -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
}
+12 -8
View File
@@ -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;
}
}
},
+7 -7
View File
@@ -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<HashMap<String, windmill_api::oauth2_ee::OAuthClient>>,
Option<HashMap<String, windmill_api::oauth2_oss::OAuthClient>>,
>(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();
}
+8 -26
View File
@@ -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
+1 -1
View File
@@ -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
+1
View File
@@ -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 = []
@@ -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<String>,
@@ -43,8 +53,10 @@ pub struct AgentAuth {
pub exp: Option<usize>,
}
#[cfg(not(feature = "private"))]
pub struct AgentCache {}
#[cfg(not(feature = "private"))]
impl AgentCache {
pub fn new() -> Self {
AgentCache {}
+1 -1
View File
@@ -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! {
+2 -2
View File
@@ -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},
-5
View File
@@ -1,5 +0,0 @@
use axum::Router;
pub fn global_unauthed_service() -> Router {
Router::new()
}
+11
View File
@@ -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()
}
+1 -1
View File
@@ -85,7 +85,7 @@ impl RawWebhookArgs {
db: &DB,
w_id: &str,
) -> Result<HashMap<String, Box<RawValue>>, 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;
+2 -2
View File
@@ -28,7 +28,7 @@ async fn get_audit(
Path((w_id, id)): Path<(String, i32)>,
) -> JsonResult<AuditLog> {
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<ListAuditLogQuery>,
) -> JsonResult<Vec<AuditLog>> {
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))
}
+2 -2
View File
@@ -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(),
+4 -4
View File
@@ -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<StatusCode> {
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, _, _) =
+1 -1
View File
@@ -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},
+1 -1
View File
@@ -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,
@@ -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<Arc<RwLock<Self>>> {
// Implementation is not open source
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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,
@@ -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<String>,
@@ -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<chrono::DateTime<chrono::Utc>>,
pub enabled: bool,
}
#[cfg(not(feature = "private"))]
impl TriggerJobArgs<String> for GcpTrigger {
fn v1_payload_fn(payload: String) -> HashMap<String, Box<RawValue>> {
HashMap::from([("payload".to_string(), to_raw_value(&payload))])
-9
View File
@@ -1,9 +0,0 @@
use axum::routing::Router;
pub fn workspaced_service() -> Router {
Router::new()
}
pub fn global_service() -> Router {
Router::new()
}
+16
View File
@@ -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()
}
+1 -1
View File
@@ -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::{
+2 -2
View File
@@ -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;
-9
View File
@@ -1,9 +0,0 @@
use axum::Router;
pub fn workspaced_service() -> Router {
Router::new()
}
pub fn global_service() -> Router {
Router::new()
}
+16
View File
@@ -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()
}
@@ -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<String>,
}
#[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>) -> 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<dyn ObjectStore>,
_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<dyn ObjectStore>,
_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,
+2 -2
View File
@@ -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 {
@@ -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<String>,
pub enabled: bool,
}
}
+94 -54
View File
@@ -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()
+1 -1
View File
@@ -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},
@@ -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<String>,
pub enabled: bool,
}
}
@@ -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<Vec<String>>,
_userinfo_url: Option<String>,
}
#[cfg(feature = "oauth2")]
#[cfg(all(feature = "oauth2", not(feature = "private")))]
pub type BasicClientsMap = HashMap<String, ClientWithScopes>;
#[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<bool>,
}
#[cfg(not(feature = "private"))]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OAuthClient {
id: String,
@@ -71,7 +88,7 @@ pub struct OAuthClient {
login_config: Option<OAuthConfig>,
}
#[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<OClient>,
}
#[cfg(feature = "oauth2")]
#[cfg(all(feature = "oauth2", not(feature = "private")))]
pub async fn build_oauth_clients(
_base_url: &str,
_oauths_from_config: Option<HashMap<String, OAuthClient>>,
@@ -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<Vec<Scope>>,
}
#[cfg(not(feature = "private"))]
#[derive(Serialize)]
struct Logins {
oauth: Vec<String>,
saml: Option<String>,
}
#[cfg(not(feature = "private"))]
async fn list_logins() -> error::JsonResult<Logins> {
// 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<Vec<String>> {
Ok(Json(
(&OAUTH_CLIENTS.read().await.connects)
@@ -127,12 +147,14 @@ async fn list_connects() -> error::JsonResult<Vec<String>> {
))
}
#[cfg(not(feature = "oauth2"))]
async fn list_connects() -> error::JsonResult<Vec<String>> {
#[allow(unused)]
#[cfg(not(all(feature = "oauth2", not(feature = "private"))))]
async fn list_connects() -> windmill_common::error::JsonResult<Vec<String>> {
// 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<S: AsRef<[u8]>>(secret: S) -> anyhow::Result<SlackVerifier> {
HmacSha256::new_from_slice(secret.as_ref())
@@ -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()
}
@@ -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(
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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,
@@ -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<ServiceProviderExt> {
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()
+1 -1
View File
@@ -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,
@@ -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<B>(_request: Request<B>, _next: Next) -> Response {
//Not implemented in open-source version
todo!()
+1 -1
View File
@@ -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;
+8 -8
View File
@@ -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<String> {
pub async fn send_stats(Extension(db): Extension<DB>, authed: ApiAuthed) -> Result<String> {
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<String> {
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<LicenseQuery>,
) -> Result<String> {
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);
}
@@ -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<AuthCache>,
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<Self>, _addr: SocketAddr) -> anyhow::Result<()> {
let _ = self.auth_cache;
@@ -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<String>,
pub last_server_ping: Option<chrono::DateTime<chrono::Utc>>,
pub enabled: bool,
}
}
-5
View File
@@ -1,5 +0,0 @@
use axum::Router;
pub fn add_stripe_routes(router: Router) -> Router {
return router;
}
+11
View File
@@ -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;
}
@@ -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<StatusCode, Error> {
Err(Error::InternalErr("enterprise feature only".to_string()))
}
}
@@ -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<StatusCode, Error> {
return Err(Error::BadRequest(
"Teams only available on enterprise".to_string(),
));
}
#[cfg(not(feature = "private"))]
pub async fn workspaces_list_available_teams_ids() -> Result<StatusCode, Error> {
return Err(Error::BadRequest(
"Teams only available on enterprise".to_string(),
));
}
#[cfg(not(feature = "private"))]
pub async fn connect_teams() -> Result<StatusCode, Error> {
return Err(Error::BadRequest(
"Teams only available on enterprise".to_string(),
));
}
#[cfg(not(feature = "private"))]
pub async fn run_teams_message_test_job() -> Result<StatusCode, Error> {
return Err(Error::BadRequest(
"Teams only available on enterprise".to_string(),
));
}
#[cfg(not(feature = "private"))]
pub async fn workspaces_list_available_teams_channels() -> Result<StatusCode, Error> {
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()
}
}
+4 -4
View File
@@ -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<Arc<Argon2<'_>>>,
Json(nu): Json<NewUser>,
) -> 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<EditPassword>,
) -> Result<String> {
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<EditPassword>,
) -> Result<String> {
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(
@@ -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<Argon2<'_>>,
@@ -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"
+3 -3
View File
@@ -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,
@@ -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},
+5 -5
View File
@@ -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<String>,
Json(ea): Json<EditAutoInvite>,
) -> Result<String> {
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(
@@ -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
+1 -1
View File
@@ -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;
@@ -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,
+1
View File
@@ -10,6 +10,7 @@ path = "./src/lib.rs"
[features]
enterprise = ["windmill-common/enterprise"]
private = []
[dependencies]
serde.workspace = true
@@ -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<String>,
}
#[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<AuditLog> {
// Implementation is not open source as Audit logs is a Windmill Enterprise Edition feature
tx.commit().await?;
+2
View File
@@ -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")]
+1
View File
@@ -10,6 +10,7 @@ path = "./src/lib.rs"
[features]
enterprise = ["windmill-queue/enterprise", "windmill-common/enterprise"]
private = []
default = []
[dependencies]
@@ -1,6 +0,0 @@
use windmill_common::DB;
pub async fn apply_all_autoscaling(_db: &DB) -> anyhow::Result<()> {
// Autoscaling is an ee feature
Ok(())
}
@@ -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(())
}
+4 -2
View File
@@ -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::*;
+1
View File
@@ -7,6 +7,7 @@ edition.workspace = true
[features]
default = []
enterprise = []
private = []
jemalloc = ["dep:tikv-jemalloc-ctl"]
tantivy = []
prometheus = ["dep:prometheus"]
@@ -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<RwLock<bool>> = Arc::new(RwLock::new(true));
pub static ref LICENSE_KEY_ID: Arc<RwLock<String>> = Arc::new(RwLock::new("".to_string()));
pub static ref LICENSE_KEY: Arc<RwLock<String>> = 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<String>,
@@ -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<String>) {
#[cfg(all(feature = "enterprise", not(feature = "private")))]
pub async fn low_disk_alerts(
_db: &DB,
_server_mode: bool,
_worker_mode: bool,
_workers: Vec<String>,
) {
// Implementation is not open source
}
@@ -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,
@@ -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>,
+17 -3
View File
@@ -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;
-198
View File
@@ -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<String>,
pub flow_path: Option<String>,
pub groups: Vec<String>,
pub username: String,
pub email: String,
pub workspace: String,
}
lazy_static::lazy_static! {
static ref PRIVATE_KEY: RwLock<Option<String>> = RwLock::new(None);
}
pub async fn generate_id_token<T: AdditionalClaims>(
db: Option<&DB>,
claim: T,
audience: &str,
identifier: String,
email: Option<String>,
) -> Result<WindmillIdToken> {
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::<T, CoreGenderClaim>::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<String> {
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<Keys> {
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)
}
+92
View File
@@ -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<String>,
pub flow_path: Option<String>,
pub groups: Vec<String>,
pub username: String,
pub email: String,
pub workspace: String,
}
#[cfg(not(feature = "private"))]
lazy_static::lazy_static! {
static ref PRIVATE_KEY: RwLock<Option<String>> = RwLock::new(None);
}
#[cfg(not(feature = "private"))]
pub async fn generate_id_token<T: AdditionalClaims>(
_db: Option<&DB>,
_claim: T,
_audience: &str,
_identifier: String,
_email: Option<String>,
) -> Result<WindmillIdToken> {
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<String> {
Err(anyhow::anyhow!(
"Not implemented in Windmill's Open Source repository"
))
}
@@ -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<opentelemetry_sdk::metrics::SdkMeterProvider>;
#[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<T: Sized> 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<EnvFilter> {
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) {}
+3 -3
View File
@@ -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,
@@ -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<ScriptLang>,
@@ -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<i32>,
pub operator_count: Option<i32>,
}
#[cfg(not(feature = "private"))]
pub async fn get_user_usage<'c, E: sqlx::Executor<'c, Database = Postgres>>(
_db: E,
) -> Result<ActiveUserUsage> {
+5
View File
@@ -0,0 +1,5 @@
#[cfg(feature = "private")]
#[allow(unused)]
pub use crate::teams_ee::*;
+4 -4
View File
@@ -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<EnvFilter> = 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};
+2 -2
View File
@@ -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;
+1
View File
@@ -9,6 +9,7 @@ name = "windmill_git_sync"
path = "./src/lib.rs"
[features]
private = []
enterprise = ["windmill-queue/enterprise", "windmill-common/enterprise"]
default = []
@@ -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,
+3 -1
View File
@@ -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<Postgres>;
#[derive(Clone, Debug)]
+1
View File
@@ -11,6 +11,7 @@ path = "src/lib.rs"
[features]
default = []
parquet = ["dep:object_store"]
private = []
enterprise = []
[dependencies]
@@ -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<Postgres>) -> Result<(IndexReader, IndexWriter), Error> {
Err(anyhow!("Cannot initialize index: not in EE").into())
}
#[cfg(not(feature = "private"))]
pub async fn run_indexer(
_db: Pool<Postgres>,
mut _index_writer: IndexWriter,
@@ -1 +0,0 @@
@@ -0,0 +1,5 @@
#[cfg(feature = "private")]
#[allow(unused)]
pub use crate::indexer_ee::*;
+6
View File
@@ -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;
@@ -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<Postgres>,
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<Postgres>,
mut _index_writer: ServiceLogIndexWriter,
+1
View File
@@ -10,6 +10,7 @@ path = "src/lib.rs"
[features]
default = []
private = []
enterprise = ["windmill-common/enterprise"]
cloud = []
benchmark = ["windmill-common/benchmark"]
+2 -2
View File
@@ -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;
@@ -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,
+2
View File
@@ -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;
+1 -1
View File
@@ -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;
+1
View File
@@ -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"]
+4 -4
View File
@@ -728,7 +728,7 @@ async fn get_workspace_s3_resource_path(
storage: Option<&String>,
) -> windmill_common::error::Result<Option<ObjectStoreResource>> {
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(_)) {
+1 -1
View File
@@ -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};

Some files were not shown because too many files have changed in this diff Show More