2929
3030from openstackclient .common import clientmanager
3131from openstackclient .common import exceptions as exc
32+ from openstackclient .common import openstackkeyring
3233from openstackclient .common import utils
3334
3435
3536VERSION = '0.1'
37+ KEYRING_SERVICE = 'openstack'
3638
3739
3840def env (* vars , ** kwargs ):
@@ -123,6 +125,18 @@ def build_option_parser(self, description, version):
123125 default = env ('OS_URL' ),
124126 help = 'Defaults to env[OS_URL]' )
125127
128+ env_os_keyring = env ('OS_USE_KEYRING' , default = False )
129+ if type (env_os_keyring ) == str :
130+ if env_os_keyring .lower () in ['true' , '1' ]:
131+ env_os_keyring = True
132+ else :
133+ env_os_keyring = False
134+ parser .add_argument ('--os-use-keyring' ,
135+ default = env_os_keyring ,
136+ action = 'store_true' ,
137+ help = 'Use keyring to store password, '
138+ 'default=False (Env: OS_USE_KEYRING)' )
139+
126140 return parser
127141
128142 def authenticate_user (self ):
@@ -149,12 +163,14 @@ def authenticate_user(self):
149163 "You must provide a username via"
150164 " either --os-username or env[OS_USERNAME]" )
151165
166+ self .get_password_from_keyring ()
152167 if not self .options .os_password :
153168 # No password, if we've got a tty, try prompting for it
154169 if hasattr (sys .stdin , 'isatty' ) and sys .stdin .isatty ():
155170 # Check for Ctl-D
156171 try :
157172 self .options .os_password = getpass .getpass ()
173+ self .set_password_in_keyring ()
158174 except EOFError :
159175 pass
160176 # No password because we did't have a tty or the
@@ -188,6 +204,34 @@ def authenticate_user(self):
188204 )
189205 return
190206
207+ def init_keyring_backend (self ):
208+ """Initialize openstack backend to use for keyring"""
209+ return openstackkeyring .os_keyring ()
210+
211+ def get_password_from_keyring (self ):
212+ """Get password from keyring, if it's set"""
213+ if self .options .os_use_keyring :
214+ service = KEYRING_SERVICE
215+ backend = self .init_keyring_backend ()
216+ if not self .options .os_password :
217+ password = backend .get_password (service ,
218+ self .options .os_username )
219+ self .options .os_password = password
220+
221+ def set_password_in_keyring (self ):
222+ """Set password in keyring for this user"""
223+ if self .options .os_use_keyring :
224+ service = KEYRING_SERVICE
225+ backend = self .init_keyring_backend ()
226+ if self .options .os_password :
227+ password = backend .get_password (service ,
228+ self .options .os_username )
229+ # either password is not set in keyring, or it is different
230+ if password != self .options .os_password :
231+ backend .set_password (service ,
232+ self .options .os_username ,
233+ self .options .os_password )
234+
191235 def initialize_app (self , argv ):
192236 """Global app init bits:
193237
0 commit comments