Python is a great language, but sometimes I miss type safety. While I was always comfortable with C++, I know that the lanugague has it’s warts. Lately, I’ve been taking an interest in Rust, which seems to be set to address many of the shortcomiings of C++. What better way to learn it than to try and use on problems I already know well; OpenStack and Keystone? So, I wrote my first non-trivial program, which gets a Keystone token.
Here is my src/main.rs
/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See http://www.gnu.org/licenses/ */ extern crate curl; extern crate rustc_serialize; use curl::http; use rustc_serialize::json; #[derive(RustcDecodable, RustcEncodable)] struct Domain { name: String } #[derive(RustcDecodable, RustcEncodable)] struct User { name: String, password: String, domain: Domain } #[derive(RustcDecodable, RustcEncodable)] struct PasswordAuth { user: User } #[derive(RustcDecodable, RustcEncodable)] struct Project{ domain: Domain, name: String } #[derive(RustcDecodable, RustcEncodable)] struct Scope{ project : Project } #[derive(RustcDecodable, RustcEncodable)] struct Identity{ methods: Vec<String>, password: PasswordAuth } #[derive(RustcDecodable, RustcEncodable)] struct Auth{ identity: Identity, scope: Scope } #[derive(RustcDecodable, RustcEncodable)] struct TokenRequest{ auth: Auth, } fn main() { let os_auth_url = env!("OS_AUTH_URL").to_string(); let os_username = env!("OS_USERNAME").to_string(); let os_password = env!("OS_PASSWORD").to_string(); let os_project_name = env!("OS_PROJECT_NAME").to_string(); let os_project_domain_name = env!("OS_PROJECT_DOMAIN_NAME").to_string(); let os_user_domain_name = env!("OS_USER_DOMAIN_NAME").to_string(); let request = TokenRequest { auth: Auth{ identity: Identity { methods: vec!["password".to_string()], password: PasswordAuth{ user: User{ name: os_username, password: os_password, domain: Domain { name: os_user_domain_name} } } }, scope: Scope { project: Project{ name: os_project_name, domain: Domain{ name: os_project_domain_name } } } } }; let s = json::encode(&request).unwrap(); let data: &str = &s; let token_request_url = os_auth_url.to_string() + "/auth/tokens"; let resp = http::handle() .post(token_request_url, data) .header("Content-Type", "application/json") .exec().unwrap(); let body = String::from_utf8_lossy(resp.get_body()); println!("code={}; headers={:?}; body={}", resp.get_code(), resp.get_headers(), body); } |
Here is the Cargo.toml file
[package] name = "osrust" version = "0.0.1" authors = [ "Adam Young <adam@younglogic.com>" ] [dependencies.curl] git = "https://github.com/carllerche/curl-rust" [dependencies] rustc-serialize = "0.3.15" |
My Directory structure looks like this:
./src ./src/main.rs ./Cargo.toml |
Build it with:
cargo build
It reads the values necessary to connect to Keystone from environment variables, which I have in a file like this.
export OS_AUTH_URL=http://hostname:5000/v3 export OS_USERNAME=ayoung export OS_PASSWORD=changeme export OS_USER_DOMAIN_NAME=Default export OS_PROJECT_DOMAIN_NAME=Default export OS_PROJECT_NAME=ChangeMe |
To Run it
. ~/keystonev3.rc ./target/debug/osrust |
I decided to use Curl instead of rust-http, mainly due to the expectation that rust-http hasn’t dealt with Negotiate (GSSAPI, Kerberos) yet but Curl has. I want to use this approach to talk to IPA as well as to Keystone, using Kerberos for authentication. The rust-http would not be radically different.
rust is good ,esp. of systems programming.
but, you should also try “Haxe” . (see http://www.haxe.org).
1) It is also again a statically typed language
2) haxe program compiles to java ,C++,python,C#, nodejs,PHP etc programs.
So with one language you can run on any platform, any OS and any of the major VMs.
3) haxe syntax is like Actionscript, C# or java. So one can easily learn its syntax, compared to rust etc, if he is coming from these backgrounds.
also read:
https://en.wikipedia.org/wiki/HaXe
Thanks for the suggestion. I have limited bandwidth, I want native, not a VM language, and Rust has worked really hard at doing things right. One language at a time…
Just started to play Rust and I am addicted, highly recommented.
Heh. I think that is a different Rust.
I was surprised to not find an existing library to access openstack in rust! I think you should put this snippet on github as a basis for the future library 😉