Skip to content

Commit 9b91b8a

Browse files
YOU54FGuillaume CAMUS
authored andcommitted
feat: Support Broker Authentication Mechanisms [BC]
∙ ∙ pact-graph-network now supports Pact Broker Auth For Basic Auth users, set ∙ - PACT_BROKER_USERNAME ∙ - PACT_BROKER_PASSWORD For Bearer Token users, set - PACT_BROKER_TOKEN For options, see `--help` Notes:- description/metadata fields set to optional. This was due to errors seen using the https://testdemo.pactflow.io hosted broker, it may be due to invalid contracts.
1 parent 1dc7759 commit 9b91b8a

File tree

5 files changed

+116
-52
lines changed

5 files changed

+116
-52
lines changed

README.md

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@ Available for linux, alpine and OSX.
2121

2222
# Table of contents
2323

24-
* [Pact graph network](#pact-graph-network)
25-
* [Broker APIs](#broker-apis)
26-
* [Table of contents](#table-of-contents)
27-
* [Screenshots](#screenshots)
28-
* [Tech Stack](#tech-stack)
29-
* [Features](#features)
30-
* [How to install](#how-to-install)
31-
* [Usage](#usage)
32-
* [Options](#options)
33-
* [Environment Variables](#environment-variables)
34-
* [Feedback](#feedback)
35-
* [License](#license)
24+
- [Pact graph network](#pact-graph-network)
25+
- [Broker APIs](#broker-apis)
26+
- [Table of contents](#table-of-contents)
27+
- [Screenshots](#screenshots)
28+
- [Tech Stack](#tech-stack)
29+
- [Features](#features)
30+
- [How to install](#how-to-install)
31+
- [Usage](#usage)
32+
- [Basic Auth](#basic-auth)
33+
- [Bearer Auth](#bearer-auth)
34+
- [Environment Variables](#environment-variables)
35+
- [Options](#options)
36+
- [Environment Variables](#environment-variables-1)
37+
- [Feedback](#feedback)
38+
- [License](#license)
3639

3740
## Screenshots
3841

@@ -55,7 +58,7 @@ This project is created with:
5558
- [x] generate a force directed layout chart
5659
- [x] exclude sevices with pattern
5760
- [ ] filter only services
58-
- [ ] add support fort Pact Broker authentification
61+
- [X] add support fort Pact Broker authentification (Basic Auth + Bearer Based)
5962

6063
## How to install
6164

@@ -71,22 +74,46 @@ chmod u+x $HOME/.local/bin/pact-graph-network
7174

7275
## Usage
7376

77+
Generate the graph
78+
7479
~~~bash
7580
pact-graph-network \
7681
--url https://pact-brocker.your.com/ \
7782
--output report
7883
~~~
7984

85+
View the output in your browser
86+
87+
~~~bash
88+
open report/edge-bundling.html
89+
~~~
90+
91+
### Basic Auth
92+
93+
~~~bash
94+
pact-graph-network --url https://pact-brocker.your.com/ --output report --username $PACT_BROKER_USERNAME --password $PACT_BROKER_PASSWORD
95+
~~~
96+
97+
### Bearer Auth
98+
99+
~~~bash
100+
pact-graph-network --url https://pact-brocker.your.com/ --output report --token $PACT_BROKER_TOKEN
101+
~~~
102+
103+
## Environment Variables
80104
### Options
81105

82106
```
83-
-u, --url <URL> Pact broker URL
84-
-o, --output <OUTPUT> Path of the output dir [default: report]
85-
-g, --graph <GRAPH> [default: edge] [possible values: edge, directed]
86-
--timeout <TIMEOUT> timeout of http request in milliseconds [default: 2000]
87-
--exclude <EXCLUDE> list of service to exclude
88-
-h, --help Print help information
89-
-V, --version Print version information
107+
-b, --url <URL> Pact broker URL
108+
-u, --username <USERNAME> Pact broker username
109+
-p, --password <PASSWORD> Pact broker password
110+
-t, --token <TOKEN> Pact broker token
111+
-o, --output <OUTPUT> Path of the output dir [default: report]
112+
-g, --graph <GRAPH> [default: edge] [possible values: edge, directed]
113+
--timeout <TIMEOUT> timeout of http request in milliseconds [default: 2000]
114+
--exclude <EXCLUDE> list of service to exclude
115+
-h, --help Print help information
116+
-V, --version Print version information
90117
```
91118

92119
### Environment Variables
Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use snafu::{Backtrace, Snafu};
1+
use snafu::{Backtrace, ErrorCompat, Snafu};
22

33
#[derive(Snafu, Debug)]
44
#[snafu(visibility(pub))]
@@ -7,19 +7,32 @@ pub enum Error {
77
source: url::ParseError,
88
backtrace: Backtrace,
99
},
10-
#[snafu(display("HTTP Error: {}\n\nFound at {}", source, backtrace))]
10+
#[snafu(display("HTTP Error: {}", source))]
1111
Http {
1212
source: reqwest::Error,
13-
backtrace: Backtrace,
13+
#[snafu(backtrace)]
14+
backtrace: Option<Backtrace>,
1415
},
15-
#[snafu(display("Serde Error: {}\nFound at {}", source, backtrace))]
16+
#[snafu(display("Serde Error: {}", source))]
1617
Serde {
1718
source: serde_json::Error,
18-
backtrace: Backtrace,
19+
#[snafu(backtrace)]
20+
backtrace: Option<Backtrace>,
1921
},
20-
#[snafu(display("JSON Error in {}: {}\nFound at {}", source.path(), source.inner(), backtrace))]
22+
#[snafu(display("JSON Error in {}: {}", source.path(), source.inner()))]
2123
Json {
2224
source: serde_path_to_error::Error<serde_json::Error>,
23-
backtrace: Backtrace,
25+
#[snafu(backtrace)]
26+
backtrace: Option<Backtrace>,
2427
},
2528
}
29+
30+
impl Error {
31+
pub fn display_backtrace(&self, verbose: bool) {
32+
if verbose {
33+
if let Some(backtrace) = self.backtrace() {
34+
eprintln!("{}", backtrace);
35+
}
36+
}
37+
}
38+
}

pact-broker-models/src/contract.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
44
pub struct Contract {
55
pub consumer: Pacticant,
66
pub interactions: Option<Vec<Interaction>>,
7-
pub metadata: Metadata,
7+
pub metadata: Option<Metadata>,
88
pub provider: Pacticant,
99
#[serde(rename = "createdAt")]
1010
pub created_at: String,
@@ -21,7 +21,7 @@ pub struct Pacticant {
2121
pub struct Interaction {
2222
#[serde(rename = "_id")]
2323
pub id: String,
24-
pub description: String,
24+
pub description: Option<String>,
2525
#[serde(rename = "providerStates")]
2626
pub provider_states: Option<Vec<State>>,
2727
pub request: Request,

src/cli.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,17 @@ pub enum GraphChoice {
3636
)]
3737
pub struct Cli {
3838
/// Pact broker URL
39-
#[arg(short, long)]
39+
#[arg(short = 'b', long)]
4040
pub url: String,
41+
/// Pact broker username
42+
#[arg(short, long)]
43+
pub username: Option<String>,
44+
/// Pact broker password
45+
#[arg(short, long)]
46+
pub password: Option<String>,
47+
/// Pact broker token
48+
#[arg(short, long)]
49+
pub token: Option<String>,
4150
/// Path of the output dir
4251
#[arg(short, long, default_value = "report")]
4352
pub output: String,

src/lib.rs

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,45 @@ pub async fn run(args: Cli) -> Result<()> {
2121

2222
let timeout = Duration::from_millis(args.timeout as u64);
2323

24-
let api = Builder::new()
24+
let mut api_builder = Builder::new()
2525
.base_url(args.url)
2626
.unwrap()
27-
.with_timeout(timeout)
28-
.build()
29-
.unwrap();
30-
31-
let urls: Vec<Url> = api
32-
.pacts()
33-
.latest()
34-
.await
35-
.unwrap()
36-
.pacts
37-
.iter()
38-
.filter_map(|pact| match pact.links.links_self.first() {
39-
Some(link) => match Url::parse(link.href.as_str()) {
40-
Ok(link) => Some(link),
41-
Err(_) => None,
42-
},
43-
None => None,
44-
})
45-
.collect();
46-
47-
let data = api.batch_get::<Contract>(urls, None).await.unwrap();
27+
.with_timeout(timeout);
28+
29+
if let (Some(username), Some(password)) = (args.username, args.password) {
30+
api_builder = api_builder.basic_auth(&username, &password);
31+
}
32+
33+
if let Some(token) = args.token {
34+
api_builder = api_builder.token(&token);
35+
}
36+
37+
let api = api_builder.build().unwrap();
38+
let urls: Vec<Url> = match api.pacts().latest().await {
39+
Ok(pacts) => pacts
40+
.pacts
41+
.iter()
42+
.filter_map(|pact| match pact.links.links_self.first() {
43+
Some(link) => match Url::parse(link.href.as_str()) {
44+
Ok(link) => Some(link),
45+
Err(_) => None,
46+
},
47+
None => None,
48+
})
49+
.collect(),
50+
Err(e) => {
51+
eprintln!("Failed to fetch latests pacts:");
52+
return Err(e.into());
53+
}
54+
};
55+
56+
let data = match api.batch_get::<Contract>(urls, None).await {
57+
Ok(data) => data,
58+
Err(e) => {
59+
eprintln!("Failed to fetch iterate over contracts:");
60+
return Err(e.into());
61+
}
62+
};
4863

4964
let graph = dataset::Graph::from(&data);
5065
let json_data = serde_json::to_string(&graph)?;

0 commit comments

Comments
 (0)