Skip to content

Commit

Permalink
Add support for multiple organizations
Browse files Browse the repository at this point in the history
Closes #43

Signed-off-by: Sergio Castaño Arteaga <[email protected]>
Signed-off-by: Cintia Sanchez Garcia <[email protected]>
Co-authored-by: Sergio Castaño Arteaga <[email protected]>
Co-authored-by: Cintia Sanchez Garcia <[email protected]>
  • Loading branch information
tegioz and cynthia-sg committed Jul 12, 2023
1 parent f7c2a76 commit d4bf6ce
Show file tree
Hide file tree
Showing 22 changed files with 943 additions and 777 deletions.
21 changes: 5 additions & 16 deletions charts/clowarden/templates/server_secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,10 @@ stringData:
password: {{ .Values.server.basicAuth.password }}
githubApp:
appId: {{ .Values.server.githubApp.appId }}
installationId: {{ .Values.server.githubApp.installationId }}
privateKey: {{ .Values.server.githubApp.privateKey | quote }}
webhookSecret: {{ .Values.server.githubApp.webhookSecret | quote }}
config:
organization: {{ .Values.server.config.organization }}
repository: {{ .Values.server.config.repository }}
branch: {{ .Values.server.config.branch }}
legacy:
enabled: {{ .Values.server.config.legacy.enabled }}
sheriff:
permissionsPath: {{ .Values.server.config.legacy.sheriff.permissionsPath }}
{{- with .Values.server.config.legacy.cncf.peoplePath }}
cncf:
peoplePath: {{ . }}
{{- end }}
services:
github:
enabled: {{ .Values.server.config.services.github.enabled }}
services:
github:
enabled: {{ .Values.services.github.enabled }}
organizations: {{ toYaml .Values.organizations | nindent 6 }}
40 changes: 23 additions & 17 deletions charts/clowarden/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,11 @@ server:
githubApp:
# GitHub application ID
appId: null
# GitHub application installation ID
installationId: null
# GitHub application private key path
privateKey: null
# GitHub application webhook secret
webhookSecret: null

# CLOWarden service configuration
config:
organization: null
repository: null
branch: main
legacy:
enabled: true
sheriff:
permissionsPath: config.yaml
cncf:
peoplePath: null
services:
github:
enabled: true

# Ingress configuration
ingress:
enabled: true
Expand All @@ -101,6 +84,29 @@ server:
repository: clowarden-server
resources: {}

# Services CLOWarden will manage
services:
github:
enabled: true

# Organizations managed by this CLOWarden instance
organizations:
[]
# - # Name of the GitHub organization
# name: org-name
# # CLOWarden's GitHub application installation id
# installationId: 12345678
# # Repository where the configuration files are located
# repository: .clowarden
# # Branch to use in the configuration repository
# branch: main
# # Legacy mode configuration
# legacy:
# # Whether legacy mode is enabled or not
# enabled: true
# # Path of the Sheriff's permissions file
# sheriffPermissionsPath: config.yaml

# PostgreSQL configuration
postgresql:
enabled: true
Expand Down
89 changes: 60 additions & 29 deletions clowarden-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
#![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::doc_markdown, clippy::similar_names)]

use anyhow::{format_err, Result};
use clap::{Args, Parser, Subcommand};
use clowarden_core::{
github::GHApi,
cfg::Legacy,
github::{GHApi, Source},
multierror,
services::{
self,
github::{self, service::SvcApi, State},
github::{
self,
service::{Ctx, SvcApi},
State,
},
Change,
},
};
use config::Config;
use std::{env, sync::Arc};

