Merge pull request #3021 from jakemcdermott/credential_input_access_methods

add input access methods to credentials

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
softwarefactory-project-zuul[bot]
2019-01-21 21:10:12 +00:00
committed by GitHub
8 changed files with 178 additions and 87 deletions

View File

@@ -385,6 +385,7 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
def encrypt_field(self, field, ask):
if not hasattr(self, field):
return None
encrypted = encrypt_field(self, field, ask=ask)
if encrypted:
self.inputs[field] = encrypted
@@ -415,12 +416,12 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
type_alias = self.credential_type.name
else:
type_alias = self.credential_type_id
if self.kind == 'vault' and self.inputs.get('vault_id', None):
if self.kind == 'vault' and self.has_input('vault_id'):
if display:
fmt_str = six.text_type('{} (id={})')
else:
fmt_str = six.text_type('{}_{}')
return fmt_str.format(type_alias, self.inputs.get('vault_id'))
return fmt_str.format(type_alias, self.get_input('vault_id'))
return six.text_type(type_alias)
@staticmethod
@@ -430,6 +431,29 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
ret[cred.unique_hash()] = cred
return ret
def get_input(self, field_name, **kwargs):
"""
Get an injectable and decrypted value for an input field.
Retrieves the value for a given credential input field name. Return
values for secret input fields are decrypted. If the credential doesn't
have an input value defined for the given field name, an AttributeError
is raised unless a default value is provided.
:param field_name(str): The name of the input field.
:param default(optional[str]): A default return value to use.
"""
if field_name in self.credential_type.secret_fields:
return decrypt_field(self, field_name)
if field_name in self.inputs:
return self.inputs[field_name]
if 'default' in kwargs:
return kwargs['default']
raise AttributeError(field_name)
def has_input(self, field_name):
return field_name in self.inputs and self.inputs[field_name] not in ('', None)
class CredentialType(CommonModelNameNotUnique):
'''
@@ -611,8 +635,9 @@ class CredentialType(CommonModelNameNotUnique):
safe_namespace[field_name] = namespace[field_name] = value
continue
value = credential.get_input(field_name)
if field_name in self.secret_fields:
value = decrypt_field(credential, field_name)
safe_namespace[field_name] = '**********'
elif len(value):
safe_namespace[field_name] = value

View File

@@ -3,25 +3,28 @@ import os
import stat
import tempfile
from awx.main.utils import decrypt_field
from django.conf import settings
def aws(cred, env, private_data_dir):
env['AWS_ACCESS_KEY_ID'] = cred.username
env['AWS_SECRET_ACCESS_KEY'] = decrypt_field(cred, 'password')
if len(cred.security_token) > 0:
env['AWS_SECURITY_TOKEN'] = decrypt_field(cred, 'security_token')
env['AWS_ACCESS_KEY_ID'] = cred.get_input('username', default='')
env['AWS_SECRET_ACCESS_KEY'] = cred.get_input('password', default='')
if cred.has_input('security_token'):
env['AWS_SECURITY_TOKEN'] = cred.get_input('security_token', default='')
def gce(cred, env, private_data_dir):
env['GCE_EMAIL'] = cred.username
env['GCE_PROJECT'] = cred.project
project = cred.get_input('project', default='')
username = cred.get_input('username', default='')
env['GCE_EMAIL'] = username
env['GCE_PROJECT'] = project
json_cred = {
'type': 'service_account',
'private_key': decrypt_field(cred, 'ssh_key_data'),
'client_email': cred.username,
'project_id': cred.project
'private_key': cred.get_input('ssh_key_data', default=''),
'client_email': username,
'project_id': project
}
handle, path = tempfile.mkstemp(dir=private_data_dir)
f = os.fdopen(handle, 'w')
@@ -32,21 +35,25 @@ def gce(cred, env, private_data_dir):
def azure_rm(cred, env, private_data_dir):
if len(cred.client) and len(cred.tenant):
env['AZURE_CLIENT_ID'] = cred.client
env['AZURE_SECRET'] = decrypt_field(cred, 'secret')
env['AZURE_TENANT'] = cred.tenant
env['AZURE_SUBSCRIPTION_ID'] = cred.subscription
client = cred.get_input('client', default='')
tenant = cred.get_input('tenant', default='')
if len(client) and len(tenant):
env['AZURE_CLIENT_ID'] = client
env['AZURE_TENANT'] = tenant
env['AZURE_SECRET'] = cred.get_input('secret', default='')
env['AZURE_SUBSCRIPTION_ID'] = cred.get_input('subscription', default='')
else:
env['AZURE_SUBSCRIPTION_ID'] = cred.subscription
env['AZURE_AD_USER'] = cred.username
env['AZURE_PASSWORD'] = decrypt_field(cred, 'password')
if cred.inputs.get('cloud_environment', None):
env['AZURE_CLOUD_ENVIRONMENT'] = cred.inputs['cloud_environment']
env['AZURE_SUBSCRIPTION_ID'] = cred.get_input('subscription', default='')
env['AZURE_AD_USER'] = cred.get_input('username', default='')
env['AZURE_PASSWORD'] = cred.get_input('password', default='')
if cred.has_input('cloud_environment'):
env['AZURE_CLOUD_ENVIRONMENT'] = cred.get_input('cloud_environment')
def vmware(cred, env, private_data_dir):
env['VMWARE_USER'] = cred.username
env['VMWARE_PASSWORD'] = decrypt_field(cred, 'password')
env['VMWARE_HOST'] = cred.host
env['VMWARE_USER'] = cred.get_input('username', default='')
env['VMWARE_PASSWORD'] = cred.get_input('password', default='')
env['VMWARE_HOST'] = cred.get_input('host', default='')
env['VMWARE_VALIDATE_CERTS'] = str(settings.VMWARE_VALIDATE_CERTS)

View File

@@ -166,8 +166,8 @@ class ProjectOptions(models.Model):
check_special_cases=False)
scm_url_parts = urlparse.urlsplit(scm_url)
# Prefer the username/password in the URL, if provided.
scm_username = scm_url_parts.username or cred.username or ''
if scm_url_parts.password or cred.password:
scm_username = scm_url_parts.username or cred.get_input('username', default='')
if scm_url_parts.password or cred.has_input('password'):
scm_password = '********'
else:
scm_password = ''