Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add keystone support #12

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 50 additions & 6 deletions IronCore.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class IronCore
protected $curl = null;
protected $last_status;

protected $keystone;
protected $use_keystone;
protected $keystone_token;
protected $keystone_token_expires;

protected $urlFetchContext;
protected $urlFetchData;
protected $urlFetchUrl;
Expand Down Expand Up @@ -150,9 +155,16 @@ protected function getConfigData($config)

$this->loadFromHash($this->default_values);

if (empty($this->token) || empty($this->project_id)) {
if (empty($this->project_id)) {
throw new InvalidArgumentException("token or project_id not found in any of the available sources");
}

if (!empty($this->keystone)){
$required_keys = array('username', 'password', 'tenant', 'server');
if (count(array_intersect_key(array_flip($required_keys), $this->keystone)) === count($required_keys)) {
$this->use_keystone = True;
}
}
}


Expand All @@ -168,6 +180,7 @@ protected function loadFromHash($options)
$this->setVarIfValue('port', $options);
$this->setVarIfValue('api_version', $options);
$this->setVarIfValue('encryption_key', $options);
$this->setVarIfValue('keystone', $options);
}

protected function loadFromEnv($prefix)
Expand Down Expand Up @@ -219,17 +232,13 @@ protected function loadConfigFile($file)
$this->loadFromHash($data);
}

protected function apiCall($type, $url, $params = array(), $data = null)
protected function request($type, $url, $params = array(), $data = null)
{
$url = "{$this->url}$url";
$this->debug("API $type", $url);

if ($this->curl == null && $this->curlEnabled()) {
$this->curl = curl_init();
}
if (!isset($params['oauth'])) {
$params['oauth'] = $this->token;
}
if ($this->curlEnabled()) {
switch ($type) {
case self::DELETE:
Expand Down Expand Up @@ -305,6 +314,15 @@ protected function apiCall($type, $url, $params = array(), $data = null)
return $this->callWithRetries();
}

protected function apiCall($type, $url, $params = array(), $data = null)
{
$url = "{$this->url}$url";
if (!isset($params['oauth'])) {
$params['oauth'] = $this->token;
}
return $this -> request($type, $url, $params, $data);
}

protected function callWithRetries()
{
for ($retry = 0; $retry < $this->max_retries; $retry++) {
Expand Down Expand Up @@ -421,6 +439,32 @@ protected function setCommonHeaders()
'Keep-Alive' => '300'
);
}

protected function getToken()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find any call of getToken :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry, it's iron_core

{
$current_time = new DateTime("now", new DateTimeZone('UTC'));
if (is_null($this->keystone_token) || $current_time > $this->keystone_token_expires) {

$req = array(
'auth' => array(
'tenantName' => $this->keystone['tenant'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tenantId as far as I understand how it works , names are not reliable

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thousandsofthem, could you clarify?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. Also, tenantId always equal to project_id so could be derived from it
P.P.S. tenantName is not unique therefore can't be used as a key

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thousandsofthem,

  • @edsrzf said we should support not tenantId, but tenantName, please discuss it with him.
  • Why 'tenantName' string is not unique key?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tenantName means "project name", and user can set any name he wants to, including duplicate ones.
@edsrzf do you know anything else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some notes:

  • only project_id required (with tenantId), project name is extra dependency
  • tenantId actually works with test server and on AT&T installation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any update so far?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edsrzf, @carimura, @treeder

We implemented support of format "keystone": { "server": ..., "tenant": ..., "username": ..., "password": ... } because we discussed it with Evan and he accepted this way. @thousandsofthem wants to change this format and we will change it if somebody of you confirm it.

'passwordCredentials' => array(
'username' => $this->keystone['username'],
'password' => $this->keystone['password']
)
)
);
$this -> setCommonHeaders();
$url = $this->keystone['server'].'tokens';
$response = json_decode($this->request(self::POST, $url, $req), true);
$token = $response['access']['token'];
$timespan = abs(strtotime($token['expires']) - strtotime($token['issued_at']));
$this->keystone_token_expires = $current_time->add(new DateInterval('PT'.$timespan.'S'));
$this->keystone_token = $token['id'];
}

return $this->keystone_token;
}
}

/**
Expand Down