Skip to content

Commit

Permalink
Add app config
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiimk committed Oct 29, 2023
1 parent b884acd commit 848327a
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 65 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.8.0] - 2023-10-26
## [0.10.0] - 2023-10-29
### Added
- Introduced a config file allowing to configure the list of supported auth providers

## [0.9.0] - 2023-10-26
### Added
- FlightSQL endpoint

Expand Down
94 changes: 91 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ kamu-adapter-flight-sql = { git = "https://github.com/kamu-data/kamu-cli", tag =


[workspace.package]
version = "0.9.0"
version = "0.10.0"
edition = "2021"
homepage = "https://github.com/kamu-data/kamu-platform"
repository = "https://github.com/kamu-data/kamu-platform"
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Additional Use Grant: You may use the Licensed Work for any purpose,
Licensed Work where data or transformations are
controlled by such third parties.

Change Date: 2027-10-26
Change Date: 2027-10-29

Change License: Apache License, Version 2.0

Expand Down
3 changes: 2 additions & 1 deletion src/app/api-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ async-trait = { version = "0.1", default-features = false }
chrono = "0.4"
clap = "4"
datafusion = "31"
figment = { version = "0.10", features = ["env", "yaml", "json"] }
futures = "0.3"
indoc = "2"
serde = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tempfile = "3"
tokio = { version = "1", default-features = false, features = ["macros"] }
Expand Down
57 changes: 51 additions & 6 deletions src/app/api-server/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ use kamu::utils::smart_transfer_protocol::SmartTransferProtocolClient;
use tracing::info;
use url::Url;

use crate::config::{ApiServerConfig, AuthProviderConfig};
use crate::dummy_auth_provider::DummyAuthProvider;

/////////////////////////////////////////////////////////////////////////////////////////

pub const BINARY_NAME: &str = env!("CARGO_PKG_NAME");
Expand All @@ -27,6 +30,8 @@ const DEFAULT_LOGGING_CONFIG: &str = "info,tower_http=trace";
pub async fn run(matches: clap::ArgMatches) -> Result<(), InternalError> {
init_logging();

let config = load_config(matches.get_one("config"))?;

let repo_url = if let Some(repo_url) = matches.get_one::<Url>("repo-url").cloned() {
repo_url
} else {
Expand All @@ -51,7 +56,9 @@ pub async fn run(matches: clap::ArgMatches) -> Result<(), InternalError> {
BINARY_NAME
);

let catalog = init_dependencies(&repo_url, local_dir.path()).await.build();
let catalog = init_dependencies(config, &repo_url, local_dir.path())
.await
.build();

match matches.subcommand() {
Some(("gql", sub)) => match sub.subcommand() {
Expand Down Expand Up @@ -145,7 +152,29 @@ fn init_logging() {

/////////////////////////////////////////////////////////////////////////////////////////

pub async fn init_dependencies(repo_url: &Url, local_dir: &Path) -> CatalogBuilder {
pub fn load_config(path: Option<&PathBuf>) -> Result<ApiServerConfig, InternalError> {
use figment::providers::Format;

let Some(path) = path else {
return Ok(ApiServerConfig::default());
};

figment::Figment::from(figment::providers::Serialized::defaults(
ApiServerConfig::default(),
))
.merge(figment::providers::Yaml::file(path))
.merge(figment::providers::Env::prefixed("KAMU_API_SERVER_").lowercase(false))
.extract()
.int_err()
}

/////////////////////////////////////////////////////////////////////////////////////////

pub async fn init_dependencies(
config: ApiServerConfig,
repo_url: &Url,
local_dir: &Path,
) -> CatalogBuilder {
let mut b = dill::CatalogBuilder::new();

// TODO: Improve output multiplexing and cache interface
Expand Down Expand Up @@ -256,8 +285,8 @@ pub async fn init_dependencies(repo_url: &Url, local_dir: &Path) -> CatalogBuild
b.add::<kamu::ObjectStoreBuilderLocalFs>();
b.bind::<dyn kamu::domain::ObjectStoreBuilder, kamu::ObjectStoreBuilderLocalFs>();

b.add::<crate::builtin_authentication_provider::BuiltinAuthenticationProvider>();
b.bind::<dyn kamu::domain::auth::AuthenticationProvider, crate::builtin_authentication_provider::BuiltinAuthenticationProvider>();
b.add_value(DummyAuthProvider::new_with_default_account());
b.bind::<dyn kamu::domain::auth::AuthenticationProvider, DummyAuthProvider>();
}
"s3" | "s3+http" | "s3+https" => {
let s3_context = kamu::utils::s3_context::S3Context::from_url(&repo_url).await;
Expand All @@ -272,8 +301,24 @@ pub async fn init_dependencies(repo_url: &Url, local_dir: &Path) -> CatalogBuild
b.add_value(kamu::ObjectStoreBuilderS3::new(s3_context, false))
.bind::<dyn kamu::domain::ObjectStoreBuilder, kamu::ObjectStoreBuilderS3>();

b.add::<kamu_adapter_oauth::OAuthGithub>();
b.bind::<dyn kamu::domain::auth::AuthenticationProvider, kamu_adapter_oauth::OAuthGithub>();
// Default to GitHub auth
if config.auth.providers.is_empty() {
b.add::<kamu_adapter_oauth::OAuthGithub>();
b.bind::<dyn kamu::domain::auth::AuthenticationProvider, kamu_adapter_oauth::OAuthGithub>();
}

for provider in config.auth.providers {
match provider {
AuthProviderConfig::Github(_) => {
b.add::<kamu_adapter_oauth::OAuthGithub>();
b.bind::<dyn kamu::domain::auth::AuthenticationProvider, kamu_adapter_oauth::OAuthGithub>();
}
AuthProviderConfig::Dummy(prov) => {
b.add_value(DummyAuthProvider::new(prov.accounts));
b.bind::<dyn kamu::domain::auth::AuthenticationProvider, DummyAuthProvider>();
}
}
}
}
_ => panic!("Unsupported repository scheme: {}", repo_url.scheme()),
}
Expand Down
14 changes: 10 additions & 4 deletions src/app/api-server/src/cli_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ pub fn cli() -> Command {
kamu-api-server <command> <sub-command> -h
"
))
.args([Arg::new("repo-url")
.long("repo-url")
.value_parser(value_parse_repo_url)
.help("URL of the remote dataset repository")])
.args([
Arg::new("config")
.long("config")
.value_parser(value_parser!(std::path::PathBuf))
.help("Path to the config file"),
Arg::new("repo-url")
.long("repo-url")
.value_parser(value_parse_repo_url)
.help("URL of the remote dataset repository"),
])
.subcommands([
Command::new("run").about("Run the server").args([
Arg::new("address")
Expand Down
50 changes: 50 additions & 0 deletions src/app/api-server/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright Kamu Data, Inc. and contributors. All rights reserved.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0.

use serde::{Deserialize, Serialize};

/////////////////////////////////////////////////////////////////////////////////////////

#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ApiServerConfig {
pub auth: AuthConfig,
}

/////////////////////////////////////////////////////////////////////////////////////////

#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthConfig {
pub providers: Vec<AuthProviderConfig>,
}

/////////////////////////////////////////////////////////////////////////////////////////

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "kind")]
pub enum AuthProviderConfig {
Github(AuthProviderConfigGitHub),
Dummy(AuthProviderConfigDummy),
}

/////////////////////////////////////////////////////////////////////////////////////////

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthProviderConfigGitHub {}

/////////////////////////////////////////////////////////////////////////////////////////

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthProviderConfigDummy {
pub accounts: Vec<kamu::domain::auth::AccountInfo>,
}
Loading

0 comments on commit 848327a

Please sign in to comment.