1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
// Copyright 2017 Dmitry Tantsur <divius.inside@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Authentication modules.
//!
//! Usually, accessing OpenStack services requires authentication. This module
//! provides a way to authenticate against an Identity service, as well as
//! simple authentication implementations for standalone use.
//!
//! The usual workflow for connecting to OpenStack API is as follows:
//!
//! 1. Create a suitable authentication method.
//! 2. Populate it with authentication data (credentials, etc).
//! 3. Create a [Cloud](../struct.Cloud.html).
//!
//! # Using password authentication
//!
//! Start with creating an [Identity](struct.Identity.html) object which will
//! guide you through setting all necessary values.
//! [PasswordAuth](struct.PasswordAuth.html) is the actual implementation
//! of the authentication [method](trait.AuthMethod.html) trait.
//!
//! Note that as of now, only project-scoped tokens are supported.
//! An attempt to create unscoped tokens always fails. This restriction may
//! be lifted in the future.
//!
//! # Examples
//!
//! Creating an authentication method using project-scoped tokens:
//!
//! ```rust,no_run
//! use openstack;
//!
//! let auth = openstack::auth::Password::new(
//! "https://my.cloud.com/identity",
//! "admin", "pa$$w0rd", "domain.com")
//! .expect("Invalid authentication URL")
//! .with_project_scope("project1", "domain.com");
//! let os = openstack::Cloud::new(auth);
//! ```
//!
//! Creating a session and a cloud from environment variables:
//!
//! ```rust,no_run
//! use openstack;
//!
//! let session = openstack::auth::from_env().expect("Failed to authenticate");
//! let os = openstack::Cloud::from(session);
//! ```
//!
//! Creating a dummy authentication method for use against clouds that do not
//! have actual authentication:
//!
//! ```
//! use openstack;
//!
//! let auth = openstack::auth::NoAuth::new("https://my.cloud.com/some-service")
//! .unwrap();
//! let os = openstack::Cloud::new(auth);
//! ```
//!
//! # Limitations
//!
//! * Only Identity API v3 is supported and planned for support.
mod base;
mod config;
mod identity;
mod simple;
pub use self::base::{AuthMethod, BoxedClone};
pub use self::config::from_config;
pub use self::simple::NoAuth;
pub use self::identity::{Identity, Password};
use std::env;
use super::{Error, ErrorKind, Result};
use super::session::Session;
const MISSING_ENV_VARS: &str =
"Not all required environment variables were provided";
#[inline]
fn _get_env(name: &str) -> Result<String> {
env::var(name).map_err(|_| {
Error::new(ErrorKind::InvalidInput, MISSING_ENV_VARS)
})
}
/// Create a `Session` from environment variables.
pub fn from_env() -> Result<Session> {
if let Ok(cloud_name) = env::var("OS_CLOUD") {
from_config(cloud_name)
} else {
let auth_url = _get_env("OS_AUTH_URL")?;
let user_name = _get_env("OS_USERNAME")?;
let password = _get_env("OS_PASSWORD")?;
let user_domain = env::var("OS_USER_DOMAIN_NAME")
.unwrap_or(String::from("Default"));
let id = Password::new(&auth_url, user_name, password, user_domain)?;
let project_name = _get_env("OS_PROJECT_NAME")?;
let project_domain = env::var("OS_PROJECT_DOMAIN_NAME")
.unwrap_or(String::from("Default"));
Ok(Session::new(id.with_project_scope(project_name, project_domain)))
}
}