feat: Add an authorization token to all client requests

Connects to influxdata/fusion#59. Delorean currently ignores this
header.

Also add an example of using this to connect to an InfluxDB 2 instance;
I tested this out with a locally running Influx DB 2 and I was able to
write points!
pull/24376/head
Carol (Nichols || Goulding) 2020-09-02 10:08:36 -04:00
parent 0f1cd1a77e
commit 6223cbdc99
3 changed files with 49 additions and 10 deletions

View File

@ -0,0 +1,27 @@
use futures::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let org = "0000000000000000";
let bucket = "1111111111111111";
let influx_url = "http://localhost:9999";
let token = "my-token";
let client = influxdb2_client::Client::new(influx_url, token);
let points = vec![
influxdb2_client::DataPoint::builder("cpu_load_short")
.tag("host", "server01")
.tag("region", "us-west")
.field("value", 0.64)
.build()?,
influxdb2_client::DataPoint::builder("cpu_load_short")
.tag("host", "server01")
.field("value", 27.99)
.build()?,
];
client.write(org, bucket, stream::iter(points)).await?;
Ok(())
}

View File

@ -16,7 +16,6 @@
//! ## Work Remaining
//!
//! - Query
//! - Authentication
//! - optional sync client
//! - Influx 1.x API?
//! - Other parts of the API
@ -36,7 +35,7 @@
//! let org_id = "0000111100001111";
//! let bucket_id = "1111000011110000";
//!
//! let client = Client::new("http://localhost:8888");
//! let client = Client::new("http://localhost:8888", "some-token");
//!
//! client.create_bucket(org_id, bucket_id).await?;
//!
@ -62,7 +61,10 @@ use futures::{Stream, StreamExt};
use reqwest::{Body, Method};
use serde::Serialize;
use snafu::{ResultExt, Snafu};
use std::io::{self, Write};
use std::{
fmt,
io::{self, Write},
};
pub mod data_point;
pub use data_point::{DataPoint, FieldValue, WriteDataPoint};
@ -100,27 +102,32 @@ pub enum RequestError {
#[derive(Debug, Clone)]
pub struct Client {
url: String,
auth_header: String,
reqwest: reqwest::Client,
}
impl Client {
/// Create a new client pointing to the URL specified in `protocol://server:port` format.
/// Create a new client pointing to the URL specified in `protocol://server:port` format and
/// using the specified token for authorization.
///
/// # Example
///
/// ```
/// let client = influxdb2_client::Client::new("http://localhost:8888");
/// let client = influxdb2_client::Client::new("http://localhost:8888", "my-token");
/// ```
pub fn new(url: impl Into<String>) -> Self {
pub fn new(url: impl Into<String>, auth_token: impl fmt::Display) -> Self {
Self {
url: url.into(),
auth_header: format!("Token {}", auth_token),
reqwest: reqwest::Client::new(),
}
}
/// Consolidate common request building code
fn request(&self, method: Method, url: &str) -> reqwest::RequestBuilder {
self.reqwest.request(method, url)
self.reqwest
.request(method, url)
.header("Authorization", &self.auth_header)
}
/// Write line protocol data to the specified organization and bucket.
@ -224,11 +231,13 @@ mod tests {
async fn writing_points() -> Result {
let org_id = "0000111100001111";
let bucket_id = "1111000011110000";
let token = "some-token";
let mock_server = mock(
"POST",
format!("/api/v2/write?bucket={}&org={}", bucket_id, org_id).as_str(),
)
.match_header("Authorization", format!("Token {}", token).as_str())
.match_body(
"\
cpu,host=server01 usage=0.5
@ -237,7 +246,7 @@ cpu,host=server01,region=us-west usage=0.87
)
.create();
let client = Client::new(&mockito::server_url());
let client = Client::new(&mockito::server_url(), token);
let points = vec![
DataPoint::builder("cpu")
@ -265,8 +274,10 @@ cpu,host=server01,region=us-west usage=0.87
async fn create_bucket() -> Result {
let org_id = "0000111100001111";
let bucket_id = "1111000011110000";
let token = "some-token";
let mock_server = mock("POST", "/api/v2/buckets")
.match_header("Authorization", format!("Token {}", token).as_str())
.match_body(
format!(
r#"{{"orgID":"{}","name":"{}","retentionRules":[]}}"#,
@ -276,7 +287,7 @@ cpu,host=server01,region=us-west usage=0.87
)
.create();
let client = Client::new(&mockito::server_url());
let client = Client::new(&mockito::server_url(), token);
let _result = client.create_bucket(org_id, bucket_id).await;

View File

@ -40,6 +40,7 @@ use tempfile::TempDir;
const HTTP_BASE: &str = "http://localhost:8080";
const API_BASE: &str = "http://localhost:8080/api/v2";
const GRPC_URL_BASE: &str = "http://localhost:8082/";
const TOKEN: &str = "delorean doesn't have authentication yet";
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
type Result<T, E = Error> = std::result::Result<T, E>;
@ -109,7 +110,7 @@ async fn read_and_write_data() -> Result<()> {
let bucket_id = u64::from_str_radix(bucket_id_str, 16).unwrap();
let client = reqwest::Client::new();
let client2 = influxdb2_client::Client::new(HTTP_BASE);
let client2 = influxdb2_client::Client::new(HTTP_BASE, TOKEN);
let mut grpc_client = DeloreanClient::connect(GRPC_URL_BASE).await?;
let get_buckets_request = tonic::Request::new(Organization {