Merge pull request #6844 from ryanpetrello/fix-6561

add help text + i18n handling for built-in Tower credential types
This commit is contained in:
Ryan Petrello 2017-07-05 13:25:33 -04:00 committed by GitHub
commit a6975ad060
4 changed files with 70 additions and 22 deletions

View File

@ -1924,6 +1924,17 @@ class CredentialTypeSerializer(BaseSerializer):
)
return res
def to_representation(self, data):
value = super(CredentialTypeSerializer, self).to_representation(data)
# translate labels and help_text for credential fields "managed by Tower"
if value.get('managed_by_tower'):
for field in value.get('inputs', {}).get('fields', []):
field['label'] = _(field['label'])
if 'help_text' in field:
field['help_text'] = _(field['help_text'])
return value
# TODO: remove when API v1 is removed
@six.add_metaclass(BaseSerializerMetaclass)

View File

@ -25,8 +25,8 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=512)),
('kind', models.CharField(max_length=32, choices=[(b'ssh', 'SSH'), (b'vault', 'Vault'), (b'net', 'Network'), (b'scm', 'Source Control'), (b'cloud', 'Cloud'), (b'insights', 'Insights')])),
('managed_by_tower', models.BooleanField(default=False, editable=False)),
('inputs', awx.main.fields.CredentialTypeInputField(default={}, blank=True)),
('injectors', awx.main.fields.CredentialTypeInjectorField(default={}, blank=True)),
('inputs', awx.main.fields.CredentialTypeInputField(default={}, blank=True, help_text='Enter inputs using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.')),
('injectors', awx.main.fields.CredentialTypeInjectorField(default={}, blank=True, help_text='Enter injectors using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.')),
('created_by', models.ForeignKey(related_name="{u'class': 'credentialtype', u'app_label': 'main'}(class)s_created+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('modified_by', models.ForeignKey(related_name="{u'class': 'credentialtype', u'app_label': 'main'}(class)s_modified+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags')),

View File

@ -99,12 +99,12 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='credential',
name='credential_type',
field=models.ForeignKey(related_name='credentials', to='main.CredentialType', null=False, help_text='Type for this credential. Credential Types define valid fields (e.g,. "username", "password") and their properties (e.g,. "username is required" or "password should be stored with encryption").')
field=models.ForeignKey(related_name='credentials', to='main.CredentialType', null=False, help_text='Specify the type of credential you want to create. Refer to the Ansible Tower documentation for details on each type.')
),
migrations.AlterField(
model_name='credential',
name='inputs',
field=awx.main.fields.CredentialInputField(default={}, help_text='Data structure used to specify input values (e.g., {"username": "jane-doe", "password": "secret"}). Valid fields and their requirements vary depending on the fields defined on the chosen CredentialType.', blank=True),
field=awx.main.fields.CredentialInputField(default={}, help_text='Enter inputs using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.', blank=True),
),
migrations.RemoveField(
model_name='job',

View File

@ -219,10 +219,8 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
'CredentialType',
related_name='credentials',
null=False,
help_text=_('Type for this credential. Credential Types define '
'valid fields (e.g,. "username", "password") and their '
'properties (e.g,. "username is required" or "password '
'should be stored with encryption").')
help_text=_('Specify the type of credential you want to create. Refer '
'to the Ansible Tower documentation for details on each type.')
)
organization = models.ForeignKey(
'Organization',
@ -235,10 +233,9 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
inputs = CredentialInputField(
blank=True,
default={},
help_text=_('Data structure used to specify input values (e.g., '
'{"username": "jane-doe", "password": "secret"}). Valid '
'fields and their requirements vary depending on the '
'fields defined on the chosen CredentialType.')
help_text=_('Enter inputs using either JSON or YAML syntax. Use the '
'radio button to toggle between the two. Refer to the '
'Ansible Tower documentation for example syntax.')
)
admin_role = ImplicitRoleField(
parent_role=[
@ -421,11 +418,17 @@ class CredentialType(CommonModelNameNotUnique):
)
inputs = CredentialTypeInputField(
blank=True,
default={}
default={},
help_text=_('Enter inputs using either JSON or YAML syntax. Use the '
'radio button to toggle between the two. Refer to the '
'Ansible Tower documentation for example syntax.')
)
injectors = CredentialTypeInjectorField(
blank=True,
default={}
default={},
help_text=_('Enter injectors using either JSON or YAML syntax. Use the '
'radio button to toggle between the two. Refer to the '
'Ansible Tower documentation for example syntax.')
)
def get_absolute_url(self, request=None):
@ -621,7 +624,10 @@ def ssh(cls):
'id': 'become_method',
'label': 'Privilege Escalation Method',
'choices': map(operator.itemgetter(0),
V1Credential.FIELDS['become_method'].choices)
V1Credential.FIELDS['become_method'].choices),
'help_text': ('Specify a method for "become" operations. This is '
'equivalent to specifying the --become-method '
'Ansible parameter.')
}, {
'id': 'become_username',
'label': 'Privilege Escalation Username',
@ -751,6 +757,10 @@ def aws(cls):
'label': 'STS Token',
'type': 'string',
'secret': True,
'help_text': ('Security Token Service (STS) is a web service '
'that enables you to request temporary, '
'limited-privilege credentials for AWS Identity '
'and Access Management (IAM) users.'),
}],
'required': ['username', 'password']
}
@ -777,6 +787,8 @@ def openstack(cls):
'id': 'host',
'label': 'Host (Authentication URL)',
'type': 'string',
'help_text': ('The host to authenticate with. For example, '
'https://openstack.business.com/v2.0/')
}, {
'id': 'project',
'label': 'Project (Tenant Name)',
@ -784,7 +796,11 @@ def openstack(cls):
}, {
'id': 'domain',
'label': 'Domain Name',
'type': 'string'
'type': 'string',
'help_text': ('OpenStack domains define administrative boundaries. '
'It is only needed for Keystone v3 authentication '
'URLs. Refer to Ansible Tower documentation for '
'common scenarios.')
}],
'required': ['username', 'password', 'host', 'project']
}
@ -802,6 +818,8 @@ def vmware(cls):
'id': 'host',
'label': 'VCenter Host',
'type': 'string',
'help_text': ('Enter the hostname or IP address which corresponds '
'to your VMware vCenter.')
}, {
'id': 'username',
'label': 'Username',
@ -828,6 +846,8 @@ def satellite6(cls):
'id': 'host',
'label': 'Satellite 6 URL',
'type': 'string',
'help_text': ('Enter the URL which corresponds to your Red Hat '
'Satellite 6 server. For example, https://satellite.example.org')
}, {
'id': 'username',
'label': 'Username',
@ -853,6 +873,9 @@ def cloudforms(cls):
'id': 'host',
'label': 'CloudForms URL',
'type': 'string',
'help_text': ('Enter the URL for the virtual machine which '
'corresponds to your CloudForm instance. '
'For example, https://cloudforms.example.org')
}, {
'id': 'username',
'label': 'Username',
@ -877,18 +900,25 @@ def gce(cls):
'fields': [{
'id': 'username',
'label': 'Service Account Email Address',
'type': 'string'
'type': 'string',
'help_text': ('The email address assigned to the Google Compute '
'Engine service account.')
}, {
'id': 'project',
'label': 'Project',
'type': 'string'
'type': 'string',
'help_text': ('The Project ID is the GCE assigned identification. '
'It is constructed as two words followed by a three '
'digit number. Example: adjective-noun-000')
}, {
'id': 'ssh_key_data',
'label': 'RSA Private Key',
'type': 'string',
'format': 'ssh_private_key',
'secret': True,
'multiline': True
'multiline': True,
'help_text': ('Paste the contents of the PEM file associated '
'with the service account email.')
}]
}
)
@ -904,14 +934,19 @@ def azure(cls):
'fields': [{
'id': 'username',
'label': 'Subscription ID',
'type': 'string'
'type': 'string',
'help_text': ('Subscription ID is an Azure construct, which is '
'mapped to a username.')
}, {
'id': 'ssh_key_data',
'label': 'Management Certificate',
'type': 'string',
'format': 'ssh_private_key',
'secret': True,
'multiline': True
'multiline': True,
'help_text': ('Paste the contents of the PEM file that corresponds '
'to the certificate you uploaded in the Microsoft '
'Azure console.')
}]
}
)
@ -927,7 +962,9 @@ def azure_rm(cls):
'fields': [{
'id': 'subscription',
'label': 'Subscription ID',
'type': 'string'
'type': 'string',
'help_text': ('Subscription ID is an Azure construct, which is '
'mapped to a username.')
}, {
'id': 'username',
'label': 'Username',