#[derive(Parser)]
Expand Down Expand Up @@ -68,7 +75,7 @@ async fn main() -> Result<()> {

// Setup logging
if std::env::var_os("RUST_LOG").is_none() {
std::env::set_var("RUST_LOG", "clowarden_cli=debug")
std::env::set_var("RUST_LOG", "clowarden_cli=debug");
}
tracing_subscriber::fmt::init();

Expand All @@ -91,10 +98,15 @@ async fn main() -> Result<()> {
async fn validate(args: BaseArgs, github_token: String) -> Result<()> {
// GitHub

// Setup services
let (gh, svc) = setup_services(github_token);
let legacy = setup_legacy(&args);
let ctx = setup_context(&args);
let src = setup_source(&args);

// Validate configuration and display results
println!("Validating configuration...");
let (cfg, gh, svc) = setup_services(&args, github_token)?;
match github::State::new_from_config(cfg, gh, svc, None, None, None).await {
match github::State::new_from_config(gh, svc, &legacy, &ctx, &src).await {
Ok(_) => println!("Configuration is valid!"),
Err(err) => {
println!("{}\n", multierror::format_error(&err)?);
Expand All @@ -109,21 +121,26 @@ async fn validate(args: BaseArgs, github_token: String) -> Result<()> {
async fn diff(args: BaseArgs, github_token: String) -> Result<()> {
// GitHub

// Setup services
let (gh, svc) = setup_services(github_token);
let legacy = setup_legacy(&args);
let ctx = setup_context(&args);
let src = setup_source(&args);

// Get changes from the actual state to the desired state
println!("Calculating diff between the actual state and the desired state...");
let (cfg, gh, svc) = setup_services(&args, github_token)?;
let actual_state = State::new_from_service(svc.clone()).await?;
let desired_state = State::new_from_config(cfg, gh, svc, None, None, None).await?;
let actual_state = State::new_from_service(svc.clone(), &ctx).await?;
let desired_state = State::new_from_config(gh, svc, &legacy, &ctx, &src).await?;
let changes = actual_state.diff(&desired_state);

// Display changes
println!("\n# GitHub");
println!("\n## Directory changes\n");
for change in changes.directory.into_iter() {
for change in changes.directory {
println!("{}", change.template_format()?);
}
println!("\n## Repositories changes\n");
for change in changes.repositories.into_iter() {
for change in changes.repositories {
println!("{}", change.template_format()?);
}
println!();
Expand All @@ -132,22 +149,36 @@ async fn diff(args: BaseArgs, github_token: String) -> Result<()> {
}

/// Helper function to setup some services from the arguments provided.
fn setup_services(args: &BaseArgs, github_token: String) -> Result<(Arc<Config>, Arc<GHApi>, Arc<SvcApi>)> {
let cfg = Config::builder()
.set_override("server.config.legacy.enabled", true)?
.set_override(
"server.config.legacy.sheriff.permissionsPath",
args.permissions_file.clone(),
)?
.set_override_option("server.config.legacy.cncf.peoplePath", args.people_file.clone())?
.build()?;
let gh = GHApi::new(
args.org.clone(),
args.repo.clone(),
args.branch.clone(),
github_token.clone(),
)?;
let svc = services::github::service::SvcApi::new(args.org.clone(), github_token)?;

Ok((Arc::new(cfg), Arc::new(gh), Arc::new(svc)))
fn setup_services(github_token: String) -> (Arc<GHApi>, Arc<SvcApi>) {
let gh = GHApi::new_with_token(github_token.clone());
let svc = services::github::service::SvcApi::new_with_token(github_token);

(Arc::new(gh), Arc::new(svc))
}

/// Helper function to create a legacy config instance from the arguments.
fn setup_legacy(args: &BaseArgs) -> Legacy {
Legacy {
enabled: true,
sheriff_permissions_path: args.permissions_file.clone(),
cncf_people_path: args.people_file.clone(),
}
}

/// Helper function to create a context instance from the arguments.
fn setup_context(args: &BaseArgs) -> Ctx {
Ctx {
inst_id: None,
org: args.org.clone(),
}
}

/// Helper function to create a source instance from the arguments.
fn setup_source(args: &BaseArgs) -> Source {
Source {
inst_id: None,
owner: args.org.clone(),
repo: args.repo.clone(),
ref_: args.branch.clone(),
}
}
32 changes: 32 additions & 0 deletions clowarden-core/src/cfg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//! This module defines some types that represent parts of the configuration.

use serde::{Deserialize, Serialize};

/// Organization configuration.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct Organization {
pub name: String,
pub installation_id: i64,
pub repository: String,
pub branch: String,
pub legacy: Legacy,
}

/// Organization legacy configuration.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct Legacy {
pub enabled: bool,
pub sheriff_permissions_path: String,
pub cncf_people_path: Option<String>,
}

/// GitHub application configuration.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct GitHubApp {
pub app_id: i64,
pub private_key: String,
pub webhook_secret: String,
}
Loading

0 comments on commit d4bf6ce

Please sign in to comment.