add cdh plugin passwords to key manager

This patch changes the way that the cdh plugin handles its generated
passwords for the ClouderaManager, Hive, and Sentry. The helper
functions for generating and retrieving passwords has been modified to
use the key manager interface for store, retrieving, and deleting
passwords.

* modify the get_password_from_db helper function to use the key manager
  interface
* add methods to delete passwords from the key manager
* add convenience definitions for the individual password names
* add deletion to the on_terminate_cluster function of the
  AbstractVersionHandler

Change-Id: Ia55758010e42961a1ebe8159f5fc0e1787069731
Partial-Implements: blueprint improved-secret-storage
This commit is contained in:
Michael McCune 2016-01-13 12:01:24 -05:00
parent 3625f307f9
commit bdaa3f3f1d
5 changed files with 55 additions and 9 deletions

View File

@ -17,6 +17,8 @@ import abc
import six import six
from sahara.plugins.cdh import db_helper as dh
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class AbstractVersionHandler(object): class AbstractVersionHandler(object):
@ -70,4 +72,4 @@ class AbstractVersionHandler(object):
return return
def on_terminate_cluster(self, cluster): def on_terminate_cluster(self, cluster):
pass dh.delete_passwords_from_keymanager(cluster)

View File

@ -19,26 +19,70 @@ import six
from sahara import conductor from sahara import conductor
from sahara import context from sahara import context
from sahara.service.castellan import utils as key_manager
CM_PASSWORD = 'cm_password'
HIVE_DB_PASSWORD = 'hive_db_password'
SENTRY_DB_PASSWORD = 'sentry_db_password'
conductor = conductor.API conductor = conductor.API
def delete_password_from_keymanager(cluster, pwname):
"""delete the named password from the key manager
This function will lookup the named password in the cluster entry
and delete it from the key manager.
:param cluster: The cluster record containing the password
:param pwname: The name associated with the password
"""
ctx = context.ctx()
cluster = conductor.cluster_get(ctx, cluster.id)
key_id = cluster.extra.get(pwname) if cluster.extra else None
if key_id is not None:
key_manager.delete_key(key_id, ctx)
def delete_passwords_from_keymanager(cluster):
"""delete all passwords associated with a cluster
This function will remove all passwords stored in a cluster database
entry from the key manager.
:param cluster: The cluster record containing the passwords
"""
delete_password_from_keymanager(cluster, CM_PASSWORD)
delete_password_from_keymanager(cluster, HIVE_DB_PASSWORD)
delete_password_from_keymanager(cluster, SENTRY_DB_PASSWORD)
def get_password_from_db(cluster, pwname): def get_password_from_db(cluster, pwname):
"""return a password for the named entry
This function will return, or create and return, a password for the
named entry. It will store the password in the key manager and use
the ID in the database entry.
:param cluster: The cluster record containing the password
:param pwname: The entry name associated with the password
:returns: The cleartext password
"""
ctx = context.ctx() ctx = context.ctx()
cluster = conductor.cluster_get(ctx, cluster.id) cluster = conductor.cluster_get(ctx, cluster.id)
passwd = cluster.extra.get(pwname) if cluster.extra else None passwd = cluster.extra.get(pwname) if cluster.extra else None
if passwd: if passwd:
return passwd return key_manager.get_secret(passwd, ctx)
passwd = six.text_type(uuid.uuid4()) passwd = six.text_type(uuid.uuid4())
extra = cluster.extra.to_dict() if cluster.extra else {} extra = cluster.extra.to_dict() if cluster.extra else {}
extra[pwname] = passwd extra[pwname] = key_manager.store_secret(passwd, ctx)
cluster = conductor.cluster_update(ctx, cluster, {'extra': extra}) cluster = conductor.cluster_update(ctx, cluster, {'extra': extra})
return passwd return passwd
def get_cm_password(cluster): def get_cm_password(cluster):
return get_password_from_db(cluster, 'cm_password') return get_password_from_db(cluster, CM_PASSWORD)
def remote_execute_db_script(remote, script_content): def remote_execute_db_script(remote, script_content):

View File

@ -18,7 +18,7 @@ from sahara.utils import files
def get_hive_db_password(cluster): def get_hive_db_password(cluster):
return dh.get_password_from_db(cluster, 'hive_db_password') return dh.get_password_from_db(cluster, dh.HIVE_DB_PASSWORD)
def create_hive_database(cluster, remote): def create_hive_database(cluster, remote):

View File

@ -18,11 +18,11 @@ from sahara.utils import files
def get_hive_db_password(cluster): def get_hive_db_password(cluster):
return dh.get_password_from_db(cluster, 'hive_db_password') return dh.get_password_from_db(cluster, dh.HIVE_DB_PASSWORD)
def get_sentry_db_password(cluster): def get_sentry_db_password(cluster):
return dh.get_password_from_db(cluster, 'sentry_db_password') return dh.get_password_from_db(cluster, dh.SENTRY_DB_PASSWORD)
def create_hive_database(cluster, remote): def create_hive_database(cluster, remote):

View File

@ -18,11 +18,11 @@ from sahara.utils import files
def get_hive_db_password(cluster): def get_hive_db_password(cluster):
return dh.get_password_from_db(cluster, 'hive_db_password') return dh.get_password_from_db(cluster, dh.HIVE_DB_PASSWORD)
def get_sentry_db_password(cluster): def get_sentry_db_password(cluster):
return dh.get_password_from_db(cluster, 'sentry_db_password') return dh.get_password_from_db(cluster, dh.SENTRY_DB_PASSWORD)
def create_hive_database(cluster, remote): def create_hive_database(cluster, remote):