-
Notifications
You must be signed in to change notification settings - Fork 7
Secure auth credential and profile files with ansible vault encryption #59
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some comments, but overall I am looking forward to this change. It will be a big improvement to Rho, and will remove some hesitations that customers could have about using Rho.
rho/authaddcommand.py
Outdated
@@ -15,28 +15,50 @@ | |||
""" | |||
|
|||
from __future__ import print_function | |||
import csv | |||
import json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 👍
""" | ||
auth_found = False | ||
for cred in cred_list: | ||
if cred.get('name') == auth_name: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we ever have credentials with no "name" field? I really don't know, just asking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. A name is a required field for an auth credential.
https://github.com/quipucords/rho/blob/master/rho/authaddcommand.py#L78
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
rho/authaddcommand.py
Outdated
cred_list.append(new_cred) | ||
|
||
data = json.dumps(cred_list, separators=(',', ': ')) | ||
with open(credentials_path, 'wb') as cred_file: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes me nervous, because if something goes wrong, I think we lose the old credentials file as well as the new one. How about writing to a new temporary file and then renaming the temp file to credentials_path
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved writing data into vault file. It now takes an object then coverts to json, the writes to temporary file, the moves to final file location.
|
||
os.remove('data/cred-temp') | ||
if self.options.name: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that in general there is a lot of duplicated code in these files, specifically in the self.parse.add_option
calls and in the "get Vault password, read credentials file, and then rewrite credentials file" patterns. I would like to move that to helper functions/classes. We could either put them in a new file, or combine all of the auth-related commands into a single file and put the helpers there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've collapsed the vault init flow to a helper method in the vault.py
file. Open to changes in the init for commands around the self.parse.add_option
, perhaps we can pursue this as part of #38.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me.
rho/vault.py
Outdated
|
||
def load_as_json(self, secure_file): | ||
"""read vault secured file and return json decoded object""" | ||
return json.loads(self.load(open(secure_file).read())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe json.loads(self.load_secure_file(secure_file))
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep. That was my intent, but must have gotten side tracked. Will fix.
test/test_clicommand.py
Outdated
@@ -58,7 +71,7 @@ def test_scan_facts_default(self): | |||
"--reset", "--reportfile", | |||
"data/test_report.csv", "--facts", | |||
"default", "ansible_forks", | |||
"100"]) | |||
"100", "--vault", "./vault_pass"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use /tmp for these files. I can imagine that writing to ./vault_pass
in some directory we don't control could cause problems for someone later on.
Also, please pull the default file paths for testing out into module-level constants or group the shared code. I know the rest of the code isn't written that way, but I think that it all should be, and at least we can avoid making it worse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved all the files for testing to /tmp
. Hopefully this is what you were going for, if not lets capture further updates here: #33
1 similar comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! This is a big improvement in Rho. 👍
""" | ||
auth_found = False | ||
for cred in cred_list: | ||
if cred.get('name') == auth_name: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
|
||
os.remove('data/cred-temp') | ||
if self.options.name: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me.
rho/scancommand.py
Outdated
@@ -66,7 +67,14 @@ def _create_ping_inventory(profile_ranges, profile_port, profile_auth_list, | |||
|
|||
string_header = copy(string_to_write) | |||
|
|||
for auth_item in profile_auth_list: | |||
for cred_item in profile_auth_list: | |||
auth_item = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestion:
auth_item = [
cred_item.get('id'),
cred_item.get('name'),
... ]
This is a first step where all i/o to
data/credentials
anddata/profiles
are encrypted/decrypted using the ansible vault api.Some notable changes: