Skip to content

Commit 7d9f9ad

Browse files
committed
Inclusterconfig, Bearer token, and Basic auth
1 parent fe27390 commit 7d9f9ad

File tree

7 files changed

+123
-18
lines changed

7 files changed

+123
-18
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# kubernetes-rust
22

3-
[![Client Support Level](https://img.shields.io/badge/kubernetes%20client-alpha-green.svg?style=flat&colorA=306CE8)](http://bit.ly/kubernetes-client-support-badge)
3+
[![Client Capabilities](https://img.shields.io/badge/Kubernetes%20client-Bronze-blue.svg?style=plastic&colorB=cd7f32&colorA=306CE8)](http://bit.ly/kubernetes-client-capabilities-badge)
4+
[![Client Support Level](https://img.shields.io/badge/kubernetes%20client-beta-green.svg?style=plastic&colorA=306CE8)](http://bit.ly/kubernetes-client-support-badge)
45

56
Rust client for [Kubernetes](http://kubernetes.io) API.
67

src/client/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl APIClient {
2828
http::Method::DELETE => self.configuration.client.delete(&uri_str),
2929
http::Method::PUT => self.configuration.client.put(&uri_str),
3030
other => {
31-
return Err(Error::from(format_err!("invalid method: {}", other)));
31+
return Err(Error::from(format_err!("Invalid method: {}", other)));
3232
}
3333
}.body(body);
3434

src/config/apis.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl Config {
106106

107107
impl Cluster {
108108
pub fn load_certificate_authority(&self) -> Result<Option<Vec<u8>>, Error> {
109-
utils::data_or_file(
109+
utils::load_data_or_file(
110110
&self.certificate_authority_data,
111111
&self.certificate_authority,
112112
)
@@ -115,10 +115,10 @@ impl Cluster {
115115

116116
impl AuthInfo {
117117
pub fn load_client_certificate(&self) -> Result<Option<Vec<u8>>, Error> {
118-
utils::data_or_file(&self.client_certificate_data, &self.client_certificate)
118+
utils::load_data_or_file(&self.client_certificate_data, &self.client_certificate)
119119
}
120120

121121
pub fn load_client_key(&self) -> Result<Option<Vec<u8>>, Error> {
122-
utils::data_or_file(&self.client_key_data, &self.client_key)
122+
utils::load_data_or_file(&self.client_key_data, &self.client_key)
123123
}
124124
}

src/config/incluster_config.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use std::env;
2+
3+
use failure::Error;
4+
use openssl::x509::X509;
5+
6+
use config::utils;
7+
8+
pub const SERVICE_HOSTENV: &str = "KUBERNETES_SERVICE_HOST";
9+
pub const SERVICE_PORTENV: &str = "KUBERNETES_SERVICE_PORT";
10+
const SERVICE_TOKENFILE: &str = "/var/run/secrets/kubernetes.io/serviceaccount/token";
11+
const SERVICE_CERTFILE: &str = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt";
12+
13+
pub fn kube_server() -> Option<String> {
14+
let f = |(h, p)| format!("https://{}{}", h, p);
15+
kube_host().and_then(|h| kube_port().map(|p| f((h, p))))
16+
}
17+
18+
fn kube_host() -> Option<String> {
19+
env::var(SERVICE_HOSTENV).ok()
20+
}
21+
22+
fn kube_port() -> Option<String> {
23+
env::var(SERVICE_PORTENV).ok()
24+
}
25+
26+
pub fn load_token() -> Result<String, Error> {
27+
utils::load_token_data_or_file(&None, &Some(SERVICE_TOKENFILE.to_string()))?.ok_or(format_err!(
28+
"Unable to load token from {}",
29+
SERVICE_TOKENFILE
30+
))
31+
}
32+
33+
pub fn load_cert() -> Result<X509, Error> {
34+
let ca = utils::load_data_or_file(&None, &Some(SERVICE_CERTFILE.to_string()))?
35+
.ok_or(format_err!("Unable to load certificate"))?;
36+
X509::from_pem(&ca).map_err(Error::from)
37+
}
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,14 @@ impl KubeConfigLoader {
4343
}
4444

4545
pub fn p12(&self, password: &str) -> Result<Pkcs12, Error> {
46-
let client_cert = self.user.load_client_certificate()?.unwrap();
47-
let client_key = self.user.load_client_key()?.unwrap();
46+
let client_cert = self
47+
.user
48+
.load_client_certificate()?
49+
.ok_or(format_err!("Unable to load client certificate"))?;
50+
let client_key = self
51+
.user
52+
.load_client_key()?
53+
.ok_or(format_err!("Unable to load client key"))?;
4854

4955
let x509 = X509::from_pem(&client_cert)?;
5056
let pkey = PKey::private_key_from_pem(&client_key)?;
@@ -55,7 +61,10 @@ impl KubeConfigLoader {
5561
}
5662

5763
pub fn ca(&self) -> Result<X509, Error> {
58-
let ca = self.cluster.load_certificate_authority()?.unwrap();
64+
let ca = self
65+
.cluster
66+
.load_certificate_authority()?
67+
.ok_or(format_err!("Unable to load certificate authority"))?;
5968
X509::from_pem(&ca).map_err(Error::from)
6069
}
6170
}

src/config/mod.rs

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
mod apis;
2-
mod loader;
2+
mod incluster_config;
3+
mod kube_config;
34
mod utils;
45

6+
use base64;
57
use failure::Error;
68
use reqwest::{header, Certificate, Client, Identity};
79

8-
use self::loader::KubeConfigLoader;
10+
use self::kube_config::KubeConfigLoader;
911

1012
pub struct Configuration {
1113
pub base_path: String,
@@ -22,15 +24,14 @@ impl Configuration {
2224
}
2325

2426
pub fn load_kube_config() -> Result<Configuration, Error> {
25-
let kubeconfig = utils::kube_path()
27+
let kubeconfig = utils::kubeconfig_path()
2628
.or_else(utils::default_kube_path)
27-
.ok_or(format_err!("Unable to load config"))?;
29+
.ok_or(format_err!("Unable to load kubeconfig"))?;
2830

2931
let loader = KubeConfigLoader::load(kubeconfig)?;
3032

31-
let password = " ";
32-
let p12 = loader.p12(password)?;
33-
let req_p12 = Identity::from_pkcs12_der(&p12.to_der()?, password)?;
33+
let p12 = loader.p12(" ")?;
34+
let req_p12 = Identity::from_pkcs12_der(&p12.to_der()?, " ")?;
3435

3536
let ca = loader.ca()?;
3637
let req_ca = Certificate::from_der(&ca.to_der()?)?;
@@ -40,10 +41,51 @@ pub fn load_kube_config() -> Result<Configuration, Error> {
4041
.add_root_certificate(req_ca);
4142

4243
let mut headers = header::HeaderMap::new();
43-
headers.insert(header::AUTHORIZATION, header::HeaderValue::from_static(""));
44+
45+
match (
46+
utils::load_token_data_or_file(&loader.user.token, &loader.user.token_file)?,
47+
(loader.user.username, loader.user.password),
48+
) {
49+
(Some(token), _) => {
50+
headers.insert(
51+
header::AUTHORIZATION,
52+
header::HeaderValue::from_str(&format!("Bearer {}", token))?,
53+
);
54+
}
55+
(_, (Some(u), Some(p))) => {
56+
let encoded = base64::encode(&format!("{}:{}", u, p));
57+
headers.insert(
58+
header::AUTHORIZATION,
59+
header::HeaderValue::from_str(&format!("Basic {}", encoded))?,
60+
);
61+
}
62+
_ => {}
63+
}
4464

4565
Ok(Configuration::new(
4666
loader.cluster.server,
4767
client_builder.build()?,
4868
))
4969
}
70+
71+
pub fn incluster_config() -> Result<Configuration, Error> {
72+
let server = incluster_config::kube_server().ok_or(format_err!(
73+
"Unable to load incluster config, {} and {} must be defined",
74+
incluster_config::SERVICE_HOSTENV,
75+
incluster_config::SERVICE_PORTENV
76+
))?;
77+
78+
let ca = incluster_config::load_cert()?;
79+
let req_ca = Certificate::from_der(&ca.to_der()?)?;
80+
81+
let client_builder = Client::builder().add_root_certificate(req_ca);
82+
83+
let token = incluster_config::load_token()?;
84+
let mut headers = header::HeaderMap::new();
85+
headers.insert(
86+
header::AUTHORIZATION,
87+
header::HeaderValue::from_str(&format!("Bearer {}", token))?,
88+
);
89+
90+
Ok(Configuration::new(server, client_builder.build()?))
91+
}

src/config/utils.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ use failure::Error;
99

1010
const KUBECONFIG: &str = "KUBECONFIG";
1111

12-
pub fn kube_path() -> Option<PathBuf> {
12+
pub fn kubeconfig_path() -> Option<PathBuf> {
1313
env::var_os(KUBECONFIG).map(PathBuf::from)
1414
}
1515

1616
pub fn default_kube_path() -> Option<PathBuf> {
1717
home_dir().map(|h| h.join(".kube").join("config"))
1818
}
1919

20-
pub fn data_or_file(
20+
pub fn load_data_or_file(
2121
data: &Option<String>,
2222
file: &Option<String>,
2323
) -> Result<Option<Vec<u8>>, Error> {
@@ -32,3 +32,19 @@ pub fn data_or_file(
3232
_ => Ok(None),
3333
}
3434
}
35+
36+
pub fn load_token_data_or_file(
37+
data: &Option<String>,
38+
file: &Option<String>,
39+
) -> Result<Option<String>, Error> {
40+
match (data, file) {
41+
(Some(d), _) => Ok(Some(d.to_string())),
42+
(_, Some(f)) => {
43+
let mut s = String::new();
44+
let mut ff = File::open(f)?;
45+
ff.read_to_string(&mut s)?;
46+
Ok(Some(s))
47+
}
48+
_ => Ok(None),
49+
}
50+
}

0 commit comments

Comments
 (0)