[snowpatch] [PATCH] jenkins: support token authentication

Russell Currey ruscur at russell.cc
Tue Nov 22 12:42:13 AEDT 2016


On Mon, 2016-11-21 at 19:41 +1100, Andrew Donnellan wrote:
> Allow a username and token to be specified in the Jenkins configuration.
> 
> To enable this, add a few helper methods for JenkinsBackend that spit out
> Authorization headers and wrap the hyper client's get() and post() methods
> to use those headers.
> 
> Also, update the example configuration, 'openpower.toml', to include fake
> credentials.
> 
> Signed-off-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>
> ---
>  examples/openpower.toml |  3 ++-
>  src/jenkins.rs          | 36 ++++++++++++++++++++++++++++++------
>  src/main.rs             |  2 ++
>  src/settings.rs         |  2 ++
>  4 files changed, 36 insertions(+), 7 deletions(-)
> 
> diff --git a/examples/openpower.toml b/examples/openpower.toml
> index 28671a4..8446865 100644
> --- a/examples/openpower.toml
> +++ b/examples/openpower.toml
> @@ -24,7 +24,8 @@ polling_interval = 10 # polling interval in minutes
>  [jenkins]
>  url = "https://jenkins.ozlabs.ibm.com"
>  port = 443
> -# TODO: jenkins auth (our testing jenkins has no auth)
> +username = patchwork
> +token = 33333333333333333333333333333333

these should be in quotes

>  
>  [projects]
>  
> diff --git a/src/jenkins.rs b/src/jenkins.rs
> index f450243..0a0a699 100644
> --- a/src/jenkins.rs
> +++ b/src/jenkins.rs
> @@ -30,7 +30,8 @@ use std::thread::sleep;
>  use std::sync::Arc;
>  
>  use hyper::Client;
> -use hyper::header::Location;
> +use hyper::client::{IntoUrl, RequestBuilder};
> +use hyper::header::{Headers, Basic, Authorization, Location};
>  use rustc_serialize::json::Json;
>  
>  // Constants
> @@ -45,7 +46,8 @@ pub trait CIBackend { // TODO: Separate out
>  pub struct JenkinsBackend {
>      pub base_url: String,
>      pub hyper_client: Arc<Client>,
> -    // TODO: Authentication
> +    pub username: Option<String>,
> +    pub token: Option<String>,
>  }
>  
>  impl CIBackend for JenkinsBackend {
> @@ -60,9 +62,8 @@ impl CIBackend for JenkinsBackend {
>              .extend_pairs(params)
>              .finish();
>  
> -        let res = self.hyper_client
> -            .post(&format!("{}/job/{}/buildWithParameters?{}",
> -                           self.base_url, job_name, params))
> +        let res = self.post(&format!("{}/job/{}/buildWithParameters?{}",
> +                                     self.base_url, job_name, params))
>              .send().expect("HTTP request error"); // TODO don't panic here
>  
>          match res.headers.get::<Location>() {
> @@ -78,10 +79,33 @@ pub enum JenkinsBuildStatus {
>  }
>  
>  impl JenkinsBackend {
> +    fn headers(&self) -> Headers {
> +        let mut headers = Headers::new();
> +        if let Some(ref username) = self.username {
> +            headers.set(
> +                Authorization(
> +                    Basic {
> +                        username: username.clone(),
> +                        password: self.token.clone(),
> +                    }
> +                )
> +            );
> +        }
> +        headers
> +    }
> +
> +    fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
> +        self.hyper_client.get(url).headers(self.headers())
> +    }
> +
> +    fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
> +        self.hyper_client.post(url).headers(self.headers())
> +    }
> +
>      fn get_api_json_object(&self, base_url: &str) ->
> rustc_serialize::json::Object {
>          // TODO: Don't panic on failure, fail more gracefully
>          let url = format!("{}api/json", base_url);
> -        let mut resp = self.hyper_client.get(&url).send().expect("HTTP
> request error");
> +        let mut resp = self.get(&url).send().expect("HTTP request error");
>          let mut result_str = String::new();
>          resp.read_to_string(&mut result_str)
>              .unwrap_or_else(|err| panic!("Couldn't read from server: {}",
> err));
> diff --git a/src/main.rs b/src/main.rs
> index e1f1885..17437c4 100644
> --- a/src/main.rs
> +++ b/src/main.rs
> @@ -95,6 +95,8 @@ fn run_tests(settings: &Config, client: Arc<Client>,
> project: &Project, tag: &st
>      let jenkins = JenkinsBackend {
>          base_url: settings.jenkins.url.clone(),
>          hyper_client: client,
> +        username: settings.jenkins.username.clone(),
> +        token: settings.jenkins.token.clone(),
>      };
>      let project = project.clone();
>      for job_params in project.jobs.iter() {
> diff --git a/src/settings.rs b/src/settings.rs
> index 80d2759..a4a5614 100644
> --- a/src/settings.rs
> +++ b/src/settings.rs
> @@ -41,6 +41,8 @@ pub struct Patchwork {
>  pub struct Jenkins {
>      pub url: String,
>      pub port: Option<u16>,
> +    // TODO: fail if we only get one of username or token
> +    pub username: Option<String>,
>      pub token: Option<String>
>  }
>  



More information about the snowpatch mailing list