Fetch the in-repo config file from the remote repo.
This commit is contained in:
parent
c32a8650f5
commit
66228f83f2
7
list_files_curl.bash
Executable file
7
list_files_curl.bash
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
curl -vv -H "Authorization: token $(cat /bridge/git/mrmanager/k8s/lighthouse/secrets/lighthouse/lighthouse/OAUTH_TOKEN)" 'https://code.fizz.buzz/api/v1/repos/talexander/organic/git/trees/841a348dd02f31ee8828f069b2a948712369069d?recursive=true&per_page=10&page=60'
|
7
run.bash
Executable file
7
run.bash
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
RUST_LOG=webhook_bridge=DEBUG WEBHOOK_BRIDGE_API_ROOT="https://code.fizz.buzz/api" WEBHOOK_BRIDGE_HMAC_SECRET=$(cat /bridge/git/mrmanager/k8s/lighthouse/secrets/lighthouse/lighthouse/HMAC_TOKEN) WEBHOOK_BRIDGE_OAUTH_TOKEN=$(cat /bridge/git/mrmanager/k8s/lighthouse/secrets/lighthouse/lighthouse/OAUTH_TOKEN) cargo run
|
24
src/discovery.rs
Normal file
24
src/discovery.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use crate::gitea_client::GiteaClient;
|
||||||
|
use crate::gitea_client::TreeFileReference;
|
||||||
|
use crate::in_repo_config::InRepoConfig;
|
||||||
|
|
||||||
|
pub(crate) async fn discover_webhook_bridge_config<O: AsRef<str>, R: AsRef<str>, C: AsRef<str>>(
|
||||||
|
gitea: &GiteaClient,
|
||||||
|
owner: O,
|
||||||
|
repo: R,
|
||||||
|
commit: C,
|
||||||
|
) -> Result<InRepoConfig, Box<dyn std::error::Error>> {
|
||||||
|
let repo_tree = gitea.get_tree(owner, repo, commit).await?;
|
||||||
|
let in_repo_config_reference = repo_tree
|
||||||
|
.files
|
||||||
|
.iter()
|
||||||
|
.filter(|file_reference| file_reference.path == ".webhook_bridge/webhook_bridge.toml")
|
||||||
|
.next()
|
||||||
|
.ok_or("File not found in remote repo: .webhook_bridge/webhook_bridge.toml.")?;
|
||||||
|
|
||||||
|
let in_repo_config_contents =
|
||||||
|
String::from_utf8(gitea.read_file(in_repo_config_reference).await?)?;
|
||||||
|
let parsed_in_repo_config = InRepoConfig::from_str(in_repo_config_contents)?;
|
||||||
|
|
||||||
|
Ok(parsed_in_repo_config)
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use self::error::GiteaClientError;
|
use self::error::GiteaClientError;
|
||||||
pub(crate) mod error;
|
pub(crate) mod error;
|
||||||
@ -30,7 +32,7 @@ impl GiteaClient {
|
|||||||
let mut num_responses: u64 = 0;
|
let mut num_responses: u64 = 0;
|
||||||
loop {
|
loop {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{api_root}/v1/repos/{owner}/{repo}/git/trees/{commit}?recursive=true&per_page=10{page}",
|
"{api_root}/v1/repos/{owner}/{repo}/git/trees/{commit}?recursive=true&per_page=100{page}",
|
||||||
api_root = self.api_root,
|
api_root = self.api_root,
|
||||||
owner = owner.as_ref(),
|
owner = owner.as_ref(),
|
||||||
repo = repo.as_ref(),
|
repo = repo.as_ref(),
|
||||||
@ -70,6 +72,27 @@ impl GiteaClient {
|
|||||||
}
|
}
|
||||||
Ok(Tree::new(files))
|
Ok(Tree::new(files))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn read_file(
|
||||||
|
&self,
|
||||||
|
file_reference: &TreeFileReference,
|
||||||
|
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
|
||||||
|
let response = self
|
||||||
|
.http_client
|
||||||
|
.get(&file_reference.url)
|
||||||
|
.header("Authorization", format!("token {}", self.token))
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
let response = response.error_for_status()?;
|
||||||
|
let body = response.text().await?;
|
||||||
|
debug!("read_file response: {}", body);
|
||||||
|
let parsed_body: ResponseReadFile = serde_json::from_str(body.as_str())?;
|
||||||
|
assert!(
|
||||||
|
parsed_body.encoding == "base64",
|
||||||
|
"We currently only support base64 file encoding from gitea."
|
||||||
|
);
|
||||||
|
Ok(general_purpose::STANDARD.decode(parsed_body.content)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single API response for GetTree containing only one page.
|
/// A single API response for GetTree containing only one page.
|
||||||
@ -101,13 +124,13 @@ pub(crate) struct Tree {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct TreeFileReference {
|
pub(crate) struct TreeFileReference {
|
||||||
path: String,
|
pub(crate) path: String,
|
||||||
url: String,
|
pub(crate) url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tree {
|
impl Tree {
|
||||||
pub(crate) fn new(files: Vec<TreeFileReference>) -> Tree {
|
pub(crate) fn new(files: Vec<TreeFileReference>) -> Tree {
|
||||||
Tree { files: Vec::new() }
|
Tree { files }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,3 +142,12 @@ impl TreeFileReference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct ResponseReadFile {
|
||||||
|
content: String,
|
||||||
|
encoding: String,
|
||||||
|
url: String,
|
||||||
|
sha: String,
|
||||||
|
size: u64,
|
||||||
|
}
|
||||||
|
@ -4,8 +4,7 @@ use serde::Serialize;
|
|||||||
/// The webhook_bridge.toml file that lives inside repos that have their CI triggered by webhook_bridge.
|
/// The webhook_bridge.toml file that lives inside repos that have their CI triggered by webhook_bridge.
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub(crate) struct InRepoConfig {
|
pub(crate) struct InRepoConfig {
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
pub(crate) version: String,
|
||||||
pub(crate) version: Option<String>,
|
|
||||||
|
|
||||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
pub(crate) push: Vec<TriggerPush>,
|
pub(crate) push: Vec<TriggerPush>,
|
||||||
@ -29,3 +28,16 @@ pub(crate) struct TriggerPush {
|
|||||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
pub(crate) skip_branches: Vec<String>,
|
pub(crate) skip_branches: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InRepoConfig {
|
||||||
|
pub(crate) fn from_str<S: AsRef<str>>(
|
||||||
|
contents: S,
|
||||||
|
) -> Result<InRepoConfig, Box<dyn std::error::Error>> {
|
||||||
|
let parsed_in_repo_config: InRepoConfig = toml::from_str(contents.as_ref())?;
|
||||||
|
assert!(
|
||||||
|
parsed_in_repo_config.version == "0.0.1",
|
||||||
|
"We only support version 0.0.1 currently."
|
||||||
|
);
|
||||||
|
Ok(parsed_in_repo_config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
19
src/main.rs
19
src/main.rs
@ -19,6 +19,7 @@ use tracing_subscriber::layer::SubscriberExt;
|
|||||||
use tracing_subscriber::util::SubscriberInitExt;
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
|
|
||||||
use self::crd_pipeline_run::PipelineRun;
|
use self::crd_pipeline_run::PipelineRun;
|
||||||
|
use self::discovery::discover_webhook_bridge_config;
|
||||||
use self::gitea_client::GiteaClient;
|
use self::gitea_client::GiteaClient;
|
||||||
use self::in_repo_config::InRepoConfig;
|
use self::in_repo_config::InRepoConfig;
|
||||||
use self::webhook::hook;
|
use self::webhook::hook;
|
||||||
@ -26,13 +27,13 @@ use self::webhook::verify_signature;
|
|||||||
use kube::CustomResourceExt;
|
use kube::CustomResourceExt;
|
||||||
|
|
||||||
mod crd_pipeline_run;
|
mod crd_pipeline_run;
|
||||||
|
mod discovery;
|
||||||
mod gitea_client;
|
mod gitea_client;
|
||||||
mod hook_push;
|
mod hook_push;
|
||||||
mod in_repo_config;
|
mod in_repo_config;
|
||||||
mod webhook;
|
mod webhook;
|
||||||
|
|
||||||
const EXAMPLE_PIPELINE_RUN: &'static str = include_str!("../example_pipeline_run.json");
|
const EXAMPLE_PIPELINE_RUN: &'static str = include_str!("../example_pipeline_run.json");
|
||||||
const TEST_IN_REPO_CONFIG: &'static str = include_str!("../.webhook_bridge/webhook_bridge.toml");
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
@ -53,15 +54,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let gitea_api_token = std::env::var("WEBHOOK_BRIDGE_OAUTH_TOKEN")?;
|
let gitea_api_token = std::env::var("WEBHOOK_BRIDGE_OAUTH_TOKEN")?;
|
||||||
let gitea = GiteaClient::new(gitea_api_root, gitea_api_token);
|
let gitea = GiteaClient::new(gitea_api_root, gitea_api_token);
|
||||||
|
|
||||||
// gitea
|
discover_webhook_bridge_config(
|
||||||
// .get_tree(
|
&gitea,
|
||||||
// "talexander",
|
"talexander",
|
||||||
// "organic",
|
"webhook_bridge",
|
||||||
// "841a348dd02f31ee8828f069b2a948712369069d",
|
"c32a8650f509b5e4bbf6df0c210a3a01ad405eb5",
|
||||||
// )
|
)
|
||||||
// .await?;
|
.await?;
|
||||||
|
|
||||||
let parsed_in_repo_config: InRepoConfig = toml::from_str(TEST_IN_REPO_CONFIG)?;
|
|
||||||
|
|
||||||
// let jobs: Api<PipelineRun> = Api::namespaced(kubernetes_client, "lighthouse");
|
// let jobs: Api<PipelineRun> = Api::namespaced(kubernetes_client, "lighthouse");
|
||||||
// let jobs: Api<PipelineRun> = Api::default_namespaced(kubernetes_client);
|
// let jobs: Api<PipelineRun> = Api::default_namespaced(kubernetes_client);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user