Merge "Remove keyring support from openstackclient"
This commit is contained in:
commit
b3736fd9df
@ -79,7 +79,6 @@ The 'password flow' variation is most commonly used::
|
|||||||
export OS_PROJECT_NAME=<project-name>
|
export OS_PROJECT_NAME=<project-name>
|
||||||
export OS_USERNAME=<user-name>
|
export OS_USERNAME=<user-name>
|
||||||
export OS_PASSWORD=<password> # (optional)
|
export OS_PASSWORD=<password> # (optional)
|
||||||
export OS_USE_KEYRING=true # (optional)
|
|
||||||
|
|
||||||
The corresponding command-line options look very similar::
|
The corresponding command-line options look very similar::
|
||||||
|
|
||||||
@ -87,12 +86,9 @@ The corresponding command-line options look very similar::
|
|||||||
--os-project-name <project-name>
|
--os-project-name <project-name>
|
||||||
--os-username <user-name>
|
--os-username <user-name>
|
||||||
[--os-password <password>]
|
[--os-password <password>]
|
||||||
[--os-use-keyring]
|
|
||||||
|
|
||||||
If a password is not provided above (in plaintext), you will be interactively
|
If a password is not provided above (in plaintext), you will be interactively
|
||||||
prompted to provide one securely. If keyring is enabled, the password entered
|
prompted to provide one securely.
|
||||||
in the prompt is stored in keyring. From next time, the password is read from
|
|
||||||
keyring, if it is not provided above (in plaintext).
|
|
||||||
|
|
||||||
The token flow variation for authentication uses an already-acquired token
|
The token flow variation for authentication uses an already-acquired token
|
||||||
and a URL pointing directly to the service API that presumably was acquired
|
and a URL pointing directly to the service API that presumably was acquired
|
||||||
|
@ -68,9 +68,6 @@ OPTIONS
|
|||||||
:option:`--os-default-domain` <auth-domain>
|
:option:`--os-default-domain` <auth-domain>
|
||||||
Default domain ID (Default: 'default')
|
Default domain ID (Default: 'default')
|
||||||
|
|
||||||
:option:`--os-use-keyring`
|
|
||||||
Use keyring to store password (default: False)
|
|
||||||
|
|
||||||
:option:`--os-cacert` <ca-bundle-file>
|
:option:`--os-cacert` <ca-bundle-file>
|
||||||
CA certificate bundle file
|
CA certificate bundle file
|
||||||
|
|
||||||
@ -177,9 +174,6 @@ The following environment variables can be set to alter the behaviour of :progra
|
|||||||
:envvar:`OS_DEFAULT_DOMAIN`
|
:envvar:`OS_DEFAULT_DOMAIN`
|
||||||
Default domain ID (Default: ‘default’)
|
Default domain ID (Default: ‘default’)
|
||||||
|
|
||||||
:envvar:`OS_USE_KEYRING`
|
|
||||||
Use keyring to store password (default: False)
|
|
||||||
|
|
||||||
:envvar:`OS_CACERT`
|
:envvar:`OS_CACERT`
|
||||||
CA certificate bundle file
|
CA certificate bundle file
|
||||||
|
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
# Copyright 2011-2013 OpenStack, LLC.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
"""Keyring backend for OpenStack, to store encrypted password in a file."""
|
|
||||||
|
|
||||||
from Crypto.Cipher import AES
|
|
||||||
|
|
||||||
import keyring
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
KEYRING_FILE = os.path.join(os.path.expanduser('~'), '.openstack-keyring.cfg')
|
|
||||||
|
|
||||||
|
|
||||||
class OpenStackKeyring(keyring.backends.file.BaseKeyring):
|
|
||||||
"""OpenStack Keyring to store encrypted password."""
|
|
||||||
filename = KEYRING_FILE
|
|
||||||
|
|
||||||
def supported(self):
|
|
||||||
"""Applicable for all platforms, but not recommend."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _init_crypter(self):
|
|
||||||
"""Initialize the crypter using the class name."""
|
|
||||||
block_size = 32
|
|
||||||
padding = '0'
|
|
||||||
|
|
||||||
# init the cipher with the class name, up to block_size
|
|
||||||
password = __name__[block_size:]
|
|
||||||
password = password + (block_size - len(password) %
|
|
||||||
block_size) * padding
|
|
||||||
return AES.new(password, AES.MODE_CFB)
|
|
||||||
|
|
||||||
def encrypt(self, password):
|
|
||||||
"""Encrypt the given password."""
|
|
||||||
crypter = self._init_crypter()
|
|
||||||
return crypter.encrypt(password)
|
|
||||||
|
|
||||||
def decrypt(self, password_encrypted):
|
|
||||||
"""Decrypt the given password."""
|
|
||||||
crypter = self._init_crypter()
|
|
||||||
return crypter.decrypt(password_encrypted)
|
|
||||||
|
|
||||||
|
|
||||||
def os_keyring():
|
|
||||||
"""Initialize the openstack keyring."""
|
|
||||||
ring = 'openstackclient.common.openstackkeyring.OpenStackKeyring'
|
|
||||||
return keyring.core.load_keyring(None, ring)
|
|
@ -31,7 +31,6 @@ import openstackclient
|
|||||||
from openstackclient.common import clientmanager
|
from openstackclient.common import clientmanager
|
||||||
from openstackclient.common import commandmanager
|
from openstackclient.common import commandmanager
|
||||||
from openstackclient.common import exceptions as exc
|
from openstackclient.common import exceptions as exc
|
||||||
from openstackclient.common import openstackkeyring
|
|
||||||
from openstackclient.common import restapi
|
from openstackclient.common import restapi
|
||||||
from openstackclient.common import utils
|
from openstackclient.common import utils
|
||||||
from openstackclient.identity import client as identity_client
|
from openstackclient.identity import client as identity_client
|
||||||
@ -305,18 +304,6 @@ class OpenStackShell(app.App):
|
|||||||
default=env('OS_URL'),
|
default=env('OS_URL'),
|
||||||
help='Defaults to env[OS_URL]')
|
help='Defaults to env[OS_URL]')
|
||||||
|
|
||||||
env_os_keyring = env('OS_USE_KEYRING', default=False)
|
|
||||||
if type(env_os_keyring) == str:
|
|
||||||
if env_os_keyring.lower() in ['true', '1']:
|
|
||||||
env_os_keyring = True
|
|
||||||
else:
|
|
||||||
env_os_keyring = False
|
|
||||||
parser.add_argument('--os-use-keyring',
|
|
||||||
default=env_os_keyring,
|
|
||||||
action='store_true',
|
|
||||||
help='Use keyring to store password, '
|
|
||||||
'default=False (Env: OS_USE_KEYRING)')
|
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--os-identity-api-version',
|
'--os-identity-api-version',
|
||||||
metavar='<identity-api-version>',
|
metavar='<identity-api-version>',
|
||||||
@ -359,14 +346,12 @@ class OpenStackShell(app.App):
|
|||||||
"You must provide a username via"
|
"You must provide a username via"
|
||||||
" either --os-username or env[OS_USERNAME]")
|
" either --os-username or env[OS_USERNAME]")
|
||||||
|
|
||||||
self.get_password_from_keyring()
|
|
||||||
if not self.options.os_password:
|
if not self.options.os_password:
|
||||||
# No password, if we've got a tty, try prompting for it
|
# No password, if we've got a tty, try prompting for it
|
||||||
if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty():
|
if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty():
|
||||||
# Check for Ctl-D
|
# Check for Ctl-D
|
||||||
try:
|
try:
|
||||||
self.options.os_password = getpass.getpass()
|
self.options.os_password = getpass.getpass()
|
||||||
self.set_password_in_keyring()
|
|
||||||
except EOFError:
|
except EOFError:
|
||||||
pass
|
pass
|
||||||
# No password because we did't have a tty or the
|
# No password because we did't have a tty or the
|
||||||
@ -430,34 +415,6 @@ class OpenStackShell(app.App):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
def init_keyring_backend(self):
|
|
||||||
"""Initialize openstack backend to use for keyring"""
|
|
||||||
return openstackkeyring.os_keyring()
|
|
||||||
|
|
||||||
def get_password_from_keyring(self):
|
|
||||||
"""Get password from keyring, if it's set"""
|
|
||||||
if self.options.os_use_keyring:
|
|
||||||
service = KEYRING_SERVICE
|
|
||||||
backend = self.init_keyring_backend()
|
|
||||||
if not self.options.os_password:
|
|
||||||
password = backend.get_password(service,
|
|
||||||
self.options.os_username)
|
|
||||||
self.options.os_password = password
|
|
||||||
|
|
||||||
def set_password_in_keyring(self):
|
|
||||||
"""Set password in keyring for this user"""
|
|
||||||
if self.options.os_use_keyring:
|
|
||||||
service = KEYRING_SERVICE
|
|
||||||
backend = self.init_keyring_backend()
|
|
||||||
if self.options.os_password:
|
|
||||||
password = backend.get_password(service,
|
|
||||||
self.options.os_username)
|
|
||||||
# either password is not set in keyring, or it is different
|
|
||||||
if password != self.options.os_password:
|
|
||||||
backend.set_password(service,
|
|
||||||
self.options.os_username,
|
|
||||||
self.options.os_password)
|
|
||||||
|
|
||||||
def initialize_app(self, argv):
|
def initialize_app(self, argv):
|
||||||
"""Global app init bits:
|
"""Global app init bits:
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
pbr>=0.6,!=0.7,<1.0
|
pbr>=0.6,!=0.7,<1.0
|
||||||
cliff>=1.6.0
|
cliff>=1.6.0
|
||||||
keyring>=2.1
|
|
||||||
pycrypto>=2.6
|
|
||||||
python-glanceclient>=0.13.1
|
python-glanceclient>=0.13.1
|
||||||
python-keystoneclient>=0.9.0
|
python-keystoneclient>=0.9.0
|
||||||
python-novaclient>=2.17.0
|
python-novaclient>=2.17.0
|
||||||
|
Loading…
Reference in New Issue
Block a user