diff --git a/CHANGELOG.md b/CHANGELOG.md
index ffad4cfb70..afa7697114 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,25 @@
This is a list of high-level changes for each release of AWX. A full list of commits can be found at `https://github.com/ansible/awx/releases/tag/`.
+## 15.0.0 (September 30, 2020)
+- AWX now utilizes a version of certifi that auto-discovers certificates in the system certificate store - https://github.com/ansible/awx/pull/8242
+- Added support for arbitrary custom inventory plugin configuration: https://github.com/ansible/awx/issues/5150
+- Added improved support for fetching Ansible collections from private Galaxy content sources (such as https://github.com/ansible/galaxy_ng) - https://github.com/ansible/awx/issues/7813
+- Added an optional setting to disable the auto-creation of organizations and teams on successful SAML login. - https://github.com/ansible/awx/pull/8069
+- Added a number of optimizations to AWX's callback receiver to improve the speed of stdout processing for simultaneous playbooks runs - https://github.com/ansible/awx/pull/8193 https://github.com/ansible/awx/pull/8191
+- Added the ability to use `!include` and `!import` constructors when constructing YAML for use with the AWX CLI - https://github.com/ansible/awx/issues/8135
+- Fixed a bug that prevented certain users from being able to edit approval nodes in Workflows - https://github.com/ansible/awx/pull/8253
+- Fixed a bug that broke password prompting for credentials in certain cases - https://github.com/ansible/awx/issues/8202
+- Fixed a bug which can cause PostgreSQL deadlocks when running many parallel playbooks against large shared inventories - https://github.com/ansible/awx/issues/8145
+- Fixed a bug which can cause delays in AWX's task manager when large numbers of simultaneous jobs are scheduled - https://github.com/ansible/awx/issues/7655
+- Fixed a bug which can cause certain scheduled jobs - those that run every X minute(s) or hour(s) - to fail to run at the proper time - https://github.com/ansible/awx/issues/8071
+- Fixed a performance issue for playbooks that store large amounts of data using the `set_stats` module - https://github.com/ansible/awx/issues/8006
+- Fixed a bug related to AWX's handling of the auth_path argument for the HashiVault KeyValue credential plugin - https://github.com/ansible/awx/pull/7991
+- Fixed a bug that broke support for Remote Archive SCM Type project syncs on platforms that utilize Python2 - https://github.com/ansible/awx/pull/8057
+- Updated to the latest version of Django Rest Framework to address CVE-2020-25626
+- Updated to the latest version of Django to address CVE-2020-24583 and CVE-2020-24584
+- Updated to the latest verson of channels_redis to address a bug that slowly causes Daphne processes to leak memory over time - https://github.com/django/channels_redis/issues/212
+
## 14.1.0 (Aug 25, 2020)
- AWX images can now be built on ARM64 - https://github.com/ansible/awx/pull/7607
- Added the Remote Archive SCM Type to support using immutable artifacts and releases (such as tarballs and zip files) as projects - https://github.com/ansible/awx/issues/7954
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 42516b9a15..bd3da38b51 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -80,7 +80,7 @@ For Linux platforms, refer to the following from Docker:
If you're not using Docker for Mac, or Docker for Windows, you may need, or choose to, install the Docker compose Python module separately, in which case you'll need to run the following:
```bash
-(host)$ pip install docker-compose
+(host)$ pip3 install docker-compose
```
#### Frontend Development
diff --git a/VERSION b/VERSION
index 7b3b6e02bb..94188a7483 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-14.1.0
+15.0.0
diff --git a/awx/api/conf.py b/awx/api/conf.py
index 493eed6981..f7da952004 100644
--- a/awx/api/conf.py
+++ b/awx/api/conf.py
@@ -16,6 +16,7 @@ register(
help_text=_('Number of seconds that a user is inactive before they will need to login again.'),
category=_('Authentication'),
category_slug='authentication',
+ unit=_('seconds'),
)
register(
'SESSIONS_PER_USER',
@@ -49,6 +50,7 @@ register(
'in the number of seconds.'),
category=_('Authentication'),
category_slug='authentication',
+ unit=_('seconds'),
)
register(
'ALLOW_OAUTH2_FOR_EXTERNAL_USERS',
diff --git a/awx/api/metadata.py b/awx/api/metadata.py
index 847e353890..0b60f9a1ef 100644
--- a/awx/api/metadata.py
+++ b/awx/api/metadata.py
@@ -39,7 +39,7 @@ class Metadata(metadata.SimpleMetadata):
'min_length', 'max_length',
'min_value', 'max_value',
'category', 'category_slug',
- 'defined_in_file'
+ 'defined_in_file', 'unit',
]
for attr in text_attrs:
diff --git a/awx/api/serializers.py b/awx/api/serializers.py
index 83575025e7..2bb25f3de2 100644
--- a/awx/api/serializers.py
+++ b/awx/api/serializers.py
@@ -1269,6 +1269,7 @@ class OrganizationSerializer(BaseSerializer):
object_roles = self.reverse('api:organization_object_roles_list', kwargs={'pk': obj.pk}),
access_list = self.reverse('api:organization_access_list', kwargs={'pk': obj.pk}),
instance_groups = self.reverse('api:organization_instance_groups_list', kwargs={'pk': obj.pk}),
+ galaxy_credentials = self.reverse('api:organization_galaxy_credentials_list', kwargs={'pk': obj.pk}),
))
return res
@@ -2536,10 +2537,11 @@ class CredentialTypeSerializer(BaseSerializer):
class CredentialSerializer(BaseSerializer):
show_capabilities = ['edit', 'delete', 'copy', 'use']
capabilities_prefetch = ['admin', 'use']
+ managed_by_tower = serializers.ReadOnlyField()
class Meta:
model = Credential
- fields = ('*', 'organization', 'credential_type', 'inputs', 'kind', 'cloud', 'kubernetes')
+ fields = ('*', 'organization', 'credential_type', 'managed_by_tower', 'inputs', 'kind', 'cloud', 'kubernetes')
extra_kwargs = {
'credential_type': {
'label': _('Credential Type'),
@@ -2603,6 +2605,13 @@ class CredentialSerializer(BaseSerializer):
return summary_dict
+ def validate(self, attrs):
+ if self.instance and self.instance.managed_by_tower:
+ raise PermissionDenied(
+ detail=_("Modifications not allowed for managed credentials")
+ )
+ return super(CredentialSerializer, self).validate(attrs)
+
def get_validation_exclusions(self, obj=None):
ret = super(CredentialSerializer, self).get_validation_exclusions(obj)
for field in ('credential_type', 'inputs'):
@@ -2610,6 +2619,17 @@ class CredentialSerializer(BaseSerializer):
ret.remove(field)
return ret
+ def validate_organization(self, org):
+ if (
+ self.instance and
+ self.instance.credential_type.kind == 'galaxy' and
+ org is None
+ ):
+ raise serializers.ValidationError(_(
+ "Galaxy credentials must be owned by an Organization."
+ ))
+ return org
+
def validate_credential_type(self, credential_type):
if self.instance and credential_type.pk != self.instance.credential_type.pk:
for related_objects in (
@@ -2674,6 +2694,15 @@ class CredentialSerializerCreate(CredentialSerializer):
if attrs.get('team'):
attrs['organization'] = attrs['team'].organization
+ if (
+ 'credential_type' in attrs and
+ attrs['credential_type'].kind == 'galaxy' and
+ list(owner_fields) != ['organization']
+ ):
+ raise serializers.ValidationError({"organization": _(
+ "Galaxy credentials must be owned by an Organization."
+ )})
+
return super(CredentialSerializerCreate, self).validate(attrs)
def create(self, validated_data):
@@ -4128,7 +4157,10 @@ class JobLaunchSerializer(BaseSerializer):
# verify that credentials (either provided or existing) don't
# require launch-time passwords that have not been provided
if 'credentials' in accepted:
- launch_credentials = accepted['credentials']
+ launch_credentials = Credential.unique_dict(
+ list(template_credentials.all()) +
+ list(accepted['credentials'])
+ ).values()
else:
launch_credentials = template_credentials
passwords = attrs.get('credential_passwords', {}) # get from original attrs
diff --git a/awx/api/urls/organization.py b/awx/api/urls/organization.py
index 3d172f1360..12b2807905 100644
--- a/awx/api/urls/organization.py
+++ b/awx/api/urls/organization.py
@@ -21,6 +21,7 @@ from awx.api.views import (
OrganizationNotificationTemplatesSuccessList,
OrganizationNotificationTemplatesApprovalList,
OrganizationInstanceGroupsList,
+ OrganizationGalaxyCredentialsList,
OrganizationObjectRolesList,
OrganizationAccessList,
OrganizationApplicationList,
@@ -49,6 +50,7 @@ urls = [
url(r'^(?P[0-9]+)/notification_templates_approvals/$', OrganizationNotificationTemplatesApprovalList.as_view(),
name='organization_notification_templates_approvals_list'),
url(r'^(?P[0-9]+)/instance_groups/$', OrganizationInstanceGroupsList.as_view(), name='organization_instance_groups_list'),
+ url(r'^(?P[0-9]+)/galaxy_credentials/$', OrganizationGalaxyCredentialsList.as_view(), name='organization_galaxy_credentials_list'),
url(r'^(?P[0-9]+)/object_roles/$', OrganizationObjectRolesList.as_view(), name='organization_object_roles_list'),
url(r'^(?P[0-9]+)/access_list/$', OrganizationAccessList.as_view(), name='organization_access_list'),
url(r'^(?P[0-9]+)/applications/$', OrganizationApplicationList.as_view(), name='organization_applications_list'),
diff --git a/awx/api/views/__init__.py b/awx/api/views/__init__.py
index c5b22d105a..4f436c8f0e 100644
--- a/awx/api/views/__init__.py
+++ b/awx/api/views/__init__.py
@@ -124,6 +124,7 @@ from awx.api.views.organization import ( # noqa
OrganizationNotificationTemplatesSuccessList,
OrganizationNotificationTemplatesApprovalList,
OrganizationInstanceGroupsList,
+ OrganizationGalaxyCredentialsList,
OrganizationAccessList,
OrganizationObjectRolesList,
)
@@ -1355,6 +1356,13 @@ class CredentialDetail(RetrieveUpdateDestroyAPIView):
model = models.Credential
serializer_class = serializers.CredentialSerializer
+ def destroy(self, request, *args, **kwargs):
+ instance = self.get_object()
+ if instance.managed_by_tower:
+ raise PermissionDenied(detail=_("Deletion not allowed for managed credentials"))
+ return super(CredentialDetail, self).destroy(request, *args, **kwargs)
+
+
class CredentialActivityStreamList(SubListAPIView):
diff --git a/awx/api/views/metrics.py b/awx/api/views/metrics.py
index 8d78dea21f..39744e1bcd 100644
--- a/awx/api/views/metrics.py
+++ b/awx/api/views/metrics.py
@@ -22,7 +22,7 @@ from awx.api.generics import (
)
-logger = logging.getLogger('awx.main.analytics')
+logger = logging.getLogger('awx.analytics')
class MetricsView(APIView):
diff --git a/awx/api/views/organization.py b/awx/api/views/organization.py
index cb929ec5b5..06172af79f 100644
--- a/awx/api/views/organization.py
+++ b/awx/api/views/organization.py
@@ -7,6 +7,7 @@ import logging
# Django
from django.db.models import Count
from django.contrib.contenttypes.models import ContentType
+from django.utils.translation import ugettext_lazy as _
# AWX
from awx.main.models import (
@@ -20,7 +21,8 @@ from awx.main.models import (
Role,
User,
Team,
- InstanceGroup
+ InstanceGroup,
+ Credential
)
from awx.api.generics import (
ListCreateAPIView,
@@ -42,7 +44,8 @@ from awx.api.serializers import (
RoleSerializer,
NotificationTemplateSerializer,
InstanceGroupSerializer,
- ProjectSerializer, JobTemplateSerializer, WorkflowJobTemplateSerializer
+ ProjectSerializer, JobTemplateSerializer, WorkflowJobTemplateSerializer,
+ CredentialSerializer
)
from awx.api.views.mixin import (
RelatedJobsPreventDeleteMixin,
@@ -214,6 +217,20 @@ class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
relationship = 'instance_groups'
+class OrganizationGalaxyCredentialsList(SubListAttachDetachAPIView):
+
+ model = Credential
+ serializer_class = CredentialSerializer
+ parent_model = Organization
+ relationship = 'galaxy_credentials'
+
+ def is_valid_relation(self, parent, sub, created=False):
+ if sub.kind != 'galaxy_api_token':
+ return {'msg': _(
+ f"Credential must be a Galaxy credential, not {sub.credential_type.name}."
+ )}
+
+
class OrganizationAccessList(ResourceAccessList):
model = User # needs to be User for AccessLists's
diff --git a/awx/api/views/root.py b/awx/api/views/root.py
index 4a15936e9b..aeda19cdeb 100644
--- a/awx/api/views/root.py
+++ b/awx/api/views/root.py
@@ -21,6 +21,7 @@ import requests
from awx.api.generics import APIView
from awx.conf.registry import settings_registry
+from awx.main.analytics import all_collectors
from awx.main.ha import is_ha_environment
from awx.main.utils import (
get_awx_version,
@@ -252,6 +253,7 @@ class ApiV2ConfigView(APIView):
ansible_version=get_ansible_version(),
eula=render_to_string("eula.md") if license_data.get('license_type', 'UNLICENSED') != 'open' else '',
analytics_status=pendo_state,
+ analytics_collectors=all_collectors(),
become_methods=PRIVILEGE_ESCALATION_METHODS,
)
diff --git a/awx/conf/registry.py b/awx/conf/registry.py
index 63336fc55e..e8e52fe695 100644
--- a/awx/conf/registry.py
+++ b/awx/conf/registry.py
@@ -129,12 +129,14 @@ class SettingsRegistry(object):
placeholder = field_kwargs.pop('placeholder', empty)
encrypted = bool(field_kwargs.pop('encrypted', False))
defined_in_file = bool(field_kwargs.pop('defined_in_file', False))
+ unit = field_kwargs.pop('unit', None)
if getattr(field_kwargs.get('child', None), 'source', None) is not None:
field_kwargs['child'].source = None
field_instance = field_class(**field_kwargs)
field_instance.category_slug = category_slug
field_instance.category = category
field_instance.depends_on = depends_on
+ field_instance.unit = unit
if placeholder is not empty:
field_instance.placeholder = placeholder
field_instance.defined_in_file = defined_in_file
diff --git a/awx/conf/settings.py b/awx/conf/settings.py
index 98a39978d3..d2733ce879 100644
--- a/awx/conf/settings.py
+++ b/awx/conf/settings.py
@@ -17,6 +17,8 @@ from django.utils.functional import cached_property
# Django REST Framework
from rest_framework.fields import empty, SkipField
+import cachetools
+
# Tower
from awx.main.utils import encrypt_field, decrypt_field
from awx.conf import settings_registry
@@ -28,6 +30,8 @@ from awx.conf.migrations._reencrypt import decrypt_field as old_decrypt_field
logger = logging.getLogger('awx.conf.settings')
+SETTING_MEMORY_TTL = 5 if 'callback_receiver' in ' '.join(sys.argv) else 0
+
# Store a special value to indicate when a setting is not set in the database.
SETTING_CACHE_NOTSET = '___notset___'
@@ -406,6 +410,7 @@ class SettingsWrapper(UserSettingsHolder):
def SETTINGS_MODULE(self):
return self._get_default('SETTINGS_MODULE')
+ @cachetools.cached(cache=cachetools.TTLCache(maxsize=2048, ttl=SETTING_MEMORY_TTL))
def __getattr__(self, name):
value = empty
if name in self.all_supported_settings:
diff --git a/awx/locale/django.pot b/awx/locale/django.pot
index dfdd2e72ef..3d2cf41999 100644
--- a/awx/locale/django.pot
+++ b/awx/locale/django.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-05-16 02:52+0000\n"
+"POT-Creation-Date: 2020-10-05 19:43+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -27,35 +27,42 @@ msgid ""
"again."
msgstr ""
-#: awx/api/conf.py:17 awx/api/conf.py:26 awx/api/conf.py:34 awx/api/conf.py:50
-#: awx/api/conf.py:62 awx/api/conf.py:74 awx/sso/conf.py:97 awx/sso/conf.py:108
+#: awx/api/conf.py:17 awx/api/conf.py:27 awx/api/conf.py:35 awx/api/conf.py:51
+#: awx/api/conf.py:64 awx/api/conf.py:76 awx/sso/conf.py:97 awx/sso/conf.py:108
#: awx/sso/conf.py:120 awx/sso/conf.py:135
msgid "Authentication"
msgstr ""
-#: awx/api/conf.py:24
-msgid "Maximum number of simultaneous logged in sessions"
+#: awx/api/conf.py:19 awx/api/conf.py:53 awx/main/conf.py:256
+#: awx/main/conf.py:268 awx/main/conf.py:281 awx/main/conf.py:503
+#: awx/main/conf.py:516 awx/main/conf.py:529 awx/main/conf.py:544
+#: awx/main/conf.py:682 awx/main/conf.py:764 awx/sso/conf.py:518
+msgid "seconds"
msgstr ""
#: awx/api/conf.py:25
+msgid "Maximum number of simultaneous logged in sessions"
+msgstr ""
+
+#: awx/api/conf.py:26
msgid ""
"Maximum number of simultaneous logged in sessions a user may have. To "
"disable enter -1."
msgstr ""
-#: awx/api/conf.py:32
+#: awx/api/conf.py:33
msgid "Enable HTTP Basic Auth"
msgstr ""
-#: awx/api/conf.py:33
+#: awx/api/conf.py:34
msgid "Enable HTTP Basic Auth for the API Browser."
msgstr ""
-#: awx/api/conf.py:43
+#: awx/api/conf.py:44
msgid "OAuth 2 Timeout Settings"
msgstr ""
-#: awx/api/conf.py:44
+#: awx/api/conf.py:45
msgid ""
"Dictionary for customizing OAuth 2 timeouts, available items are "
"`ACCESS_TOKEN_EXPIRE_SECONDS`, the duration of access tokens in the number "
@@ -65,11 +72,11 @@ msgid ""
"expired access tokens, in the number of seconds."
msgstr ""
-#: awx/api/conf.py:57
+#: awx/api/conf.py:59
msgid "Allow External Users to Create OAuth2 Tokens"
msgstr ""
-#: awx/api/conf.py:58
+#: awx/api/conf.py:60
msgid ""
"For security reasons, users from external auth providers (LDAP, SAML, SSO, "
"Radius, and others) are not allowed to create OAuth2 tokens. To change this "
@@ -77,11 +84,11 @@ msgid ""
"setting is toggled off."
msgstr ""
-#: awx/api/conf.py:71
+#: awx/api/conf.py:73
msgid "Login redirect override URL"
msgstr ""
-#: awx/api/conf.py:72
+#: awx/api/conf.py:74
msgid ""
"URL to which unauthorized users will be redirected to log in. If blank, "
"users will be sent to the Tower login page."
@@ -126,27 +133,27 @@ msgstr ""
msgid "Invalid {field_name} id: {field_id}"
msgstr ""
-#: awx/api/filters.py:333
+#: awx/api/filters.py:338
msgid ""
"Cannot apply role_level filter to this list because its model does not use "
"roles for access control."
msgstr ""
-#: awx/api/generics.py:182
+#: awx/api/generics.py:183
msgid ""
"You did not use correct Content-Type in your HTTP request. If you are using "
"our REST API, the Content-Type must be application/json"
msgstr ""
-#: awx/api/generics.py:623 awx/api/generics.py:685
+#: awx/api/generics.py:647 awx/api/generics.py:709
msgid "\"id\" field must be an integer."
msgstr ""
-#: awx/api/generics.py:682
+#: awx/api/generics.py:706
msgid "\"id\" is required to disassociate"
msgstr ""
-#: awx/api/generics.py:733
+#: awx/api/generics.py:757
msgid "{} 'id' field is missing."
msgstr ""
@@ -248,1127 +255,1161 @@ msgid ""
"saved to the database."
msgstr ""
-#: awx/api/serializers.py:878
+#: awx/api/serializers.py:880
msgid "Write-only field used to change the password."
msgstr ""
-#: awx/api/serializers.py:880
+#: awx/api/serializers.py:882
msgid "Set if the account is managed by an external service"
msgstr ""
-#: awx/api/serializers.py:907
+#: awx/api/serializers.py:909
msgid "Password required for new User."
msgstr ""
-#: awx/api/serializers.py:992
+#: awx/api/serializers.py:994
#, python-format
msgid "Unable to change %s on user managed by LDAP."
msgstr ""
-#: awx/api/serializers.py:1088
+#: awx/api/serializers.py:1090
msgid "Must be a simple space-separated string with allowed scopes {}."
msgstr ""
-#: awx/api/serializers.py:1186
+#: awx/api/serializers.py:1188
msgid "Authorization Grant Type"
msgstr ""
-#: awx/api/serializers.py:1188 awx/main/credential_plugins/azure_kv.py:30
-#: awx/main/models/credential/__init__.py:964
+#: awx/api/serializers.py:1190 awx/main/credential_plugins/azure_kv.py:30
+#: awx/main/models/credential/__init__.py:972
msgid "Client Secret"
msgstr ""
-#: awx/api/serializers.py:1191
+#: awx/api/serializers.py:1193
msgid "Client Type"
msgstr ""
-#: awx/api/serializers.py:1194
+#: awx/api/serializers.py:1196
msgid "Redirect URIs"
msgstr ""
-#: awx/api/serializers.py:1197
+#: awx/api/serializers.py:1199
msgid "Skip Authorization"
msgstr ""
-#: awx/api/serializers.py:1303
+#: awx/api/serializers.py:1306
msgid "Cannot change max_hosts."
msgstr ""
-#: awx/api/serializers.py:1336
+#: awx/api/serializers.py:1339
msgid "This path is already being used by another manual project."
msgstr ""
-#: awx/api/serializers.py:1338
+#: awx/api/serializers.py:1341
+msgid "SCM branch cannot be used with archive projects."
+msgstr ""
+
+#: awx/api/serializers.py:1343
msgid "SCM refspec can only be used with git projects."
msgstr ""
-#: awx/api/serializers.py:1415
+#: awx/api/serializers.py:1420
msgid ""
"One or more job templates depend on branch override behavior for this "
"project (ids: {})."
msgstr ""
-#: awx/api/serializers.py:1422
+#: awx/api/serializers.py:1427
msgid "Update options must be set to false for manual projects."
msgstr ""
-#: awx/api/serializers.py:1428
+#: awx/api/serializers.py:1433
msgid "Array of playbooks available within this project."
msgstr ""
-#: awx/api/serializers.py:1447
+#: awx/api/serializers.py:1452
msgid ""
"Array of inventory files and directories available within this project, not "
"comprehensive."
msgstr ""
-#: awx/api/serializers.py:1495 awx/api/serializers.py:3034
-#: awx/api/serializers.py:3246
+#: awx/api/serializers.py:1500 awx/api/serializers.py:3089
+#: awx/api/serializers.py:3301
msgid "A count of hosts uniquely assigned to each status."
msgstr ""
-#: awx/api/serializers.py:1498 awx/api/serializers.py:3037
+#: awx/api/serializers.py:1503 awx/api/serializers.py:3092
msgid "A count of all plays and tasks for the job run."
msgstr ""
-#: awx/api/serializers.py:1625
+#: awx/api/serializers.py:1630
msgid "Smart inventories must specify host_filter"
msgstr ""
-#: awx/api/serializers.py:1713
+#: awx/api/serializers.py:1722
#, python-format
msgid "Invalid port specification: %s"
msgstr ""
-#: awx/api/serializers.py:1724
+#: awx/api/serializers.py:1733
msgid "Cannot create Host for Smart Inventory"
msgstr ""
-#: awx/api/serializers.py:1808
+#: awx/api/serializers.py:1751
+msgid "A Group with that name already exists."
+msgstr ""
+
+#: awx/api/serializers.py:1822
+msgid "A Host with that name already exists."
+msgstr ""
+
+#: awx/api/serializers.py:1827
msgid "Invalid group name."
msgstr ""
-#: awx/api/serializers.py:1813
+#: awx/api/serializers.py:1832
msgid "Cannot create Group for Smart Inventory"
msgstr ""
-#: awx/api/serializers.py:1888
+#: awx/api/serializers.py:1907
msgid ""
"Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python"
msgstr ""
-#: awx/api/serializers.py:1917
+#: awx/api/serializers.py:1936
msgid "Cloud credential to use for inventory updates."
msgstr ""
-#: awx/api/serializers.py:1938
+#: awx/api/serializers.py:1957
msgid "`{}` is a prohibited environment variable"
msgstr ""
-#: awx/api/serializers.py:1949
+#: awx/api/serializers.py:1968
msgid "If 'source' is 'custom', 'source_script' must be provided."
msgstr ""
-#: awx/api/serializers.py:1955
+#: awx/api/serializers.py:1974
msgid "Must provide an inventory."
msgstr ""
-#: awx/api/serializers.py:1959
+#: awx/api/serializers.py:1978
msgid ""
"The 'source_script' does not belong to the same organization as the "
"inventory."
msgstr ""
-#: awx/api/serializers.py:1961
+#: awx/api/serializers.py:1980
msgid "'source_script' doesn't exist."
msgstr ""
-#: awx/api/serializers.py:2063
+#: awx/api/serializers.py:2082
msgid "Cannot use manual project for SCM-based inventory."
msgstr ""
-#: awx/api/serializers.py:2068
+#: awx/api/serializers.py:2087
msgid "Setting not compatible with existing schedules."
msgstr ""
-#: awx/api/serializers.py:2073
+#: awx/api/serializers.py:2092
msgid "Cannot create Inventory Source for Smart Inventory"
msgstr ""
-#: awx/api/serializers.py:2121
+#: awx/api/serializers.py:2140
msgid "Project required for scm type sources."
msgstr ""
-#: awx/api/serializers.py:2130
+#: awx/api/serializers.py:2149
#, python-format
msgid "Cannot set %s if not SCM type."
msgstr ""
-#: awx/api/serializers.py:2200
+#: awx/api/serializers.py:2219
msgid "The project used for this job."
msgstr ""
-#: awx/api/serializers.py:2456
+#: awx/api/serializers.py:2475
msgid "Modifications not allowed for managed credential types"
msgstr ""
-#: awx/api/serializers.py:2468
+#: awx/api/serializers.py:2487
msgid ""
"Modifications to inputs are not allowed for credential types that are in use"
msgstr ""
-#: awx/api/serializers.py:2473
+#: awx/api/serializers.py:2492
#, python-format
msgid "Must be 'cloud' or 'net', not %s"
msgstr ""
-#: awx/api/serializers.py:2479
+#: awx/api/serializers.py:2498
msgid "'ask_at_runtime' is not supported for custom credentials."
msgstr ""
-#: awx/api/serializers.py:2527
+#: awx/api/serializers.py:2547
msgid "Credential Type"
msgstr ""
-#: awx/api/serializers.py:2608
+#: awx/api/serializers.py:2611
+msgid "Modifications not allowed for managed credentials"
+msgstr ""
+
+#: awx/api/serializers.py:2629 awx/api/serializers.py:2703
+msgid "Galaxy credentials must be owned by an Organization."
+msgstr ""
+
+#: awx/api/serializers.py:2646
msgid ""
"You cannot change the credential type of the credential, as it may break the "
"functionality of the resources using it."
msgstr ""
-#: awx/api/serializers.py:2620
+#: awx/api/serializers.py:2658
msgid ""
"Write-only field used to add user to owner role. If provided, do not give "
"either team or organization. Only valid for creation."
msgstr ""
-#: awx/api/serializers.py:2625
+#: awx/api/serializers.py:2663
msgid ""
"Write-only field used to add team to owner role. If provided, do not give "
"either user or organization. Only valid for creation."
msgstr ""
-#: awx/api/serializers.py:2630
+#: awx/api/serializers.py:2668
msgid ""
"Inherit permissions from organization roles. If provided on creation, do not "
"give either user or team."
msgstr ""
-#: awx/api/serializers.py:2646
+#: awx/api/serializers.py:2685
msgid "Missing 'user', 'team', or 'organization'."
msgstr ""
-#: awx/api/serializers.py:2663
+#: awx/api/serializers.py:2690
+msgid ""
+"Only one of 'user', 'team', or 'organization' should be provided, received "
+"{} fields."
+msgstr ""
+
+#: awx/api/serializers.py:2718
msgid ""
"Credential organization must be set and match before assigning to a team"
msgstr ""
-#: awx/api/serializers.py:2789
+#: awx/api/serializers.py:2844
msgid "This field is required."
msgstr ""
-#: awx/api/serializers.py:2798
+#: awx/api/serializers.py:2853
msgid "Playbook not found for project."
msgstr ""
-#: awx/api/serializers.py:2800
+#: awx/api/serializers.py:2855
msgid "Must select playbook for project."
msgstr ""
-#: awx/api/serializers.py:2802 awx/api/serializers.py:2804
+#: awx/api/serializers.py:2857 awx/api/serializers.py:2859
msgid "Project does not allow overriding branch."
msgstr ""
-#: awx/api/serializers.py:2841
+#: awx/api/serializers.py:2896
msgid "Must be a Personal Access Token."
msgstr ""
-#: awx/api/serializers.py:2844
+#: awx/api/serializers.py:2899
msgid "Must match the selected webhook service."
msgstr ""
-#: awx/api/serializers.py:2915
+#: awx/api/serializers.py:2970
msgid "Cannot enable provisioning callback without an inventory set."
msgstr ""
-#: awx/api/serializers.py:2918
+#: awx/api/serializers.py:2973
msgid "Must either set a default value or ask to prompt on launch."
msgstr ""
-#: awx/api/serializers.py:2920 awx/main/models/jobs.py:299
+#: awx/api/serializers.py:2975 awx/main/models/jobs.py:299
msgid "Job Templates must have a project assigned."
msgstr ""
-#: awx/api/serializers.py:3078
+#: awx/api/serializers.py:3133
msgid "No change to job limit"
msgstr ""
-#: awx/api/serializers.py:3079
+#: awx/api/serializers.py:3134
msgid "All failed and unreachable hosts"
msgstr ""
-#: awx/api/serializers.py:3094
+#: awx/api/serializers.py:3149
msgid "Missing passwords needed to start: {}"
msgstr ""
-#: awx/api/serializers.py:3113
+#: awx/api/serializers.py:3168
msgid "Relaunch by host status not available until job finishes running."
msgstr ""
-#: awx/api/serializers.py:3127
+#: awx/api/serializers.py:3182
msgid "Job Template Project is missing or undefined."
msgstr ""
-#: awx/api/serializers.py:3129
+#: awx/api/serializers.py:3184
msgid "Job Template Inventory is missing or undefined."
msgstr ""
-#: awx/api/serializers.py:3167
+#: awx/api/serializers.py:3222
msgid "Unknown, job may have been ran before launch configurations were saved."
msgstr ""
-#: awx/api/serializers.py:3238 awx/main/tasks.py:2799 awx/main/tasks.py:2817
+#: awx/api/serializers.py:3293 awx/main/tasks.py:2838 awx/main/tasks.py:2856
msgid "{} are prohibited from use in ad hoc commands."
msgstr ""
-#: awx/api/serializers.py:3326 awx/api/views/__init__.py:4169
+#: awx/api/serializers.py:3381 awx/api/views/__init__.py:4211
#, python-brace-format
msgid ""
"Standard Output too large to display ({text_size} bytes), only download "
"supported for sizes over {supported_size} bytes."
msgstr ""
-#: awx/api/serializers.py:3639
+#: awx/api/serializers.py:3694
msgid "Provided variable {} has no database value to replace with."
msgstr ""
-#: awx/api/serializers.py:3657
+#: awx/api/serializers.py:3712
msgid "\"$encrypted$ is a reserved keyword, may not be used for {}.\""
msgstr ""
-#: awx/api/serializers.py:4064
+#: awx/api/serializers.py:4119
msgid "A project is required to run a job."
msgstr ""
-#: awx/api/serializers.py:4066
+#: awx/api/serializers.py:4121
msgid "Missing a revision to run due to failed project update."
msgstr ""
-#: awx/api/serializers.py:4070
+#: awx/api/serializers.py:4125
msgid "The inventory associated with this Job Template is being deleted."
msgstr ""
-#: awx/api/serializers.py:4072 awx/api/serializers.py:4188
+#: awx/api/serializers.py:4127 awx/api/serializers.py:4247
msgid "The provided inventory is being deleted."
msgstr ""
-#: awx/api/serializers.py:4080
+#: awx/api/serializers.py:4135
msgid "Cannot assign multiple {} credentials."
msgstr ""
-#: awx/api/serializers.py:4084
+#: awx/api/serializers.py:4140
msgid "Cannot assign a Credential of kind `{}`"
msgstr ""
-#: awx/api/serializers.py:4097
+#: awx/api/serializers.py:4153
msgid ""
"Removing {} credential at launch time without replacement is not supported. "
"Provided list lacked credential(s): {}."
msgstr ""
-#: awx/api/serializers.py:4186
+#: awx/api/serializers.py:4245
msgid "The inventory associated with this Workflow is being deleted."
msgstr ""
-#: awx/api/serializers.py:4257
+#: awx/api/serializers.py:4316
msgid "Message type '{}' invalid, must be either 'message' or 'body'"
msgstr ""
-#: awx/api/serializers.py:4263
+#: awx/api/serializers.py:4322
msgid "Expected string for '{}', found {}, "
msgstr ""
-#: awx/api/serializers.py:4267
+#: awx/api/serializers.py:4326
msgid "Messages cannot contain newlines (found newline in {} event)"
msgstr ""
-#: awx/api/serializers.py:4273
+#: awx/api/serializers.py:4332
msgid "Expected dict for 'messages' field, found {}"
msgstr ""
-#: awx/api/serializers.py:4277
+#: awx/api/serializers.py:4336
msgid ""
"Event '{}' invalid, must be one of 'started', 'success', 'error', or "
"'workflow_approval'"
msgstr ""
-#: awx/api/serializers.py:4283
+#: awx/api/serializers.py:4342
msgid "Expected dict for event '{}', found {}"
msgstr ""
-#: awx/api/serializers.py:4288
+#: awx/api/serializers.py:4347
msgid ""
"Workflow Approval event '{}' invalid, must be one of 'running', 'approved', "
"'timed_out', or 'denied'"
msgstr ""
-#: awx/api/serializers.py:4295
+#: awx/api/serializers.py:4354
msgid "Expected dict for workflow approval event '{}', found {}"
msgstr ""
-#: awx/api/serializers.py:4322
+#: awx/api/serializers.py:4381
msgid "Unable to render message '{}': {}"
msgstr ""
-#: awx/api/serializers.py:4324
+#: awx/api/serializers.py:4383
msgid "Field '{}' unavailable"
msgstr ""
-#: awx/api/serializers.py:4326
+#: awx/api/serializers.py:4385
msgid "Security error due to field '{}'"
msgstr ""
-#: awx/api/serializers.py:4346
+#: awx/api/serializers.py:4405
msgid "Webhook body for '{}' should be a json dictionary. Found type '{}'."
msgstr ""
-#: awx/api/serializers.py:4349
+#: awx/api/serializers.py:4408
msgid "Webhook body for '{}' is not a valid json dictionary ({})."
msgstr ""
-#: awx/api/serializers.py:4367
+#: awx/api/serializers.py:4426
msgid ""
"Missing required fields for Notification Configuration: notification_type"
msgstr ""
-#: awx/api/serializers.py:4394
+#: awx/api/serializers.py:4453
msgid "No values specified for field '{}'"
msgstr ""
-#: awx/api/serializers.py:4399
+#: awx/api/serializers.py:4458
msgid "HTTP method must be either 'POST' or 'PUT'."
msgstr ""
-#: awx/api/serializers.py:4401
+#: awx/api/serializers.py:4460
msgid "Missing required fields for Notification Configuration: {}."
msgstr ""
-#: awx/api/serializers.py:4404
+#: awx/api/serializers.py:4463
msgid "Configuration field '{}' incorrect type, expected {}."
msgstr ""
-#: awx/api/serializers.py:4421
+#: awx/api/serializers.py:4480
msgid "Notification body"
msgstr ""
-#: awx/api/serializers.py:4501
+#: awx/api/serializers.py:4560
msgid ""
"Valid DTSTART required in rrule. Value should start with: DTSTART:"
"YYYYMMDDTHHMMSSZ"
msgstr ""
-#: awx/api/serializers.py:4503
+#: awx/api/serializers.py:4562
msgid ""
"DTSTART cannot be a naive datetime. Specify ;TZINFO= or YYYYMMDDTHHMMSSZZ."
msgstr ""
-#: awx/api/serializers.py:4505
+#: awx/api/serializers.py:4564
msgid "Multiple DTSTART is not supported."
msgstr ""
-#: awx/api/serializers.py:4507
+#: awx/api/serializers.py:4566
msgid "RRULE required in rrule."
msgstr ""
-#: awx/api/serializers.py:4509
+#: awx/api/serializers.py:4568
msgid "Multiple RRULE is not supported."
msgstr ""
-#: awx/api/serializers.py:4511
+#: awx/api/serializers.py:4570
msgid "INTERVAL required in rrule."
msgstr ""
-#: awx/api/serializers.py:4513
+#: awx/api/serializers.py:4572
msgid "SECONDLY is not supported."
msgstr ""
-#: awx/api/serializers.py:4515
+#: awx/api/serializers.py:4574
msgid "Multiple BYMONTHDAYs not supported."
msgstr ""
-#: awx/api/serializers.py:4517
+#: awx/api/serializers.py:4576
msgid "Multiple BYMONTHs not supported."
msgstr ""
-#: awx/api/serializers.py:4519
+#: awx/api/serializers.py:4578
msgid "BYDAY with numeric prefix not supported."
msgstr ""
-#: awx/api/serializers.py:4521
+#: awx/api/serializers.py:4580
msgid "BYYEARDAY not supported."
msgstr ""
-#: awx/api/serializers.py:4523
+#: awx/api/serializers.py:4582
msgid "BYWEEKNO not supported."
msgstr ""
-#: awx/api/serializers.py:4525
+#: awx/api/serializers.py:4584
msgid "RRULE may not contain both COUNT and UNTIL"
msgstr ""
-#: awx/api/serializers.py:4529
+#: awx/api/serializers.py:4588
msgid "COUNT > 999 is unsupported."
msgstr ""
-#: awx/api/serializers.py:4535
+#: awx/api/serializers.py:4594
msgid "rrule parsing failed validation: {}"
msgstr ""
-#: awx/api/serializers.py:4597
+#: awx/api/serializers.py:4656
msgid "Inventory Source must be a cloud resource."
msgstr ""
-#: awx/api/serializers.py:4599
+#: awx/api/serializers.py:4658
msgid "Manual Project cannot have a schedule set."
msgstr ""
-#: awx/api/serializers.py:4602
+#: awx/api/serializers.py:4661
msgid ""
"Inventory sources with `update_on_project_update` cannot be scheduled. "
"Schedule its source project `{}` instead."
msgstr ""
-#: awx/api/serializers.py:4612
+#: awx/api/serializers.py:4671
msgid ""
"Count of jobs in the running or waiting state that are targeted for this "
"instance"
msgstr ""
-#: awx/api/serializers.py:4617
+#: awx/api/serializers.py:4676
msgid "Count of all jobs that target this instance"
msgstr ""
-#: awx/api/serializers.py:4650
+#: awx/api/serializers.py:4711
msgid ""
"Count of jobs in the running or waiting state that are targeted for this "
"instance group"
msgstr ""
-#: awx/api/serializers.py:4655
+#: awx/api/serializers.py:4716
msgid "Count of all jobs that target this instance group"
msgstr ""
-#: awx/api/serializers.py:4660
+#: awx/api/serializers.py:4721
msgid "Indicates whether instance group controls any other group"
msgstr ""
-#: awx/api/serializers.py:4664
+#: awx/api/serializers.py:4725
msgid ""
"Indicates whether instances in this group are isolated.Isolated groups have "
"a designated controller group."
msgstr ""
-#: awx/api/serializers.py:4669
+#: awx/api/serializers.py:4730
msgid ""
"Indicates whether instances in this group are containerized.Containerized "
"groups have a designated Openshift or Kubernetes cluster."
msgstr ""
-#: awx/api/serializers.py:4677
+#: awx/api/serializers.py:4738
msgid "Policy Instance Percentage"
msgstr ""
-#: awx/api/serializers.py:4678
+#: awx/api/serializers.py:4739
msgid ""
"Minimum percentage of all instances that will be automatically assigned to "
"this group when new instances come online."
msgstr ""
-#: awx/api/serializers.py:4683
+#: awx/api/serializers.py:4744
msgid "Policy Instance Minimum"
msgstr ""
-#: awx/api/serializers.py:4684
+#: awx/api/serializers.py:4745
msgid ""
"Static minimum number of Instances that will be automatically assign to this "
"group when new instances come online."
msgstr ""
-#: awx/api/serializers.py:4689
+#: awx/api/serializers.py:4750
msgid "Policy Instance List"
msgstr ""
-#: awx/api/serializers.py:4690
+#: awx/api/serializers.py:4751
msgid "List of exact-match Instances that will be assigned to this group"
msgstr ""
-#: awx/api/serializers.py:4716
+#: awx/api/serializers.py:4777
msgid "Duplicate entry {}."
msgstr ""
-#: awx/api/serializers.py:4718
+#: awx/api/serializers.py:4779
msgid "{} is not a valid hostname of an existing instance."
msgstr ""
-#: awx/api/serializers.py:4720 awx/api/views/mixin.py:98
+#: awx/api/serializers.py:4781 awx/api/views/mixin.py:98
msgid ""
"Isolated instances may not be added or removed from instances groups via the "
"API."
msgstr ""
-#: awx/api/serializers.py:4722 awx/api/views/mixin.py:102
+#: awx/api/serializers.py:4783 awx/api/views/mixin.py:102
msgid "Isolated instance group membership may not be managed via the API."
msgstr ""
-#: awx/api/serializers.py:4724 awx/api/serializers.py:4729
-#: awx/api/serializers.py:4734
+#: awx/api/serializers.py:4785 awx/api/serializers.py:4790
+#: awx/api/serializers.py:4795
msgid "Containerized instances may not be managed via the API"
msgstr ""
-#: awx/api/serializers.py:4739
+#: awx/api/serializers.py:4800
msgid "tower instance group name may not be changed."
msgstr ""
-#: awx/api/serializers.py:4744
+#: awx/api/serializers.py:4805
msgid "Only Kubernetes credentials can be associated with an Instance Group"
msgstr ""
-#: awx/api/serializers.py:4783
+#: awx/api/serializers.py:4844
msgid ""
"When present, shows the field name of the role or relationship that changed."
msgstr ""
-#: awx/api/serializers.py:4785
+#: awx/api/serializers.py:4846
msgid ""
"When present, shows the model on which the role or relationship was defined."
msgstr ""
-#: awx/api/serializers.py:4818
+#: awx/api/serializers.py:4879
msgid ""
"A summary of the new and changed values when an object is created, updated, "
"or deleted"
msgstr ""
-#: awx/api/serializers.py:4820
+#: awx/api/serializers.py:4881
msgid ""
"For create, update, and delete events this is the object type that was "
"affected. For associate and disassociate events this is the object type "
"associated or disassociated with object2."
msgstr ""
-#: awx/api/serializers.py:4823
+#: awx/api/serializers.py:4884
msgid ""
"Unpopulated for create, update, and delete events. For associate and "
"disassociate events this is the object type that object1 is being associated "
"with."
msgstr ""
-#: awx/api/serializers.py:4826
+#: awx/api/serializers.py:4887
msgid "The action taken with respect to the given object(s)."
msgstr ""
-#: awx/api/views/__init__.py:181
+#: awx/api/views/__init__.py:185
+msgid "Not found."
+msgstr ""
+
+#: awx/api/views/__init__.py:193
msgid "Dashboard"
msgstr ""
-#: awx/api/views/__init__.py:271
+#: awx/api/views/__init__.py:290
msgid "Dashboard Jobs Graphs"
msgstr ""
-#: awx/api/views/__init__.py:307
+#: awx/api/views/__init__.py:326
#, python-format
msgid "Unknown period \"%s\""
msgstr ""
-#: awx/api/views/__init__.py:321
+#: awx/api/views/__init__.py:340
msgid "Instances"
msgstr ""
-#: awx/api/views/__init__.py:329
+#: awx/api/views/__init__.py:348
msgid "Instance Detail"
msgstr ""
-#: awx/api/views/__init__.py:346
+#: awx/api/views/__init__.py:365
msgid "Instance Jobs"
msgstr ""
-#: awx/api/views/__init__.py:360
+#: awx/api/views/__init__.py:379
msgid "Instance's Instance Groups"
msgstr ""
-#: awx/api/views/__init__.py:369
+#: awx/api/views/__init__.py:388
msgid "Instance Groups"
msgstr ""
-#: awx/api/views/__init__.py:377
+#: awx/api/views/__init__.py:396
msgid "Instance Group Detail"
msgstr ""
-#: awx/api/views/__init__.py:392
+#: awx/api/views/__init__.py:411
msgid "Isolated Groups can not be removed from the API"
msgstr ""
-#: awx/api/views/__init__.py:394
+#: awx/api/views/__init__.py:413
msgid ""
"Instance Groups acting as a controller for an Isolated Group can not be "
"removed from the API"
msgstr ""
-#: awx/api/views/__init__.py:400
+#: awx/api/views/__init__.py:419
msgid "Instance Group Running Jobs"
msgstr ""
-#: awx/api/views/__init__.py:409
+#: awx/api/views/__init__.py:428
msgid "Instance Group's Instances"
msgstr ""
-#: awx/api/views/__init__.py:419
+#: awx/api/views/__init__.py:438
msgid "Schedules"
msgstr ""
-#: awx/api/views/__init__.py:433
+#: awx/api/views/__init__.py:452
msgid "Schedule Recurrence Rule Preview"
msgstr ""
-#: awx/api/views/__init__.py:480
+#: awx/api/views/__init__.py:499
msgid "Cannot assign credential when related template is null."
msgstr ""
-#: awx/api/views/__init__.py:485
+#: awx/api/views/__init__.py:504
msgid "Related template cannot accept {} on launch."
msgstr ""
-#: awx/api/views/__init__.py:487
+#: awx/api/views/__init__.py:506
msgid ""
"Credential that requires user input on launch cannot be used in saved launch "
"configuration."
msgstr ""
-#: awx/api/views/__init__.py:493
+#: awx/api/views/__init__.py:512
msgid "Related template is not configured to accept credentials on launch."
msgstr ""
-#: awx/api/views/__init__.py:495
+#: awx/api/views/__init__.py:514
#, python-brace-format
msgid ""
"This launch configuration already provides a {credential_type} credential."
msgstr ""
-#: awx/api/views/__init__.py:498
+#: awx/api/views/__init__.py:517
#, python-brace-format
msgid "Related template already uses {credential_type} credential."
msgstr ""
-#: awx/api/views/__init__.py:516
+#: awx/api/views/__init__.py:535
msgid "Schedule Jobs List"
msgstr ""
-#: awx/api/views/__init__.py:600 awx/api/views/__init__.py:4378
+#: awx/api/views/__init__.py:619 awx/api/views/__init__.py:4420
msgid ""
"You cannot assign an Organization participation role as a child role for a "
"Team."
msgstr ""
-#: awx/api/views/__init__.py:604 awx/api/views/__init__.py:4392
+#: awx/api/views/__init__.py:623 awx/api/views/__init__.py:4434
msgid "You cannot grant system-level permissions to a team."
msgstr ""
-#: awx/api/views/__init__.py:611 awx/api/views/__init__.py:4384
+#: awx/api/views/__init__.py:630 awx/api/views/__init__.py:4426
msgid ""
"You cannot grant credential access to a team when the Organization field "
"isn't set, or belongs to a different organization"
msgstr ""
-#: awx/api/views/__init__.py:713
+#: awx/api/views/__init__.py:732
msgid "Project Schedules"
msgstr ""
-#: awx/api/views/__init__.py:724
+#: awx/api/views/__init__.py:743
msgid "Project SCM Inventory Sources"
msgstr ""
-#: awx/api/views/__init__.py:825
+#: awx/api/views/__init__.py:844
msgid "Project Update Events List"
msgstr ""
-#: awx/api/views/__init__.py:839
+#: awx/api/views/__init__.py:858
msgid "System Job Events List"
msgstr ""
-#: awx/api/views/__init__.py:873
+#: awx/api/views/__init__.py:892
msgid "Project Update SCM Inventory Updates"
msgstr ""
-#: awx/api/views/__init__.py:918
+#: awx/api/views/__init__.py:937
msgid "Me"
msgstr ""
-#: awx/api/views/__init__.py:927
+#: awx/api/views/__init__.py:946
msgid "OAuth 2 Applications"
msgstr ""
-#: awx/api/views/__init__.py:936
+#: awx/api/views/__init__.py:955
msgid "OAuth 2 Application Detail"
msgstr ""
-#: awx/api/views/__init__.py:949
+#: awx/api/views/__init__.py:968
msgid "OAuth 2 Application Tokens"
msgstr ""
-#: awx/api/views/__init__.py:971
+#: awx/api/views/__init__.py:990
msgid "OAuth2 Tokens"
msgstr ""
-#: awx/api/views/__init__.py:980
+#: awx/api/views/__init__.py:999
msgid "OAuth2 User Tokens"
msgstr ""
-#: awx/api/views/__init__.py:992
+#: awx/api/views/__init__.py:1011
msgid "OAuth2 User Authorized Access Tokens"
msgstr ""
-#: awx/api/views/__init__.py:1007
+#: awx/api/views/__init__.py:1026
msgid "Organization OAuth2 Applications"
msgstr ""
-#: awx/api/views/__init__.py:1019
+#: awx/api/views/__init__.py:1038
msgid "OAuth2 Personal Access Tokens"
msgstr ""
-#: awx/api/views/__init__.py:1034
+#: awx/api/views/__init__.py:1053
msgid "OAuth Token Detail"
msgstr ""
-#: awx/api/views/__init__.py:1096 awx/api/views/__init__.py:4345
+#: awx/api/views/__init__.py:1115 awx/api/views/__init__.py:4387
msgid ""
"You cannot grant credential access to a user not in the credentials' "
"organization"
msgstr ""
-#: awx/api/views/__init__.py:1100 awx/api/views/__init__.py:4349
+#: awx/api/views/__init__.py:1119 awx/api/views/__init__.py:4391
msgid "You cannot grant private credential access to another user"
msgstr ""
-#: awx/api/views/__init__.py:1198
+#: awx/api/views/__init__.py:1217
#, python-format
msgid "Cannot change %s."
msgstr ""
-#: awx/api/views/__init__.py:1204
+#: awx/api/views/__init__.py:1223
msgid "Cannot delete user."
msgstr ""
-#: awx/api/views/__init__.py:1228
+#: awx/api/views/__init__.py:1247
msgid "Deletion not allowed for managed credential types"
msgstr ""
-#: awx/api/views/__init__.py:1230
+#: awx/api/views/__init__.py:1249
msgid "Credential types that are in use cannot be deleted"
msgstr ""
-#: awx/api/views/__init__.py:1381
+#: awx/api/views/__init__.py:1362
+msgid "Deletion not allowed for managed credentials"
+msgstr ""
+
+#: awx/api/views/__init__.py:1407
msgid "External Credential Test"
msgstr ""
-#: awx/api/views/__init__.py:1408
+#: awx/api/views/__init__.py:1442
msgid "Credential Input Source Detail"
msgstr ""
-#: awx/api/views/__init__.py:1416 awx/api/views/__init__.py:1424
+#: awx/api/views/__init__.py:1450 awx/api/views/__init__.py:1458
msgid "Credential Input Sources"
msgstr ""
-#: awx/api/views/__init__.py:1439
+#: awx/api/views/__init__.py:1473
msgid "External Credential Type Test"
msgstr ""
-#: awx/api/views/__init__.py:1497
+#: awx/api/views/__init__.py:1539
msgid "The inventory for this host is already being deleted."
msgstr ""
-#: awx/api/views/__init__.py:1614
+#: awx/api/views/__init__.py:1656
msgid "SSLError while trying to connect to {}"
msgstr ""
-#: awx/api/views/__init__.py:1616
+#: awx/api/views/__init__.py:1658
msgid "Request to {} timed out."
msgstr ""
-#: awx/api/views/__init__.py:1618
+#: awx/api/views/__init__.py:1660
msgid "Unknown exception {} while trying to GET {}"
msgstr ""
-#: awx/api/views/__init__.py:1622
+#: awx/api/views/__init__.py:1664
msgid ""
"Unauthorized access. Please check your Insights Credential username and "
"password."
msgstr ""
-#: awx/api/views/__init__.py:1626
+#: awx/api/views/__init__.py:1668
msgid ""
"Failed to access the Insights API at URL {}. Server responded with {} status "
"code and message {}"
msgstr ""
-#: awx/api/views/__init__.py:1635
+#: awx/api/views/__init__.py:1677
msgid "Expected JSON response from Insights at URL {} but instead got {}"
msgstr ""
-#: awx/api/views/__init__.py:1653
+#: awx/api/views/__init__.py:1695
msgid "Could not translate Insights system ID {} into an Insights platform ID."
msgstr ""
-#: awx/api/views/__init__.py:1695
+#: awx/api/views/__init__.py:1737
msgid "This host is not recognized as an Insights host."
msgstr ""
-#: awx/api/views/__init__.py:1703
+#: awx/api/views/__init__.py:1745
msgid "The Insights Credential for \"{}\" was not found."
msgstr ""
-#: awx/api/views/__init__.py:1782
+#: awx/api/views/__init__.py:1824
msgid "Cyclical Group association."
msgstr ""
-#: awx/api/views/__init__.py:1948
+#: awx/api/views/__init__.py:1990
msgid "Inventory subset argument must be a string."
msgstr ""
-#: awx/api/views/__init__.py:1952
+#: awx/api/views/__init__.py:1994
msgid "Subset does not use any supported syntax."
msgstr ""
-#: awx/api/views/__init__.py:2002
+#: awx/api/views/__init__.py:2044
msgid "Inventory Source List"
msgstr ""
-#: awx/api/views/__init__.py:2014
+#: awx/api/views/__init__.py:2056
msgid "Inventory Sources Update"
msgstr ""
-#: awx/api/views/__init__.py:2047
+#: awx/api/views/__init__.py:2089
msgid "Could not start because `can_update` returned False"
msgstr ""
-#: awx/api/views/__init__.py:2055
+#: awx/api/views/__init__.py:2097
msgid "No inventory sources to update."
msgstr ""
-#: awx/api/views/__init__.py:2077
+#: awx/api/views/__init__.py:2119
msgid "Inventory Source Schedules"
msgstr ""
-#: awx/api/views/__init__.py:2104
+#: awx/api/views/__init__.py:2146
msgid "Notification Templates can only be assigned when source is one of {}."
msgstr ""
-#: awx/api/views/__init__.py:2202
+#: awx/api/views/__init__.py:2244
msgid "Source already has credential assigned."
msgstr ""
-#: awx/api/views/__init__.py:2418
+#: awx/api/views/__init__.py:2460
msgid "Job Template Schedules"
msgstr ""
-#: awx/api/views/__init__.py:2467
+#: awx/api/views/__init__.py:2509
msgid "Field '{}' is missing from survey spec."
msgstr ""
-#: awx/api/views/__init__.py:2469
+#: awx/api/views/__init__.py:2511
msgid "Expected {} for field '{}', received {} type."
msgstr ""
-#: awx/api/views/__init__.py:2473
+#: awx/api/views/__init__.py:2515
msgid "'spec' doesn't contain any items."
msgstr ""
-#: awx/api/views/__init__.py:2487
+#: awx/api/views/__init__.py:2529
#, python-format
msgid "Survey question %s is not a json object."
msgstr ""
-#: awx/api/views/__init__.py:2490
+#: awx/api/views/__init__.py:2532
#, python-brace-format
msgid "'{field_name}' missing from survey question {idx}"
msgstr ""
-#: awx/api/views/__init__.py:2500
+#: awx/api/views/__init__.py:2542
#, python-brace-format
msgid "'{field_name}' in survey question {idx} expected to be {type_label}."
msgstr ""
-#: awx/api/views/__init__.py:2504
+#: awx/api/views/__init__.py:2546
#, python-format
msgid "'variable' '%(item)s' duplicated in survey question %(survey)s."
msgstr ""
-#: awx/api/views/__init__.py:2514
+#: awx/api/views/__init__.py:2556
#, python-brace-format
msgid ""
"'{survey_item[type]}' in survey question {idx} is not one of "
"'{allowed_types}' allowed question types."
msgstr ""
-#: awx/api/views/__init__.py:2524
+#: awx/api/views/__init__.py:2566
#, python-brace-format
msgid ""
"Default value {survey_item[default]} in survey question {idx} expected to be "
"{type_label}."
msgstr ""
-#: awx/api/views/__init__.py:2534
+#: awx/api/views/__init__.py:2576
#, python-brace-format
msgid "The {min_or_max} limit in survey question {idx} expected to be integer."
msgstr ""
-#: awx/api/views/__init__.py:2544
+#: awx/api/views/__init__.py:2586
#, python-brace-format
msgid "Survey question {idx} of type {survey_item[type]} must specify choices."
msgstr ""
-#: awx/api/views/__init__.py:2558
+#: awx/api/views/__init__.py:2600
msgid "Multiple Choice (Single Select) can only have one default value."
msgstr ""
-#: awx/api/views/__init__.py:2562
+#: awx/api/views/__init__.py:2604
msgid "Default choice must be answered from the choices listed."
msgstr ""
-#: awx/api/views/__init__.py:2571
+#: awx/api/views/__init__.py:2613
#, python-brace-format
msgid ""
"$encrypted$ is a reserved keyword for password question defaults, survey "
"question {idx} is type {survey_item[type]}."
msgstr ""
-#: awx/api/views/__init__.py:2585
+#: awx/api/views/__init__.py:2627
#, python-brace-format
msgid ""
"$encrypted$ is a reserved keyword, may not be used for new default in "
"position {idx}."
msgstr ""
-#: awx/api/views/__init__.py:2657
+#: awx/api/views/__init__.py:2699
#, python-brace-format
msgid "Cannot assign multiple {credential_type} credentials."
msgstr ""
-#: awx/api/views/__init__.py:2661
+#: awx/api/views/__init__.py:2703
msgid "Cannot assign a Credential of kind `{}`."
msgstr ""
-#: awx/api/views/__init__.py:2684
+#: awx/api/views/__init__.py:2726
msgid "Maximum number of labels for {} reached."
msgstr ""
-#: awx/api/views/__init__.py:2807
+#: awx/api/views/__init__.py:2849
msgid "No matching host could be found!"
msgstr ""
-#: awx/api/views/__init__.py:2810
+#: awx/api/views/__init__.py:2852
msgid "Multiple hosts matched the request!"
msgstr ""
-#: awx/api/views/__init__.py:2815
+#: awx/api/views/__init__.py:2857
msgid "Cannot start automatically, user input required!"
msgstr ""
-#: awx/api/views/__init__.py:2823
+#: awx/api/views/__init__.py:2865
msgid "Host callback job already pending."
msgstr ""
-#: awx/api/views/__init__.py:2839 awx/api/views/__init__.py:3590
+#: awx/api/views/__init__.py:2881 awx/api/views/__init__.py:3632
msgid "Error starting job!"
msgstr ""
-#: awx/api/views/__init__.py:2963 awx/api/views/__init__.py:2983
+#: awx/api/views/__init__.py:3005 awx/api/views/__init__.py:3025
msgid "Cycle detected."
msgstr ""
-#: awx/api/views/__init__.py:2975
+#: awx/api/views/__init__.py:3017
msgid "Relationship not allowed."
msgstr ""
-#: awx/api/views/__init__.py:3204
+#: awx/api/views/__init__.py:3246
msgid "Cannot relaunch slice workflow job orphaned from job template."
msgstr ""
-#: awx/api/views/__init__.py:3206
+#: awx/api/views/__init__.py:3248
msgid "Cannot relaunch sliced workflow job after slice count has changed."
msgstr ""
-#: awx/api/views/__init__.py:3239
+#: awx/api/views/__init__.py:3281
msgid "Workflow Job Template Schedules"
msgstr ""
-#: awx/api/views/__init__.py:3382 awx/api/views/__init__.py:4013
+#: awx/api/views/__init__.py:3424 awx/api/views/__init__.py:4055
msgid "Superuser privileges needed."
msgstr ""
-#: awx/api/views/__init__.py:3415
+#: awx/api/views/__init__.py:3457
msgid "System Job Template Schedules"
msgstr ""
-#: awx/api/views/__init__.py:3573
+#: awx/api/views/__init__.py:3615
#, python-brace-format
msgid "Wait until job finishes before retrying on {status_value} hosts."
msgstr ""
-#: awx/api/views/__init__.py:3578
+#: awx/api/views/__init__.py:3620
#, python-brace-format
msgid "Cannot retry on {status_value} hosts, playbook stats not available."
msgstr ""
-#: awx/api/views/__init__.py:3583
+#: awx/api/views/__init__.py:3625
#, python-brace-format
msgid "Cannot relaunch because previous job had 0 {status_value} hosts."
msgstr ""
-#: awx/api/views/__init__.py:3612
+#: awx/api/views/__init__.py:3654
msgid "Cannot create schedule because job requires credential passwords."
msgstr ""
-#: awx/api/views/__init__.py:3617
+#: awx/api/views/__init__.py:3659
msgid "Cannot create schedule because job was launched by legacy method."
msgstr ""
-#: awx/api/views/__init__.py:3619
+#: awx/api/views/__init__.py:3661
msgid "Cannot create schedule because a related resource is missing."
msgstr ""
-#: awx/api/views/__init__.py:3674
+#: awx/api/views/__init__.py:3716
msgid "Job Host Summaries List"
msgstr ""
-#: awx/api/views/__init__.py:3728
+#: awx/api/views/__init__.py:3770
msgid "Job Event Children List"
msgstr ""
-#: awx/api/views/__init__.py:3744
+#: awx/api/views/__init__.py:3786
msgid "Job Event Hosts List"
msgstr ""
-#: awx/api/views/__init__.py:3759
+#: awx/api/views/__init__.py:3801
msgid "Job Events List"
msgstr ""
-#: awx/api/views/__init__.py:3970
+#: awx/api/views/__init__.py:4012
msgid "Ad Hoc Command Events List"
msgstr ""
-#: awx/api/views/__init__.py:4215
+#: awx/api/views/__init__.py:4257
msgid "Delete not allowed while there are pending notifications"
msgstr ""
-#: awx/api/views/__init__.py:4223
+#: awx/api/views/__init__.py:4265
msgid "Notification Template Test"
msgstr ""
-#: awx/api/views/__init__.py:4483 awx/api/views/__init__.py:4498
+#: awx/api/views/__init__.py:4525 awx/api/views/__init__.py:4540
msgid "User does not have permission to approve or deny this workflow."
msgstr ""
-#: awx/api/views/__init__.py:4485 awx/api/views/__init__.py:4500
+#: awx/api/views/__init__.py:4527 awx/api/views/__init__.py:4542
msgid "This workflow step has already been approved or denied."
msgstr ""
@@ -1380,7 +1421,11 @@ msgstr ""
msgid "Cannot delete inventory script."
msgstr ""
-#: awx/api/views/inventory.py:149
+#: awx/api/views/inventory.py:137
+msgid "You cannot turn a regular inventory into a \"smart\" inventory."
+msgstr ""
+
+#: awx/api/views/inventory.py:150
#, python-brace-format
msgid "{0}"
msgstr ""
@@ -1405,71 +1450,76 @@ msgstr ""
msgid "Related job {} is still processing events."
msgstr ""
-#: awx/api/views/root.py:49 awx/templates/rest_framework/api.html:28
+#: awx/api/views/organization.py:230
+#, python-brace-format
+msgid "Credential must be a Galaxy credential, not {sub.credential_type.name}."
+msgstr ""
+
+#: awx/api/views/root.py:50 awx/templates/rest_framework/api.html:28
msgid "REST API"
msgstr ""
-#: awx/api/views/root.py:59 awx/templates/rest_framework/api.html:4
+#: awx/api/views/root.py:60 awx/templates/rest_framework/api.html:4
msgid "AWX REST API"
msgstr ""
-#: awx/api/views/root.py:72
+#: awx/api/views/root.py:73
msgid "API OAuth 2 Authorization Root"
msgstr ""
-#: awx/api/views/root.py:139
+#: awx/api/views/root.py:140
msgid "Version 2"
msgstr ""
-#: awx/api/views/root.py:148
+#: awx/api/views/root.py:149
msgid "Ping"
msgstr ""
-#: awx/api/views/root.py:180 awx/api/views/root.py:225 awx/conf/apps.py:10
+#: awx/api/views/root.py:181 awx/api/views/root.py:226 awx/conf/apps.py:10
msgid "Configuration"
msgstr ""
-#: awx/api/views/root.py:202 awx/api/views/root.py:308
+#: awx/api/views/root.py:203 awx/api/views/root.py:310
msgid "Invalid License"
msgstr ""
-#: awx/api/views/root.py:207
+#: awx/api/views/root.py:208
msgid "The provided credentials are invalid (HTTP 401)."
msgstr ""
-#: awx/api/views/root.py:209
+#: awx/api/views/root.py:210
msgid "Unable to connect to proxy server."
msgstr ""
-#: awx/api/views/root.py:211
+#: awx/api/views/root.py:212
msgid "Could not connect to subscription service."
msgstr ""
-#: awx/api/views/root.py:284
+#: awx/api/views/root.py:286
msgid "Invalid license data"
msgstr ""
-#: awx/api/views/root.py:286
+#: awx/api/views/root.py:288
msgid "Missing 'eula_accepted' property"
msgstr ""
-#: awx/api/views/root.py:290
+#: awx/api/views/root.py:292
msgid "'eula_accepted' value is invalid"
msgstr ""
-#: awx/api/views/root.py:293
+#: awx/api/views/root.py:295
msgid "'eula_accepted' must be True"
msgstr ""
-#: awx/api/views/root.py:300
+#: awx/api/views/root.py:302
msgid "Invalid JSON"
msgstr ""
-#: awx/api/views/root.py:319
+#: awx/api/views/root.py:321
msgid "Invalid license"
msgstr ""
-#: awx/api/views/root.py:327
+#: awx/api/views/root.py:329
msgid "Failed to remove license."
msgstr ""
@@ -1660,11 +1710,11 @@ msgstr ""
msgid "Expected a list of tuples of max length 2 but got {input_type} instead."
msgstr ""
-#: awx/conf/registry.py:73 awx/conf/tests/unit/test_registry.py:155
+#: awx/conf/registry.py:73 awx/conf/tests/unit/test_registry.py:156
msgid "All"
msgstr ""
-#: awx/conf/registry.py:74 awx/conf/tests/unit/test_registry.py:156
+#: awx/conf/registry.py:74 awx/conf/tests/unit/test_registry.py:157
msgid "Changed"
msgstr ""
@@ -1672,59 +1722,57 @@ msgstr ""
msgid "User-Defaults"
msgstr ""
-#: awx/conf/registry.py:143
+#: awx/conf/registry.py:145
msgid "This value has been set manually in a settings file."
msgstr ""
-#: awx/conf/tests/unit/test_registry.py:46
-#: awx/conf/tests/unit/test_registry.py:56
-#: awx/conf/tests/unit/test_registry.py:72
-#: awx/conf/tests/unit/test_registry.py:87
-#: awx/conf/tests/unit/test_registry.py:100
-#: awx/conf/tests/unit/test_registry.py:106
-#: awx/conf/tests/unit/test_registry.py:126
-#: awx/conf/tests/unit/test_registry.py:132
-#: awx/conf/tests/unit/test_registry.py:145
-#: awx/conf/tests/unit/test_registry.py:157
-#: awx/conf/tests/unit/test_registry.py:166
-#: awx/conf/tests/unit/test_registry.py:172
-#: awx/conf/tests/unit/test_registry.py:184
-#: awx/conf/tests/unit/test_registry.py:191
-#: awx/conf/tests/unit/test_registry.py:233
-#: awx/conf/tests/unit/test_registry.py:251
-#: awx/conf/tests/unit/test_settings.py:79
-#: awx/conf/tests/unit/test_settings.py:97
-#: awx/conf/tests/unit/test_settings.py:112
-#: awx/conf/tests/unit/test_settings.py:127
-#: awx/conf/tests/unit/test_settings.py:143
-#: awx/conf/tests/unit/test_settings.py:156
-#: awx/conf/tests/unit/test_settings.py:173
-#: awx/conf/tests/unit/test_settings.py:189
-#: awx/conf/tests/unit/test_settings.py:200
-#: awx/conf/tests/unit/test_settings.py:216
-#: awx/conf/tests/unit/test_settings.py:237
-#: awx/conf/tests/unit/test_settings.py:259
-#: awx/conf/tests/unit/test_settings.py:285
-#: awx/conf/tests/unit/test_settings.py:299
-#: awx/conf/tests/unit/test_settings.py:323
+#: awx/conf/tests/unit/test_registry.py:47
+#: awx/conf/tests/unit/test_registry.py:57
+#: awx/conf/tests/unit/test_registry.py:73
+#: awx/conf/tests/unit/test_registry.py:88
+#: awx/conf/tests/unit/test_registry.py:101
+#: awx/conf/tests/unit/test_registry.py:107
+#: awx/conf/tests/unit/test_registry.py:127
+#: awx/conf/tests/unit/test_registry.py:133
+#: awx/conf/tests/unit/test_registry.py:146
+#: awx/conf/tests/unit/test_registry.py:158
+#: awx/conf/tests/unit/test_registry.py:167
+#: awx/conf/tests/unit/test_registry.py:173
+#: awx/conf/tests/unit/test_registry.py:185
+#: awx/conf/tests/unit/test_registry.py:192
+#: awx/conf/tests/unit/test_registry.py:234
+#: awx/conf/tests/unit/test_registry.py:252
+#: awx/conf/tests/unit/test_settings.py:73
+#: awx/conf/tests/unit/test_settings.py:91
+#: awx/conf/tests/unit/test_settings.py:106
+#: awx/conf/tests/unit/test_settings.py:121
+#: awx/conf/tests/unit/test_settings.py:137
+#: awx/conf/tests/unit/test_settings.py:150
+#: awx/conf/tests/unit/test_settings.py:167
+#: awx/conf/tests/unit/test_settings.py:183
+#: awx/conf/tests/unit/test_settings.py:194
+#: awx/conf/tests/unit/test_settings.py:210
+#: awx/conf/tests/unit/test_settings.py:231
+#: awx/conf/tests/unit/test_settings.py:254
+#: awx/conf/tests/unit/test_settings.py:268
+#: awx/conf/tests/unit/test_settings.py:292
+#: awx/conf/tests/unit/test_settings.py:312
+#: awx/conf/tests/unit/test_settings.py:329
#: awx/conf/tests/unit/test_settings.py:343
-#: awx/conf/tests/unit/test_settings.py:360
-#: awx/conf/tests/unit/test_settings.py:374
-#: awx/conf/tests/unit/test_settings.py:398
-#: awx/conf/tests/unit/test_settings.py:411
-#: awx/conf/tests/unit/test_settings.py:430
-#: awx/conf/tests/unit/test_settings.py:466 awx/main/conf.py:24
-#: awx/main/conf.py:33 awx/main/conf.py:43 awx/main/conf.py:53
-#: awx/main/conf.py:65 awx/main/conf.py:78 awx/main/conf.py:91
-#: awx/main/conf.py:116 awx/main/conf.py:129 awx/main/conf.py:142
-#: awx/main/conf.py:154 awx/main/conf.py:162 awx/main/conf.py:173
-#: awx/main/conf.py:405 awx/main/conf.py:830 awx/main/conf.py:840
-#: awx/main/conf.py:852
+#: awx/conf/tests/unit/test_settings.py:367
+#: awx/conf/tests/unit/test_settings.py:380
+#: awx/conf/tests/unit/test_settings.py:399
+#: awx/conf/tests/unit/test_settings.py:435 awx/main/conf.py:23
+#: awx/main/conf.py:32 awx/main/conf.py:42 awx/main/conf.py:52
+#: awx/main/conf.py:64 awx/main/conf.py:77 awx/main/conf.py:90
+#: awx/main/conf.py:115 awx/main/conf.py:128 awx/main/conf.py:141
+#: awx/main/conf.py:153 awx/main/conf.py:161 awx/main/conf.py:172
+#: awx/main/conf.py:395 awx/main/conf.py:750 awx/main/conf.py:762
msgid "System"
msgstr ""
-#: awx/conf/tests/unit/test_registry.py:151
-#: awx/conf/tests/unit/test_registry.py:158
+#: awx/conf/tests/unit/test_registry.py:152
+#: awx/conf/tests/unit/test_registry.py:159
msgid "OtherSystem"
msgstr ""
@@ -1791,112 +1839,172 @@ msgstr ""
msgid "Unable to change inventory on a group."
msgstr ""
-#: awx/main/access.py:1264
+#: awx/main/access.py:1261
msgid "Unable to change organization on a team."
msgstr ""
-#: awx/main/access.py:1280
+#: awx/main/access.py:1277
msgid "The {} role cannot be assigned to a team"
msgstr ""
-#: awx/main/access.py:1474
+#: awx/main/access.py:1471
msgid "Insufficient access to Job Template credentials."
msgstr ""
-#: awx/main/access.py:1639 awx/main/access.py:2063
+#: awx/main/access.py:1635 awx/main/access.py:2059
msgid "Job was launched with secret prompts provided by another user."
msgstr ""
-#: awx/main/access.py:1648
+#: awx/main/access.py:1644
msgid "Job has been orphaned from its job template and organization."
msgstr ""
-#: awx/main/access.py:1650
+#: awx/main/access.py:1646
msgid "Job was launched with prompted fields you do not have access to."
msgstr ""
-#: awx/main/access.py:1652
+#: awx/main/access.py:1648
msgid ""
"Job was launched with unknown prompted fields. Organization admin "
"permissions required."
msgstr ""
-#: awx/main/access.py:2053
+#: awx/main/access.py:2049
msgid "Workflow Job was launched with unknown prompts."
msgstr ""
-#: awx/main/access.py:2065
+#: awx/main/access.py:2061
msgid "Job was launched with prompts you lack access to."
msgstr ""
-#: awx/main/access.py:2067
+#: awx/main/access.py:2063
msgid "Job was launched with prompts no longer accepted."
msgstr ""
-#: awx/main/access.py:2079
+#: awx/main/access.py:2075
msgid ""
"You do not have permission to the workflow job resources required for "
"relaunch."
msgstr ""
+#: awx/main/analytics/collectors.py:36
+msgid "General platform configuration."
+msgstr ""
+
+#: awx/main/analytics/collectors.py:68
+msgid "Counts of objects such as organizations, inventories, and projects"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:103
+msgid "Counts of users and teams by organization"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:115
+msgid "Counts of credentials by credential type"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:127
+msgid "Inventories, their inventory sources, and host counts"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:152
+msgid "Counts of projects by source control type"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:171
+msgid "Cluster topology and capacity"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:197
+msgid "Counts of jobs by status"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:207
+msgid "Counts of jobs by execution node"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:222
+msgid "Metadata about the analytics collected"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:285
+msgid "Automation task records"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:314
+msgid "Data on jobs run"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:351
+msgid "Data on job templates"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:374
+msgid "Data on workflow runs"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:410
+msgid "Data on workflows"
+msgstr ""
+
#: awx/main/apps.py:8
msgid "Main"
msgstr ""
-#: awx/main/conf.py:22
+#: awx/main/conf.py:21
msgid "Enable Activity Stream"
msgstr ""
-#: awx/main/conf.py:23
+#: awx/main/conf.py:22
msgid "Enable capturing activity for the activity stream."
msgstr ""
-#: awx/main/conf.py:31
+#: awx/main/conf.py:30
msgid "Enable Activity Stream for Inventory Sync"
msgstr ""
-#: awx/main/conf.py:32
+#: awx/main/conf.py:31
msgid ""
"Enable capturing activity for the activity stream when running inventory "
"sync."
msgstr ""
-#: awx/main/conf.py:40
+#: awx/main/conf.py:39
msgid "All Users Visible to Organization Admins"
msgstr ""
-#: awx/main/conf.py:41
+#: awx/main/conf.py:40
msgid ""
"Controls whether any Organization Admin can view all users and teams, even "
"those not associated with their Organization."
msgstr ""
-#: awx/main/conf.py:50
+#: awx/main/conf.py:49
msgid "Organization Admins Can Manage Users and Teams"
msgstr ""
-#: awx/main/conf.py:51
+#: awx/main/conf.py:50
msgid ""
"Controls whether any Organization Admin has the privileges to create and "
"manage users and teams. You may want to disable this ability if you are "
"using an LDAP or SAML integration."
msgstr ""
-#: awx/main/conf.py:62
+#: awx/main/conf.py:61
msgid "Base URL of the Tower host"
msgstr ""
-#: awx/main/conf.py:63
+#: awx/main/conf.py:62
msgid ""
"This setting is used by services like notifications to render a valid url to "
"the Tower host."
msgstr ""
-#: awx/main/conf.py:72
+#: awx/main/conf.py:71
msgid "Remote Host Headers"
msgstr ""
-#: awx/main/conf.py:73
+#: awx/main/conf.py:72
msgid ""
"HTTP headers and meta keys to search to determine remote host name or IP. "
"Add additional items to this list, such as \"HTTP_X_FORWARDED_FOR\", if "
@@ -1904,114 +2012,112 @@ msgid ""
"Adminstrator guide for more details."
msgstr ""
-#: awx/main/conf.py:85
-msgid "Proxy IP Whitelist"
+#: awx/main/conf.py:84
+msgid "Proxy IP Allowed List"
msgstr ""
-#: awx/main/conf.py:86
+#: awx/main/conf.py:85
msgid ""
"If Tower is behind a reverse proxy/load balancer, use this setting to "
-"whitelist the proxy IP addresses from which Tower should trust custom "
+"configure the proxy IP addresses from which Tower should trust custom "
"REMOTE_HOST_HEADERS header values. If this setting is an empty list (the "
"default), the headers specified by REMOTE_HOST_HEADERS will be trusted "
"unconditionally')"
msgstr ""
-#: awx/main/conf.py:112
+#: awx/main/conf.py:111
msgid "License"
msgstr ""
-#: awx/main/conf.py:113
+#: awx/main/conf.py:112
msgid ""
"The license controls which features and functionality are enabled. Use /api/"
"v2/config/ to update or change the license."
msgstr ""
-#: awx/main/conf.py:127
+#: awx/main/conf.py:126
msgid "Red Hat customer username"
msgstr ""
-#: awx/main/conf.py:128
+#: awx/main/conf.py:127
msgid ""
"This username is used to retrieve license information and to send Automation "
"Analytics"
msgstr ""
-#: awx/main/conf.py:140
+#: awx/main/conf.py:139
msgid "Red Hat customer password"
msgstr ""
-#: awx/main/conf.py:141
+#: awx/main/conf.py:140
msgid ""
"This password is used to retrieve license information and to send Automation "
"Analytics"
msgstr ""
-#: awx/main/conf.py:152
-msgid "Automation Analytics upload URL."
+#: awx/main/conf.py:151
+msgid "Automation Analytics upload URL"
msgstr ""
-#: awx/main/conf.py:153
+#: awx/main/conf.py:152
msgid ""
"This setting is used to to configure data collection for the Automation "
"Analytics dashboard"
msgstr ""
-#: awx/main/conf.py:161
+#: awx/main/conf.py:160
msgid "Unique identifier for an AWX/Tower installation"
msgstr ""
-#: awx/main/conf.py:170
+#: awx/main/conf.py:169
msgid "Custom virtual environment paths"
msgstr ""
-#: awx/main/conf.py:171
+#: awx/main/conf.py:170
msgid ""
"Paths where Tower will look for custom virtual environments (in addition to /"
"var/lib/awx/venv/). Enter one path per line."
msgstr ""
-#: awx/main/conf.py:181
+#: awx/main/conf.py:180
msgid "Ansible Modules Allowed for Ad Hoc Jobs"
msgstr ""
-#: awx/main/conf.py:182
+#: awx/main/conf.py:181
msgid "List of modules allowed to be used by ad-hoc jobs."
msgstr ""
-#: awx/main/conf.py:183 awx/main/conf.py:205 awx/main/conf.py:214
-#: awx/main/conf.py:225 awx/main/conf.py:235 awx/main/conf.py:245
-#: awx/main/conf.py:256 awx/main/conf.py:267 awx/main/conf.py:278
-#: awx/main/conf.py:290 awx/main/conf.py:299 awx/main/conf.py:312
-#: awx/main/conf.py:325 awx/main/conf.py:337 awx/main/conf.py:348
-#: awx/main/conf.py:359 awx/main/conf.py:371 awx/main/conf.py:383
-#: awx/main/conf.py:394 awx/main/conf.py:414 awx/main/conf.py:424
-#: awx/main/conf.py:434 awx/main/conf.py:450 awx/main/conf.py:463
-#: awx/main/conf.py:477 awx/main/conf.py:491 awx/main/conf.py:503
-#: awx/main/conf.py:513 awx/main/conf.py:524 awx/main/conf.py:534
-#: awx/main/conf.py:545 awx/main/conf.py:555 awx/main/conf.py:565
-#: awx/main/conf.py:577 awx/main/conf.py:589 awx/main/conf.py:601
-#: awx/main/conf.py:615 awx/main/conf.py:627
+#: awx/main/conf.py:182 awx/main/conf.py:204 awx/main/conf.py:213
+#: awx/main/conf.py:224 awx/main/conf.py:234 awx/main/conf.py:244
+#: awx/main/conf.py:254 awx/main/conf.py:266 awx/main/conf.py:279
+#: awx/main/conf.py:289 awx/main/conf.py:302 awx/main/conf.py:315
+#: awx/main/conf.py:327 awx/main/conf.py:338 awx/main/conf.py:349
+#: awx/main/conf.py:361 awx/main/conf.py:373 awx/main/conf.py:384
+#: awx/main/conf.py:404 awx/main/conf.py:414 awx/main/conf.py:424
+#: awx/main/conf.py:437 awx/main/conf.py:448 awx/main/conf.py:458
+#: awx/main/conf.py:469 awx/main/conf.py:479 awx/main/conf.py:489
+#: awx/main/conf.py:501 awx/main/conf.py:514 awx/main/conf.py:527
+#: awx/main/conf.py:542 awx/main/conf.py:555
msgid "Jobs"
msgstr ""
-#: awx/main/conf.py:192
+#: awx/main/conf.py:191
msgid "Always"
msgstr ""
-#: awx/main/conf.py:193
+#: awx/main/conf.py:192
msgid "Never"
msgstr ""
-#: awx/main/conf.py:194
+#: awx/main/conf.py:193
msgid "Only On Job Template Definitions"
msgstr ""
-#: awx/main/conf.py:197
+#: awx/main/conf.py:196
msgid "When can extra variables contain Jinja templates?"
msgstr ""
-#: awx/main/conf.py:199
+#: awx/main/conf.py:198
msgid ""
"Ansible allows variable substitution via the Jinja2 templating language for "
"--extra-vars. This poses a potential security risk where Tower users with "
@@ -2020,358 +2126,294 @@ msgid ""
"to \"template\" or \"never\"."
msgstr ""
-#: awx/main/conf.py:212
+#: awx/main/conf.py:211
msgid "Enable job isolation"
msgstr ""
-#: awx/main/conf.py:213
+#: awx/main/conf.py:212
msgid ""
"Isolates an Ansible job from protected parts of the system to prevent "
"exposing sensitive information."
msgstr ""
-#: awx/main/conf.py:221
+#: awx/main/conf.py:220
msgid "Job execution path"
msgstr ""
-#: awx/main/conf.py:222
+#: awx/main/conf.py:221
msgid ""
"The directory in which Tower will create new temporary directories for job "
"execution and isolation (such as credential files and custom inventory "
"scripts)."
msgstr ""
-#: awx/main/conf.py:233
+#: awx/main/conf.py:232
msgid "Paths to hide from isolated jobs"
msgstr ""
-#: awx/main/conf.py:234
+#: awx/main/conf.py:233
msgid ""
"Additional paths to hide from isolated processes. Enter one path per line."
msgstr ""
-#: awx/main/conf.py:243
+#: awx/main/conf.py:242
msgid "Paths to expose to isolated jobs"
msgstr ""
-#: awx/main/conf.py:244
+#: awx/main/conf.py:243
msgid ""
-"Whitelist of paths that would otherwise be hidden to expose to isolated "
-"jobs. Enter one path per line."
+"List of paths that would otherwise be hidden to expose to isolated jobs. "
+"Enter one path per line."
msgstr ""
-#: awx/main/conf.py:254
-msgid "Verbosity level for isolated node management tasks"
-msgstr ""
-
-#: awx/main/conf.py:255
-msgid ""
-"This can be raised to aid in debugging connection issues for isolated task "
-"execution"
-msgstr ""
-
-#: awx/main/conf.py:265
+#: awx/main/conf.py:252
msgid "Isolated status check interval"
msgstr ""
-#: awx/main/conf.py:266
+#: awx/main/conf.py:253
msgid ""
"The number of seconds to sleep between status checks for jobs running on "
"isolated instances."
msgstr ""
-#: awx/main/conf.py:275
+#: awx/main/conf.py:263
msgid "Isolated launch timeout"
msgstr ""
-#: awx/main/conf.py:276
+#: awx/main/conf.py:264
msgid ""
"The timeout (in seconds) for launching jobs on isolated instances. This "
"includes the time needed to copy source control files (playbooks) to the "
"isolated instance."
msgstr ""
-#: awx/main/conf.py:287
+#: awx/main/conf.py:276
msgid "Isolated connection timeout"
msgstr ""
-#: awx/main/conf.py:288
+#: awx/main/conf.py:277
msgid ""
"Ansible SSH connection timeout (in seconds) to use when communicating with "
"isolated instances. Value should be substantially greater than expected "
"network latency."
msgstr ""
-#: awx/main/conf.py:297
+#: awx/main/conf.py:287
msgid "Isolated host key checking"
msgstr ""
-#: awx/main/conf.py:298
+#: awx/main/conf.py:288
msgid ""
"When set to True, AWX will enforce strict host key checking for "
"communication with isolated nodes."
msgstr ""
-#: awx/main/conf.py:308
+#: awx/main/conf.py:298
msgid "Generate RSA keys for isolated instances"
msgstr ""
-#: awx/main/conf.py:309
+#: awx/main/conf.py:299
msgid ""
"If set, a random RSA key will be generated and distributed to isolated "
"instances. To disable this behavior and manage authentication for isolated "
"instances outside of Tower, disable this setting."
msgstr ""
-#: awx/main/conf.py:323 awx/main/conf.py:324
+#: awx/main/conf.py:313 awx/main/conf.py:314
msgid "The RSA private key for SSH traffic to isolated instances"
msgstr ""
-#: awx/main/conf.py:335 awx/main/conf.py:336
+#: awx/main/conf.py:325 awx/main/conf.py:326
msgid "The RSA public key for SSH traffic to isolated instances"
msgstr ""
-#: awx/main/conf.py:345
+#: awx/main/conf.py:335
msgid "Enable detailed resource profiling on all playbook runs"
msgstr ""
-#: awx/main/conf.py:346
+#: awx/main/conf.py:336
msgid ""
"If set, detailed resource profiling data will be collected on all jobs. This "
"data can be gathered with `sosreport`."
msgstr ""
-#: awx/main/conf.py:356
+#: awx/main/conf.py:346
msgid "Interval (in seconds) between polls for cpu usage."
msgstr ""
-#: awx/main/conf.py:357
+#: awx/main/conf.py:347
msgid ""
"Interval (in seconds) between polls for cpu usage. Setting this lower than "
"the default will affect playbook performance."
msgstr ""
-#: awx/main/conf.py:368
+#: awx/main/conf.py:358
msgid "Interval (in seconds) between polls for memory usage."
msgstr ""
-#: awx/main/conf.py:369
+#: awx/main/conf.py:359
msgid ""
"Interval (in seconds) between polls for memory usage. Setting this lower "
"than the default will affect playbook performance."
msgstr ""
-#: awx/main/conf.py:380
+#: awx/main/conf.py:370
msgid "Interval (in seconds) between polls for PID count."
msgstr ""
-#: awx/main/conf.py:381
+#: awx/main/conf.py:371
msgid ""
"Interval (in seconds) between polls for PID count. Setting this lower than "
"the default will affect playbook performance."
msgstr ""
-#: awx/main/conf.py:392
+#: awx/main/conf.py:382
msgid "Extra Environment Variables"
msgstr ""
-#: awx/main/conf.py:393
+#: awx/main/conf.py:383
msgid ""
"Additional environment variables set for playbook runs, inventory updates, "
"project updates, and notification sending."
msgstr ""
-#: awx/main/conf.py:403
+#: awx/main/conf.py:393
msgid "Gather data for Automation Analytics"
msgstr ""
-#: awx/main/conf.py:404
+#: awx/main/conf.py:394
msgid "Enables Tower to gather data on automation and send it to Red Hat."
msgstr ""
-#: awx/main/conf.py:412
+#: awx/main/conf.py:402
msgid "Run Project Updates With Higher Verbosity"
msgstr ""
-#: awx/main/conf.py:413
+#: awx/main/conf.py:403
msgid ""
"Adds the CLI -vvv flag to ansible-playbook runs of project_update.yml used "
"for project updates."
msgstr ""
-#: awx/main/conf.py:422
+#: awx/main/conf.py:412
msgid "Enable Role Download"
msgstr ""
-#: awx/main/conf.py:423
+#: awx/main/conf.py:413
msgid ""
"Allows roles to be dynamically downloaded from a requirements.yml file for "
"SCM projects."
msgstr ""
-#: awx/main/conf.py:432
+#: awx/main/conf.py:422
msgid "Enable Collection(s) Download"
msgstr ""
-#: awx/main/conf.py:433
+#: awx/main/conf.py:423
msgid ""
"Allows collections to be dynamically downloaded from a requirements.yml file "
"for SCM projects."
msgstr ""
-#: awx/main/conf.py:443
-msgid "Primary Galaxy Server URL"
+#: awx/main/conf.py:432
+msgid "Follow symlinks"
+msgstr ""
+
+#: awx/main/conf.py:434
+msgid ""
+"Follow symbolic links when scanning for playbooks. Be aware that setting "
+"this to True can lead to infinite recursion if a link points to a parent "
+"directory of itself."
msgstr ""
#: awx/main/conf.py:445
-msgid ""
-"For organizations that run their own Galaxy service, this gives the option "
-"to specify a host as the primary galaxy server. Requirements will be "
-"downloaded from the primary if the specific role or collection is available "
-"there. If the content is not avilable in the primary, or if this field is "
-"left blank, it will default to galaxy.ansible.com."
-msgstr ""
-
-#: awx/main/conf.py:459
-msgid "Primary Galaxy Server Username"
-msgstr ""
-
-#: awx/main/conf.py:460
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The username to use for basic authentication against the Galaxy "
-"instance, this is mutually exclusive with PRIMARY_GALAXY_TOKEN."
-msgstr ""
-
-#: awx/main/conf.py:473
-msgid "Primary Galaxy Server Password"
-msgstr ""
-
-#: awx/main/conf.py:474
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The password to use for basic authentication against the Galaxy "
-"instance, this is mutually exclusive with PRIMARY_GALAXY_TOKEN."
-msgstr ""
-
-#: awx/main/conf.py:487
-msgid "Primary Galaxy Server Token"
-msgstr ""
-
-#: awx/main/conf.py:488
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The token to use for connecting with the Galaxy instance, this is "
-"mutually exclusive with corresponding username and password settings."
-msgstr ""
-
-#: awx/main/conf.py:500
-msgid "Primary Galaxy Authentication URL"
-msgstr ""
-
-#: awx/main/conf.py:501
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The token_endpoint of a Keycloak server."
-msgstr ""
-
-#: awx/main/conf.py:511
-msgid "Allow Access to Public Galaxy"
-msgstr ""
-
-#: awx/main/conf.py:512
-msgid ""
-"Allow or deny access to the public Ansible Galaxy during project updates."
-msgstr ""
-
-#: awx/main/conf.py:521
msgid "Ignore Ansible Galaxy SSL Certificate Verification"
msgstr ""
-#: awx/main/conf.py:522
+#: awx/main/conf.py:446
msgid ""
-"If set to true, certificate validation will not be done wheninstalling "
+"If set to true, certificate validation will not be done when installing "
"content from any Galaxy server."
msgstr ""
-#: awx/main/conf.py:532
+#: awx/main/conf.py:456
msgid "Standard Output Maximum Display Size"
msgstr ""
-#: awx/main/conf.py:533
+#: awx/main/conf.py:457
msgid ""
"Maximum Size of Standard Output in bytes to display before requiring the "
"output be downloaded."
msgstr ""
-#: awx/main/conf.py:542
+#: awx/main/conf.py:466
msgid "Job Event Standard Output Maximum Display Size"
msgstr ""
-#: awx/main/conf.py:544
+#: awx/main/conf.py:468
msgid ""
"Maximum Size of Standard Output in bytes to display for a single job or ad "
"hoc command event. `stdout` will end with `…` when truncated."
msgstr ""
-#: awx/main/conf.py:553
+#: awx/main/conf.py:477
msgid "Maximum Scheduled Jobs"
msgstr ""
-#: awx/main/conf.py:554
+#: awx/main/conf.py:478
msgid ""
"Maximum number of the same job template that can be waiting to run when "
"launching from a schedule before no more are created."
msgstr ""
-#: awx/main/conf.py:563
+#: awx/main/conf.py:487
msgid "Ansible Callback Plugins"
msgstr ""
-#: awx/main/conf.py:564
+#: awx/main/conf.py:488
msgid ""
"List of paths to search for extra callback plugins to be used when running "
"jobs. Enter one path per line."
msgstr ""
-#: awx/main/conf.py:574
+#: awx/main/conf.py:498
msgid "Default Job Timeout"
msgstr ""
-#: awx/main/conf.py:575
+#: awx/main/conf.py:499
msgid ""
"Maximum time in seconds to allow jobs to run. Use value of 0 to indicate "
"that no timeout should be imposed. A timeout set on an individual job "
"template will override this."
msgstr ""
-#: awx/main/conf.py:586
+#: awx/main/conf.py:511
msgid "Default Inventory Update Timeout"
msgstr ""
-#: awx/main/conf.py:587
+#: awx/main/conf.py:512
msgid ""
"Maximum time in seconds to allow inventory updates to run. Use value of 0 to "
"indicate that no timeout should be imposed. A timeout set on an individual "
"inventory source will override this."
msgstr ""
-#: awx/main/conf.py:598
+#: awx/main/conf.py:524
msgid "Default Project Update Timeout"
msgstr ""
-#: awx/main/conf.py:599
+#: awx/main/conf.py:525
msgid ""
"Maximum time in seconds to allow project updates to run. Use value of 0 to "
"indicate that no timeout should be imposed. A timeout set on an individual "
"project will override this."
msgstr ""
-#: awx/main/conf.py:610
+#: awx/main/conf.py:537
msgid "Per-Host Ansible Fact Cache Timeout"
msgstr ""
-#: awx/main/conf.py:611
+#: awx/main/conf.py:538
msgid ""
"Maximum time, in seconds, that stored Ansible facts are considered valid "
"since the last time they were modified. Only valid, non-stale, facts will be "
@@ -2380,74 +2422,74 @@ msgid ""
"timeout should be imposed."
msgstr ""
-#: awx/main/conf.py:624
-msgid "Maximum number of forks per job."
+#: awx/main/conf.py:552
+msgid "Maximum number of forks per job"
msgstr ""
-#: awx/main/conf.py:625
+#: awx/main/conf.py:553
msgid ""
"Saving a Job Template with more than this number of forks will result in an "
"error. When set to 0, no limit is applied."
msgstr ""
-#: awx/main/conf.py:636
+#: awx/main/conf.py:564
msgid "Logging Aggregator"
msgstr ""
-#: awx/main/conf.py:637
+#: awx/main/conf.py:565
msgid "Hostname/IP where external logs will be sent to."
msgstr ""
-#: awx/main/conf.py:638 awx/main/conf.py:649 awx/main/conf.py:661
-#: awx/main/conf.py:671 awx/main/conf.py:683 awx/main/conf.py:698
-#: awx/main/conf.py:710 awx/main/conf.py:719 awx/main/conf.py:729
-#: awx/main/conf.py:741 awx/main/conf.py:752 awx/main/conf.py:764
-#: awx/main/conf.py:777 awx/main/conf.py:787 awx/main/conf.py:799
-#: awx/main/conf.py:810 awx/main/conf.py:820
+#: awx/main/conf.py:566 awx/main/conf.py:577 awx/main/conf.py:589
+#: awx/main/conf.py:599 awx/main/conf.py:611 awx/main/conf.py:626
+#: awx/main/conf.py:638 awx/main/conf.py:647 awx/main/conf.py:657
+#: awx/main/conf.py:669 awx/main/conf.py:680 awx/main/conf.py:693
+#: awx/main/conf.py:706 awx/main/conf.py:718 awx/main/conf.py:729
+#: awx/main/conf.py:739
msgid "Logging"
msgstr ""
-#: awx/main/conf.py:646
+#: awx/main/conf.py:574
msgid "Logging Aggregator Port"
msgstr ""
-#: awx/main/conf.py:647
+#: awx/main/conf.py:575
msgid ""
"Port on Logging Aggregator to send logs to (if required and not provided in "
"Logging Aggregator)."
msgstr ""
-#: awx/main/conf.py:659
+#: awx/main/conf.py:587
msgid "Logging Aggregator Type"
msgstr ""
-#: awx/main/conf.py:660
+#: awx/main/conf.py:588
msgid "Format messages for the chosen log aggregator."
msgstr ""
-#: awx/main/conf.py:669
+#: awx/main/conf.py:597
msgid "Logging Aggregator Username"
msgstr ""
-#: awx/main/conf.py:670
+#: awx/main/conf.py:598
msgid "Username for external log aggregator (if required; HTTP/s only)."
msgstr ""
-#: awx/main/conf.py:681
+#: awx/main/conf.py:609
msgid "Logging Aggregator Password/Token"
msgstr ""
-#: awx/main/conf.py:682
+#: awx/main/conf.py:610
msgid ""
"Password or authentication token for external log aggregator (if required; "
"HTTP/s only)."
msgstr ""
-#: awx/main/conf.py:691
+#: awx/main/conf.py:619
msgid "Loggers Sending Data to Log Aggregator Form"
msgstr ""
-#: awx/main/conf.py:692
+#: awx/main/conf.py:620
msgid ""
"List of loggers that will send HTTP logs to the collector, these can include "
"any or all of: \n"
@@ -2457,11 +2499,11 @@ msgid ""
"system_tracking - facts gathered from scan jobs."
msgstr ""
-#: awx/main/conf.py:705
+#: awx/main/conf.py:633
msgid "Log System Tracking Facts Individually"
msgstr ""
-#: awx/main/conf.py:706
+#: awx/main/conf.py:634
msgid ""
"If set, system tracking facts will be sent for each package, service, or "
"other item found in a scan, allowing for greater search query granularity. "
@@ -2469,47 +2511,47 @@ msgid ""
"efficiency in fact processing."
msgstr ""
-#: awx/main/conf.py:717
+#: awx/main/conf.py:645
msgid "Enable External Logging"
msgstr ""
-#: awx/main/conf.py:718
+#: awx/main/conf.py:646
msgid "Enable sending logs to external log aggregator."
msgstr ""
-#: awx/main/conf.py:727
+#: awx/main/conf.py:655
msgid "Cluster-wide Tower unique identifier."
msgstr ""
-#: awx/main/conf.py:728
+#: awx/main/conf.py:656
msgid "Useful to uniquely identify Tower instances."
msgstr ""
-#: awx/main/conf.py:737
+#: awx/main/conf.py:665
msgid "Logging Aggregator Protocol"
msgstr ""
-#: awx/main/conf.py:738
+#: awx/main/conf.py:666
msgid ""
"Protocol used to communicate with log aggregator. HTTPS/HTTP assumes HTTPS "
"unless http:// is explicitly used in the Logging Aggregator hostname."
msgstr ""
-#: awx/main/conf.py:748
+#: awx/main/conf.py:676
msgid "TCP Connection Timeout"
msgstr ""
-#: awx/main/conf.py:749
+#: awx/main/conf.py:677
msgid ""
"Number of seconds for a TCP connection to external log aggregator to "
"timeout. Applies to HTTPS and TCP log aggregator protocols."
msgstr ""
-#: awx/main/conf.py:759
+#: awx/main/conf.py:688
msgid "Enable/disable HTTPS certificate verification"
msgstr ""
-#: awx/main/conf.py:760
+#: awx/main/conf.py:689
msgid ""
"Flag to control enable/disable of certificate verification when "
"LOG_AGGREGATOR_PROTOCOL is \"https\". If enabled, Tower's log handler will "
@@ -2517,11 +2559,11 @@ msgid ""
"connection."
msgstr ""
-#: awx/main/conf.py:772
+#: awx/main/conf.py:701
msgid "Logging Aggregator Level Threshold"
msgstr ""
-#: awx/main/conf.py:773
+#: awx/main/conf.py:702
msgid ""
"Level threshold used by log handler. Severities from lowest to highest are "
"DEBUG, INFO, WARNING, ERROR, CRITICAL. Messages less severe than the "
@@ -2529,198 +2571,144 @@ msgid ""
"anlytics ignore this setting)"
msgstr ""
-#: awx/main/conf.py:785
-msgid "Enabled external log aggregation auditing"
-msgstr ""
-
-#: awx/main/conf.py:786
-msgid ""
-"When enabled, all external logs emitted by Tower will also be written to /"
-"var/log/tower/external.log. This is an experimental setting intended to be "
-"used for debugging external log aggregation issues (and may be subject to "
-"change in the future)."
-msgstr ""
-
-#: awx/main/conf.py:795
+#: awx/main/conf.py:714
msgid "Maximum disk persistance for external log aggregation (in GB)"
msgstr ""
-#: awx/main/conf.py:796
+#: awx/main/conf.py:715
msgid ""
"Amount of data to store (in gigabytes) during an outage of the external log "
"aggregator (defaults to 1). Equivalent to the rsyslogd queue.maxdiskspace "
"setting."
msgstr ""
-#: awx/main/conf.py:806
+#: awx/main/conf.py:725
msgid "File system location for rsyslogd disk persistence"
msgstr ""
-#: awx/main/conf.py:807
+#: awx/main/conf.py:726
msgid ""
"Location to persist logs that should be retried after an outage of the "
"external log aggregator (defaults to /var/lib/awx). Equivalent to the "
"rsyslogd queue.spoolDirectory setting."
msgstr ""
-#: awx/main/conf.py:817
+#: awx/main/conf.py:736
msgid "Enable rsyslogd debugging"
msgstr ""
-#: awx/main/conf.py:818
+#: awx/main/conf.py:737
msgid ""
"Enabled high verbosity debugging for rsyslogd. Useful for debugging "
"connection issues for external log aggregation."
msgstr ""
-#: awx/main/conf.py:828
-msgid "Message Durability"
-msgstr ""
-
-#: awx/main/conf.py:829
-msgid ""
-"When set (the default), underlying queues will be persisted to disk. "
-"Disable this to enable higher message bus throughput."
-msgstr ""
-
-#: awx/main/conf.py:838
+#: awx/main/conf.py:748
msgid "Last gather date for Automation Analytics."
msgstr ""
-#: awx/main/conf.py:848
+#: awx/main/conf.py:758
msgid "Automation Analytics Gather Interval"
msgstr ""
-#: awx/main/conf.py:849
+#: awx/main/conf.py:759
msgid "Interval (in seconds) between data gathering."
msgstr ""
-#: awx/main/conf.py:871 awx/sso/conf.py:1239
+#: awx/main/conf.py:782 awx/sso/conf.py:1251
msgid "\n"
msgstr ""
-#: awx/main/conf.py:892
-msgid ""
-"A URL for Primary Galaxy must be defined before disabling public Galaxy."
-msgstr ""
-
-#: awx/main/conf.py:912
-msgid "Cannot provide field if PRIMARY_GALAXY_URL is not set."
-msgstr ""
-
-#: awx/main/conf.py:925
-#, python-brace-format
-msgid ""
-"Galaxy server settings are not available until Ansible {min_version}, you "
-"are running {current_version}."
-msgstr ""
-
-#: awx/main/conf.py:934
-msgid ""
-"Setting Galaxy token and authentication URL is mutually exclusive with "
-"username and password."
-msgstr ""
-
-#: awx/main/conf.py:937
-msgid "If authenticating via username and password, both must be provided."
-msgstr ""
-
-#: awx/main/conf.py:943
-msgid ""
-"If authenticating via token, both token and authentication URL must be "
-"provided."
-msgstr ""
-
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Sudo"
msgstr ""
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Su"
msgstr ""
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Pbrun"
msgstr ""
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Pfexec"
msgstr ""
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "DZDO"
msgstr ""
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "Pmrun"
msgstr ""
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "Runas"
msgstr ""
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Enable"
msgstr ""
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Doas"
msgstr ""
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Ksu"
msgstr ""
-#: awx/main/constants.py:20
+#: awx/main/constants.py:19
msgid "Machinectl"
msgstr ""
-#: awx/main/constants.py:20
+#: awx/main/constants.py:19
msgid "Sesu"
msgstr ""
-#: awx/main/constants.py:22
+#: awx/main/constants.py:21
msgid "None"
msgstr ""
-#: awx/main/credential_plugins/aim.py:16
+#: awx/main/credential_plugins/aim.py:11
msgid "CyberArk AIM URL"
msgstr ""
-#: awx/main/credential_plugins/aim.py:21
+#: awx/main/credential_plugins/aim.py:16
msgid "Application ID"
msgstr ""
-#: awx/main/credential_plugins/aim.py:26
+#: awx/main/credential_plugins/aim.py:21
msgid "Client Key"
msgstr ""
-#: awx/main/credential_plugins/aim.py:32
+#: awx/main/credential_plugins/aim.py:27
msgid "Client Certificate"
msgstr ""
-#: awx/main/credential_plugins/aim.py:38
+#: awx/main/credential_plugins/aim.py:33
msgid "Verify SSL Certificates"
msgstr ""
-#: awx/main/credential_plugins/aim.py:44
+#: awx/main/credential_plugins/aim.py:39
msgid "Object Query"
msgstr ""
-#: awx/main/credential_plugins/aim.py:46
+#: awx/main/credential_plugins/aim.py:41
msgid ""
"Lookup query for the object. Ex: Safe=TestSafe;Object=testAccountName123"
msgstr ""
-#: awx/main/credential_plugins/aim.py:49
+#: awx/main/credential_plugins/aim.py:44
msgid "Object Query Format"
msgstr ""
-#: awx/main/credential_plugins/aim.py:55
+#: awx/main/credential_plugins/aim.py:50
msgid "Reason"
msgstr ""
-#: awx/main/credential_plugins/aim.py:57
+#: awx/main/credential_plugins/aim.py:52
msgid ""
"Object request reason. This is only needed if it is required by the object's "
"policy."
@@ -2731,12 +2719,12 @@ msgid "Vault URL (DNS Name)"
msgstr ""
#: awx/main/credential_plugins/azure_kv.py:26
-#: awx/main/models/credential/__init__.py:960
+#: awx/main/models/credential/__init__.py:968
msgid "Client ID"
msgstr ""
#: awx/main/credential_plugins/azure_kv.py:35
-#: awx/main/models/credential/__init__.py:969
+#: awx/main/models/credential/__init__.py:977
msgid "Tenant ID"
msgstr ""
@@ -2757,166 +2745,177 @@ msgid "The name of the secret to look up."
msgstr ""
#: awx/main/credential_plugins/azure_kv.py:51
-#: awx/main/credential_plugins/conjur.py:47
+#: awx/main/credential_plugins/conjur.py:42
msgid "Secret Version"
msgstr ""
#: awx/main/credential_plugins/azure_kv.py:53
-#: awx/main/credential_plugins/conjur.py:49
-#: awx/main/credential_plugins/hashivault.py:86
+#: awx/main/credential_plugins/conjur.py:44
+#: awx/main/credential_plugins/hashivault.py:89
msgid ""
"Used to specify a specific secret version (if left empty, the latest version "
"will be used)."
msgstr ""
-#: awx/main/credential_plugins/conjur.py:18
+#: awx/main/credential_plugins/conjur.py:13
msgid "Conjur URL"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:23
+#: awx/main/credential_plugins/conjur.py:18
msgid "API Key"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:28 awx/main/models/inventory.py:1018
+#: awx/main/credential_plugins/conjur.py:23
+#: awx/main/migrations/_inventory_source_vars.py:142
msgid "Account"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:32
-#: awx/main/models/credential/__init__.py:598
-#: awx/main/models/credential/__init__.py:654
-#: awx/main/models/credential/__init__.py:712
-#: awx/main/models/credential/__init__.py:785
-#: awx/main/models/credential/__init__.py:838
-#: awx/main/models/credential/__init__.py:864
-#: awx/main/models/credential/__init__.py:891
-#: awx/main/models/credential/__init__.py:951
-#: awx/main/models/credential/__init__.py:1024
-#: awx/main/models/credential/__init__.py:1055
-#: awx/main/models/credential/__init__.py:1105
+#: awx/main/credential_plugins/conjur.py:27
+#: awx/main/models/credential/__init__.py:606
+#: awx/main/models/credential/__init__.py:662
+#: awx/main/models/credential/__init__.py:720
+#: awx/main/models/credential/__init__.py:793
+#: awx/main/models/credential/__init__.py:846
+#: awx/main/models/credential/__init__.py:872
+#: awx/main/models/credential/__init__.py:899
+#: awx/main/models/credential/__init__.py:959
+#: awx/main/models/credential/__init__.py:1032
+#: awx/main/models/credential/__init__.py:1063
+#: awx/main/models/credential/__init__.py:1113
msgid "Username"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:36
+#: awx/main/credential_plugins/conjur.py:31
msgid "Public Key Certificate"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:42
+#: awx/main/credential_plugins/conjur.py:37
msgid "Secret Identifier"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:44
+#: awx/main/credential_plugins/conjur.py:39
msgid "The identifier for the secret e.g., /some/identifier"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:19
+#: awx/main/credential_plugins/hashivault.py:14
msgid "Server URL"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:22
+#: awx/main/credential_plugins/hashivault.py:17
msgid "The URL to the HashiCorp Vault"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:25
-#: awx/main/models/credential/__init__.py:990
-#: awx/main/models/credential/__init__.py:1007
+#: awx/main/credential_plugins/hashivault.py:20
+#: awx/main/models/credential/__init__.py:998
+#: awx/main/models/credential/__init__.py:1015
msgid "Token"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:28
+#: awx/main/credential_plugins/hashivault.py:23
msgid "The access token used to authenticate to the Vault server"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:31
+#: awx/main/credential_plugins/hashivault.py:26
msgid "CA Certificate"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:34
+#: awx/main/credential_plugins/hashivault.py:29
msgid ""
"The CA certificate used to verify the SSL certificate of the Vault server"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:37
+#: awx/main/credential_plugins/hashivault.py:32
msgid "AppRole role_id"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:40
+#: awx/main/credential_plugins/hashivault.py:35
msgid "The Role ID for AppRole Authentication"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:43
+#: awx/main/credential_plugins/hashivault.py:38
msgid "AppRole secret_id"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:47
+#: awx/main/credential_plugins/hashivault.py:42
msgid "The Secret ID for AppRole Authentication"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:52
-msgid "Path to Secret"
+#: awx/main/credential_plugins/hashivault.py:45
+msgid "Path to Approle Auth"
+msgstr ""
+
+#: awx/main/credential_plugins/hashivault.py:49
+msgid ""
+"The AppRole Authentication path to use if one isn't provided in the metadata "
+"when linking to an input field. Defaults to 'approle'"
msgstr ""
#: awx/main/credential_plugins/hashivault.py:54
+msgid "Path to Secret"
+msgstr ""
+
+#: awx/main/credential_plugins/hashivault.py:56
msgid "The path to the secret stored in the secret backend e.g, /some/secret/"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:57
+#: awx/main/credential_plugins/hashivault.py:59
msgid "Path to Auth"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:59
+#: awx/main/credential_plugins/hashivault.py:62
msgid "The path where the Authentication method is mounted e.g, approle"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:67
+#: awx/main/credential_plugins/hashivault.py:70
msgid "API Version"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:69
+#: awx/main/credential_plugins/hashivault.py:72
msgid ""
"API v1 is for static key/value lookups. API v2 is for versioned key/value "
"lookups."
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:74
+#: awx/main/credential_plugins/hashivault.py:77
msgid "Name of Secret Backend"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:76
+#: awx/main/credential_plugins/hashivault.py:79
msgid ""
"The name of the kv secret backend (if left empty, the first segment of the "
"secret path will be used)."
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:79
-#: awx/main/models/inventory.py:1023
+#: awx/main/credential_plugins/hashivault.py:82
+#: awx/main/migrations/_inventory_source_vars.py:147
msgid "Key Name"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:81
+#: awx/main/credential_plugins/hashivault.py:84
msgid "The name of the key to look up in the secret."
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:84
+#: awx/main/credential_plugins/hashivault.py:87
msgid "Secret Version (v2 only)"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:93
+#: awx/main/credential_plugins/hashivault.py:96
msgid "Unsigned Public Key"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:98
+#: awx/main/credential_plugins/hashivault.py:101
msgid "Role Name"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:100
+#: awx/main/credential_plugins/hashivault.py:103
msgid "The name of the role used to sign."
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:103
+#: awx/main/credential_plugins/hashivault.py:106
msgid "Valid Principals"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:105
+#: awx/main/credential_plugins/hashivault.py:108
msgid ""
"Valid principals (either usernames or hostnames) that the certificate should "
"be signed for."
@@ -2951,70 +2950,74 @@ msgstr ""
msgid "secret values must be of type string, not {}"
msgstr ""
-#: awx/main/fields.py:667
+#: awx/main/fields.py:675
#, python-format
msgid "cannot be set unless \"%s\" is set"
msgstr ""
-#: awx/main/fields.py:702
+#: awx/main/fields.py:710
msgid "must be set when SSH key is encrypted."
msgstr ""
-#: awx/main/fields.py:710
+#: awx/main/fields.py:718
msgid "should not be set when SSH key is not encrypted."
msgstr ""
-#: awx/main/fields.py:769
+#: awx/main/fields.py:777
msgid "'dependencies' is not supported for custom credentials."
msgstr ""
-#: awx/main/fields.py:783
+#: awx/main/fields.py:791
msgid "\"tower\" is a reserved field name"
msgstr ""
-#: awx/main/fields.py:790
+#: awx/main/fields.py:798
#, python-format
msgid "field IDs must be unique (%s)"
msgstr ""
-#: awx/main/fields.py:805
+#: awx/main/fields.py:813
msgid "{} is not a {}"
msgstr ""
-#: awx/main/fields.py:811
+#: awx/main/fields.py:819
#, python-brace-format
msgid "{sub_key} not allowed for {element_type} type ({element_id})"
msgstr ""
-#: awx/main/fields.py:869
+#: awx/main/fields.py:877
msgid ""
"Environment variable {} may affect Ansible configuration so its use is not "
"allowed in credentials."
msgstr ""
-#: awx/main/fields.py:875
-msgid "Environment variable {} is blacklisted from use in credentials."
+#: awx/main/fields.py:883
+msgid "Environment variable {} is not allowed to be used in credentials."
msgstr ""
-#: awx/main/fields.py:903
+#: awx/main/fields.py:911
msgid ""
"Must define unnamed file injector in order to reference `tower.filename`."
msgstr ""
-#: awx/main/fields.py:910
+#: awx/main/fields.py:918
msgid "Cannot directly reference reserved `tower` namespace container."
msgstr ""
-#: awx/main/fields.py:920
+#: awx/main/fields.py:928
msgid "Must use multi-file syntax when injecting multiple files"
msgstr ""
-#: awx/main/fields.py:940
+#: awx/main/fields.py:948
#, python-brace-format
msgid "{sub_key} uses an undefined field ({error_msg})"
msgstr ""
-#: awx/main/fields.py:947
+#: awx/main/fields.py:955
+msgid "Encountered unsafe code execution: {}"
+msgstr ""
+
+#: awx/main/fields.py:959
#, python-brace-format
msgid ""
"Syntax error rendering template for {sub_key} inside of {type} ({error_msg})"
@@ -3044,6 +3047,50 @@ msgid ""
"this list to programmatically generate named URLs for resources"
msgstr ""
+#: awx/main/migrations/_inventory_source_vars.py:140
+msgid "Image ID"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:141
+msgid "Availability Zone"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:143
+msgid "Instance ID"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:144
+msgid "Instance State"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:145
+msgid "Platform"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:146
+msgid "Instance Type"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:148
+msgid "Region"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:149
+msgid "Security Group"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:150
+msgid "Tags"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:151
+msgid "Tag None"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:152
+msgid "VPC ID"
+msgstr ""
+
#: awx/main/models/activity_stream.py:28
msgid "Entity Created"
msgstr ""
@@ -3090,17 +3137,17 @@ msgstr ""
msgid "No argument passed to %s module."
msgstr ""
-#: awx/main/models/base.py:33 awx/main/models/base.py:39
-#: awx/main/models/base.py:44 awx/main/models/base.py:49
+#: awx/main/models/base.py:34 awx/main/models/base.py:40
+#: awx/main/models/base.py:45 awx/main/models/base.py:50
msgid "Run"
msgstr ""
-#: awx/main/models/base.py:34 awx/main/models/base.py:40
-#: awx/main/models/base.py:45 awx/main/models/base.py:50
+#: awx/main/models/base.py:35 awx/main/models/base.py:41
+#: awx/main/models/base.py:46 awx/main/models/base.py:51
msgid "Check"
msgstr ""
-#: awx/main/models/base.py:35
+#: awx/main/models/base.py:36
msgid "Scan"
msgstr ""
@@ -3110,819 +3157,822 @@ msgid ""
"Tower documentation for details on each type."
msgstr ""
-#: awx/main/models/credential/__init__.py:110
-#: awx/main/models/credential/__init__.py:353
+#: awx/main/models/credential/__init__.py:114
+#: awx/main/models/credential/__init__.py:358
msgid ""
"Enter inputs using either JSON or YAML syntax. Refer to the Ansible Tower "
"documentation for example syntax."
msgstr ""
-#: awx/main/models/credential/__init__.py:325
-#: awx/main/models/credential/__init__.py:594
+#: awx/main/models/credential/__init__.py:329
+#: awx/main/models/credential/__init__.py:602
msgid "Machine"
msgstr ""
-#: awx/main/models/credential/__init__.py:326
-#: awx/main/models/credential/__init__.py:680
+#: awx/main/models/credential/__init__.py:330
+#: awx/main/models/credential/__init__.py:688
msgid "Vault"
msgstr ""
-#: awx/main/models/credential/__init__.py:327
-#: awx/main/models/credential/__init__.py:707
+#: awx/main/models/credential/__init__.py:331
+#: awx/main/models/credential/__init__.py:715
msgid "Network"
msgstr ""
-#: awx/main/models/credential/__init__.py:328
-#: awx/main/models/credential/__init__.py:649
+#: awx/main/models/credential/__init__.py:332
+#: awx/main/models/credential/__init__.py:657
msgid "Source Control"
msgstr ""
-#: awx/main/models/credential/__init__.py:329
+#: awx/main/models/credential/__init__.py:333
msgid "Cloud"
msgstr ""
-#: awx/main/models/credential/__init__.py:330
+#: awx/main/models/credential/__init__.py:334
msgid "Personal Access Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:331
-#: awx/main/models/credential/__init__.py:1019
+#: awx/main/models/credential/__init__.py:335
+#: awx/main/models/credential/__init__.py:1027
msgid "Insights"
msgstr ""
-#: awx/main/models/credential/__init__.py:332
+#: awx/main/models/credential/__init__.py:336
msgid "External"
msgstr ""
-#: awx/main/models/credential/__init__.py:333
+#: awx/main/models/credential/__init__.py:337
msgid "Kubernetes"
msgstr ""
-#: awx/main/models/credential/__init__.py:359
+#: awx/main/models/credential/__init__.py:338
+msgid "Galaxy/Automation Hub"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:364
msgid ""
"Enter injectors using either JSON or YAML syntax. Refer to the Ansible Tower "
"documentation for example syntax."
msgstr ""
-#: awx/main/models/credential/__init__.py:428
+#: awx/main/models/credential/__init__.py:433
#, python-format
msgid "adding %s credential type"
msgstr ""
-#: awx/main/models/credential/__init__.py:602
-#: awx/main/models/credential/__init__.py:658
-#: awx/main/models/credential/__init__.py:716
-#: awx/main/models/credential/__init__.py:842
-#: awx/main/models/credential/__init__.py:868
-#: awx/main/models/credential/__init__.py:895
-#: awx/main/models/credential/__init__.py:955
-#: awx/main/models/credential/__init__.py:1028
-#: awx/main/models/credential/__init__.py:1059
-#: awx/main/models/credential/__init__.py:1109
+#: awx/main/models/credential/__init__.py:610
+#: awx/main/models/credential/__init__.py:666
+#: awx/main/models/credential/__init__.py:724
+#: awx/main/models/credential/__init__.py:850
+#: awx/main/models/credential/__init__.py:876
+#: awx/main/models/credential/__init__.py:903
+#: awx/main/models/credential/__init__.py:963
+#: awx/main/models/credential/__init__.py:1036
+#: awx/main/models/credential/__init__.py:1067
+#: awx/main/models/credential/__init__.py:1119
msgid "Password"
msgstr ""
-#: awx/main/models/credential/__init__.py:608
-#: awx/main/models/credential/__init__.py:721
+#: awx/main/models/credential/__init__.py:616
+#: awx/main/models/credential/__init__.py:729
msgid "SSH Private Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:615
+#: awx/main/models/credential/__init__.py:623
msgid "Signed SSH Certificate"
msgstr ""
-#: awx/main/models/credential/__init__.py:621
-#: awx/main/models/credential/__init__.py:670
-#: awx/main/models/credential/__init__.py:728
+#: awx/main/models/credential/__init__.py:629
+#: awx/main/models/credential/__init__.py:678
+#: awx/main/models/credential/__init__.py:736
msgid "Private Key Passphrase"
msgstr ""
-#: awx/main/models/credential/__init__.py:627
+#: awx/main/models/credential/__init__.py:635
msgid "Privilege Escalation Method"
msgstr ""
-#: awx/main/models/credential/__init__.py:629
+#: awx/main/models/credential/__init__.py:637
msgid ""
"Specify a method for \"become\" operations. This is equivalent to specifying "
"the --become-method Ansible parameter."
msgstr ""
-#: awx/main/models/credential/__init__.py:634
+#: awx/main/models/credential/__init__.py:642
msgid "Privilege Escalation Username"
msgstr ""
-#: awx/main/models/credential/__init__.py:638
+#: awx/main/models/credential/__init__.py:646
msgid "Privilege Escalation Password"
msgstr ""
-#: awx/main/models/credential/__init__.py:663
+#: awx/main/models/credential/__init__.py:671
msgid "SCM Private Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:685
+#: awx/main/models/credential/__init__.py:693
msgid "Vault Password"
msgstr ""
-#: awx/main/models/credential/__init__.py:691
+#: awx/main/models/credential/__init__.py:699
msgid "Vault Identifier"
msgstr ""
-#: awx/main/models/credential/__init__.py:694
+#: awx/main/models/credential/__init__.py:702
msgid ""
"Specify an (optional) Vault ID. This is equivalent to specifying the --vault-"
"id Ansible parameter for providing multiple Vault passwords. Note: this "
"feature only works in Ansible 2.4+."
msgstr ""
-#: awx/main/models/credential/__init__.py:733
+#: awx/main/models/credential/__init__.py:741
msgid "Authorize"
msgstr ""
-#: awx/main/models/credential/__init__.py:737
+#: awx/main/models/credential/__init__.py:745
msgid "Authorize Password"
msgstr ""
-#: awx/main/models/credential/__init__.py:751
+#: awx/main/models/credential/__init__.py:759
msgid "Amazon Web Services"
msgstr ""
-#: awx/main/models/credential/__init__.py:756
+#: awx/main/models/credential/__init__.py:764
msgid "Access Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:760
+#: awx/main/models/credential/__init__.py:768
msgid "Secret Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:765
+#: awx/main/models/credential/__init__.py:773
msgid "STS Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:768
+#: awx/main/models/credential/__init__.py:776
msgid ""
"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."
msgstr ""
-#: awx/main/models/credential/__init__.py:780 awx/main/models/inventory.py:833
+#: awx/main/models/credential/__init__.py:788 awx/main/models/inventory.py:826
msgid "OpenStack"
msgstr ""
-#: awx/main/models/credential/__init__.py:789
+#: awx/main/models/credential/__init__.py:797
msgid "Password (API Key)"
msgstr ""
-#: awx/main/models/credential/__init__.py:794
-#: awx/main/models/credential/__init__.py:1050
+#: awx/main/models/credential/__init__.py:802
+#: awx/main/models/credential/__init__.py:1058
msgid "Host (Authentication URL)"
msgstr ""
-#: awx/main/models/credential/__init__.py:796
+#: awx/main/models/credential/__init__.py:804
msgid ""
"The host to authenticate with. For example, https://openstack.business.com/"
"v2.0/"
msgstr ""
-#: awx/main/models/credential/__init__.py:800
+#: awx/main/models/credential/__init__.py:808
msgid "Project (Tenant Name)"
msgstr ""
-#: awx/main/models/credential/__init__.py:804
+#: awx/main/models/credential/__init__.py:812
msgid "Project (Domain Name)"
msgstr ""
-#: awx/main/models/credential/__init__.py:808
+#: awx/main/models/credential/__init__.py:816
msgid "Domain Name"
msgstr ""
-#: awx/main/models/credential/__init__.py:810
+#: awx/main/models/credential/__init__.py:818
msgid ""
"OpenStack domains define administrative boundaries. It is only needed for "
"Keystone v3 authentication URLs. Refer to Ansible Tower documentation for "
"common scenarios."
msgstr ""
-#: awx/main/models/credential/__init__.py:816
-#: awx/main/models/credential/__init__.py:1114
-#: awx/main/models/credential/__init__.py:1148
+#: awx/main/models/credential/__init__.py:824
+#: awx/main/models/credential/__init__.py:1131
+#: awx/main/models/credential/__init__.py:1166
msgid "Verify SSL"
msgstr ""
-#: awx/main/models/credential/__init__.py:827 awx/main/models/inventory.py:830
+#: awx/main/models/credential/__init__.py:835 awx/main/models/inventory.py:824
msgid "VMware vCenter"
msgstr ""
-#: awx/main/models/credential/__init__.py:832
+#: awx/main/models/credential/__init__.py:840
msgid "VCenter Host"
msgstr ""
-#: awx/main/models/credential/__init__.py:834
+#: awx/main/models/credential/__init__.py:842
msgid ""
"Enter the hostname or IP address that corresponds to your VMware vCenter."
msgstr ""
-#: awx/main/models/credential/__init__.py:853 awx/main/models/inventory.py:831
+#: awx/main/models/credential/__init__.py:861 awx/main/models/inventory.py:825
msgid "Red Hat Satellite 6"
msgstr ""
-#: awx/main/models/credential/__init__.py:858
+#: awx/main/models/credential/__init__.py:866
msgid "Satellite 6 URL"
msgstr ""
-#: awx/main/models/credential/__init__.py:860
+#: awx/main/models/credential/__init__.py:868
msgid ""
"Enter the URL that corresponds to your Red Hat Satellite 6 server. For "
"example, https://satellite.example.org"
msgstr ""
-#: awx/main/models/credential/__init__.py:879 awx/main/models/inventory.py:832
+#: awx/main/models/credential/__init__.py:887
msgid "Red Hat CloudForms"
msgstr ""
-#: awx/main/models/credential/__init__.py:884
+#: awx/main/models/credential/__init__.py:892
msgid "CloudForms URL"
msgstr ""
-#: awx/main/models/credential/__init__.py:886
+#: awx/main/models/credential/__init__.py:894
msgid ""
"Enter the URL for the virtual machine that corresponds to your CloudForms "
"instance. For example, https://cloudforms.example.org"
msgstr ""
-#: awx/main/models/credential/__init__.py:906 awx/main/models/inventory.py:828
+#: awx/main/models/credential/__init__.py:914 awx/main/models/inventory.py:822
msgid "Google Compute Engine"
msgstr ""
-#: awx/main/models/credential/__init__.py:911
+#: awx/main/models/credential/__init__.py:919
msgid "Service Account Email Address"
msgstr ""
-#: awx/main/models/credential/__init__.py:913
+#: awx/main/models/credential/__init__.py:921
msgid ""
"The email address assigned to the Google Compute Engine service account."
msgstr ""
-#: awx/main/models/credential/__init__.py:919
+#: awx/main/models/credential/__init__.py:927
msgid ""
"The Project ID is the GCE assigned identification. It is often constructed "
"as three words or two words followed by a three-digit number. Examples: "
"project-id-000 and another-project-id"
msgstr ""
-#: awx/main/models/credential/__init__.py:925
+#: awx/main/models/credential/__init__.py:933
msgid "RSA Private Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:930
+#: awx/main/models/credential/__init__.py:938
msgid ""
"Paste the contents of the PEM file associated with the service account email."
msgstr ""
-#: awx/main/models/credential/__init__.py:940 awx/main/models/inventory.py:829
+#: awx/main/models/credential/__init__.py:948 awx/main/models/inventory.py:823
msgid "Microsoft Azure Resource Manager"
msgstr ""
-#: awx/main/models/credential/__init__.py:945
+#: awx/main/models/credential/__init__.py:953
msgid "Subscription ID"
msgstr ""
-#: awx/main/models/credential/__init__.py:947
+#: awx/main/models/credential/__init__.py:955
msgid "Subscription ID is an Azure construct, which is mapped to a username."
msgstr ""
-#: awx/main/models/credential/__init__.py:973
+#: awx/main/models/credential/__init__.py:981
msgid "Azure Cloud Environment"
msgstr ""
-#: awx/main/models/credential/__init__.py:975
+#: awx/main/models/credential/__init__.py:983
msgid ""
"Environment variable AZURE_CLOUD_ENVIRONMENT when using Azure GovCloud or "
"Azure stack."
msgstr ""
-#: awx/main/models/credential/__init__.py:985
+#: awx/main/models/credential/__init__.py:993
msgid "GitHub Personal Access Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:993
+#: awx/main/models/credential/__init__.py:1001
msgid "This token needs to come from your profile settings in GitHub"
msgstr ""
-#: awx/main/models/credential/__init__.py:1002
+#: awx/main/models/credential/__init__.py:1010
msgid "GitLab Personal Access Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:1010
+#: awx/main/models/credential/__init__.py:1018
msgid "This token needs to come from your profile settings in GitLab"
msgstr ""
-#: awx/main/models/credential/__init__.py:1045 awx/main/models/inventory.py:834
+#: awx/main/models/credential/__init__.py:1053 awx/main/models/inventory.py:827
msgid "Red Hat Virtualization"
msgstr ""
-#: awx/main/models/credential/__init__.py:1052
+#: awx/main/models/credential/__init__.py:1060
msgid "The host to authenticate with."
msgstr ""
-#: awx/main/models/credential/__init__.py:1064
+#: awx/main/models/credential/__init__.py:1072
msgid "CA File"
msgstr ""
-#: awx/main/models/credential/__init__.py:1066
+#: awx/main/models/credential/__init__.py:1074
msgid "Absolute file path to the CA file to use (optional)"
msgstr ""
-#: awx/main/models/credential/__init__.py:1095 awx/main/models/inventory.py:835
+#: awx/main/models/credential/__init__.py:1103 awx/main/models/inventory.py:828
msgid "Ansible Tower"
msgstr ""
-#: awx/main/models/credential/__init__.py:1100
+#: awx/main/models/credential/__init__.py:1108
msgid "Ansible Tower Hostname"
msgstr ""
-#: awx/main/models/credential/__init__.py:1102
+#: awx/main/models/credential/__init__.py:1110
msgid "The Ansible Tower base URL to authenticate with."
msgstr ""
-#: awx/main/models/credential/__init__.py:1134
+#: awx/main/models/credential/__init__.py:1115
+msgid ""
+"The Ansible Tower user to authenticate as.This should not be set if an OAuth "
+"token is being used."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1124
+msgid "OAuth Token"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1127
+msgid ""
+"An OAuth token to use to authenticate to Tower with.This should not be set "
+"if username/password are being used."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1152
msgid "OpenShift or Kubernetes API Bearer Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:1138
+#: awx/main/models/credential/__init__.py:1156
msgid "OpenShift or Kubernetes API Endpoint"
msgstr ""
-#: awx/main/models/credential/__init__.py:1140
+#: awx/main/models/credential/__init__.py:1158
msgid "The OpenShift or Kubernetes API Endpoint to authenticate with."
msgstr ""
-#: awx/main/models/credential/__init__.py:1143
+#: awx/main/models/credential/__init__.py:1161
msgid "API authentication bearer token"
msgstr ""
-#: awx/main/models/credential/__init__.py:1153
+#: awx/main/models/credential/__init__.py:1171
msgid "Certificate Authority data"
msgstr ""
-#: awx/main/models/credential/__init__.py:1194
+#: awx/main/models/credential/__init__.py:1184
+msgid "Ansible Galaxy/Automation Hub API Token"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1188
+msgid "Galaxy Server URL"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1190
+msgid "The URL of the Galaxy instance to connect to."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1193
+msgid "Auth Server URL"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1196
+msgid "The URL of a Keycloak server token_endpoint, if using SSO auth."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1201
+msgid "API Token"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1205
+msgid "A token to use for authentication against the Galaxy instance."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1244
msgid "Target must be a non-external credential"
msgstr ""
-#: awx/main/models/credential/__init__.py:1199
+#: awx/main/models/credential/__init__.py:1249
msgid "Source must be an external credential"
msgstr ""
-#: awx/main/models/credential/__init__.py:1206
+#: awx/main/models/credential/__init__.py:1256
msgid "Input field must be defined on target credential (options are {})."
msgstr ""
-#: awx/main/models/events.py:152 awx/main/models/events.py:674
+#: awx/main/models/events.py:165 awx/main/models/events.py:707
msgid "Host Failed"
msgstr ""
-#: awx/main/models/events.py:153
+#: awx/main/models/events.py:166
msgid "Host Started"
msgstr ""
-#: awx/main/models/events.py:154 awx/main/models/events.py:675
+#: awx/main/models/events.py:167 awx/main/models/events.py:708
msgid "Host OK"
msgstr ""
-#: awx/main/models/events.py:155
+#: awx/main/models/events.py:168
msgid "Host Failure"
msgstr ""
-#: awx/main/models/events.py:156 awx/main/models/events.py:681
+#: awx/main/models/events.py:169 awx/main/models/events.py:714
msgid "Host Skipped"
msgstr ""
-#: awx/main/models/events.py:157 awx/main/models/events.py:676
+#: awx/main/models/events.py:170 awx/main/models/events.py:709
msgid "Host Unreachable"
msgstr ""
-#: awx/main/models/events.py:158 awx/main/models/events.py:172
+#: awx/main/models/events.py:171 awx/main/models/events.py:185
msgid "No Hosts Remaining"
msgstr ""
-#: awx/main/models/events.py:159
+#: awx/main/models/events.py:172
msgid "Host Polling"
msgstr ""
-#: awx/main/models/events.py:160
+#: awx/main/models/events.py:173
msgid "Host Async OK"
msgstr ""
-#: awx/main/models/events.py:161
+#: awx/main/models/events.py:174
msgid "Host Async Failure"
msgstr ""
-#: awx/main/models/events.py:162
+#: awx/main/models/events.py:175
msgid "Item OK"
msgstr ""
-#: awx/main/models/events.py:163
+#: awx/main/models/events.py:176
msgid "Item Failed"
msgstr ""
-#: awx/main/models/events.py:164
+#: awx/main/models/events.py:177
msgid "Item Skipped"
msgstr ""
-#: awx/main/models/events.py:165
+#: awx/main/models/events.py:178
msgid "Host Retry"
msgstr ""
-#: awx/main/models/events.py:167
+#: awx/main/models/events.py:180
msgid "File Difference"
msgstr ""
-#: awx/main/models/events.py:168
+#: awx/main/models/events.py:181
msgid "Playbook Started"
msgstr ""
-#: awx/main/models/events.py:169
+#: awx/main/models/events.py:182
msgid "Running Handlers"
msgstr ""
-#: awx/main/models/events.py:170
+#: awx/main/models/events.py:183
msgid "Including File"
msgstr ""
-#: awx/main/models/events.py:171
+#: awx/main/models/events.py:184
msgid "No Hosts Matched"
msgstr ""
-#: awx/main/models/events.py:173
+#: awx/main/models/events.py:186
msgid "Task Started"
msgstr ""
-#: awx/main/models/events.py:175
+#: awx/main/models/events.py:188
msgid "Variables Prompted"
msgstr ""
-#: awx/main/models/events.py:176
+#: awx/main/models/events.py:189
msgid "Gathering Facts"
msgstr ""
-#: awx/main/models/events.py:177
+#: awx/main/models/events.py:190
msgid "internal: on Import for Host"
msgstr ""
-#: awx/main/models/events.py:178
+#: awx/main/models/events.py:191
msgid "internal: on Not Import for Host"
msgstr ""
-#: awx/main/models/events.py:179
+#: awx/main/models/events.py:192
msgid "Play Started"
msgstr ""
-#: awx/main/models/events.py:180
+#: awx/main/models/events.py:193
msgid "Playbook Complete"
msgstr ""
-#: awx/main/models/events.py:184 awx/main/models/events.py:691
+#: awx/main/models/events.py:197 awx/main/models/events.py:724
msgid "Debug"
msgstr ""
-#: awx/main/models/events.py:185 awx/main/models/events.py:692
+#: awx/main/models/events.py:198 awx/main/models/events.py:725
msgid "Verbose"
msgstr ""
-#: awx/main/models/events.py:186 awx/main/models/events.py:693
+#: awx/main/models/events.py:199 awx/main/models/events.py:726
msgid "Deprecated"
msgstr ""
-#: awx/main/models/events.py:187 awx/main/models/events.py:694
+#: awx/main/models/events.py:200 awx/main/models/events.py:727
msgid "Warning"
msgstr ""
-#: awx/main/models/events.py:188 awx/main/models/events.py:695
+#: awx/main/models/events.py:201 awx/main/models/events.py:728
msgid "System Warning"
msgstr ""
-#: awx/main/models/events.py:189 awx/main/models/events.py:696
+#: awx/main/models/events.py:202 awx/main/models/events.py:729
#: awx/main/models/unified_jobs.py:75
msgid "Error"
msgstr ""
-#: awx/main/models/ha.py:175
+#: awx/main/models/ha.py:184
msgid "Instances that are members of this InstanceGroup"
msgstr ""
-#: awx/main/models/ha.py:180
+#: awx/main/models/ha.py:189
msgid "Instance Group to remotely control this group."
msgstr ""
-#: awx/main/models/ha.py:200
+#: awx/main/models/ha.py:209
msgid "Percentage of Instances to automatically assign to this group"
msgstr ""
-#: awx/main/models/ha.py:204
+#: awx/main/models/ha.py:213
msgid ""
"Static minimum number of Instances to automatically assign to this group"
msgstr ""
-#: awx/main/models/ha.py:209
+#: awx/main/models/ha.py:218
msgid ""
"List of exact-match Instances that will always be automatically assigned to "
"this group"
msgstr ""
-#: awx/main/models/inventory.py:80
+#: awx/main/models/inventory.py:74
msgid "Hosts have a direct link to this inventory."
msgstr ""
-#: awx/main/models/inventory.py:81
+#: awx/main/models/inventory.py:75
msgid "Hosts for inventory generated using the host_filter property."
msgstr ""
-#: awx/main/models/inventory.py:86
+#: awx/main/models/inventory.py:80
msgid "inventories"
msgstr ""
-#: awx/main/models/inventory.py:93
+#: awx/main/models/inventory.py:87
msgid "Organization containing this inventory."
msgstr ""
-#: awx/main/models/inventory.py:100
+#: awx/main/models/inventory.py:94
msgid "Inventory variables in JSON or YAML format."
msgstr ""
-#: awx/main/models/inventory.py:105
+#: awx/main/models/inventory.py:99
msgid ""
"This field is deprecated and will be removed in a future release. Flag "
"indicating whether any hosts in this inventory have failed."
msgstr ""
-#: awx/main/models/inventory.py:111
+#: awx/main/models/inventory.py:105
msgid ""
"This field is deprecated and will be removed in a future release. Total "
"number of hosts in this inventory."
msgstr ""
-#: awx/main/models/inventory.py:117
+#: awx/main/models/inventory.py:111
msgid ""
"This field is deprecated and will be removed in a future release. Number of "
"hosts in this inventory with active failures."
msgstr ""
-#: awx/main/models/inventory.py:123
+#: awx/main/models/inventory.py:117
msgid ""
"This field is deprecated and will be removed in a future release. Total "
"number of groups in this inventory."
msgstr ""
-#: awx/main/models/inventory.py:129
+#: awx/main/models/inventory.py:123
msgid ""
"This field is deprecated and will be removed in a future release. Flag "
"indicating whether this inventory has any external inventory sources."
msgstr ""
-#: awx/main/models/inventory.py:135
+#: awx/main/models/inventory.py:129
msgid ""
"Total number of external inventory sources configured within this inventory."
msgstr ""
-#: awx/main/models/inventory.py:140
+#: awx/main/models/inventory.py:134
msgid "Number of external inventory sources in this inventory with failures."
msgstr ""
-#: awx/main/models/inventory.py:147
+#: awx/main/models/inventory.py:141
msgid "Kind of inventory being represented."
msgstr ""
-#: awx/main/models/inventory.py:153
+#: awx/main/models/inventory.py:147
msgid "Filter that will be applied to the hosts of this inventory."
msgstr ""
-#: awx/main/models/inventory.py:181
+#: awx/main/models/inventory.py:175
msgid ""
"Credentials to be used by hosts belonging to this inventory when accessing "
"Red Hat Insights API."
msgstr ""
-#: awx/main/models/inventory.py:190
+#: awx/main/models/inventory.py:184
msgid "Flag indicating the inventory is being deleted."
msgstr ""
-#: awx/main/models/inventory.py:245
+#: awx/main/models/inventory.py:239
msgid "Could not parse subset as slice specification."
msgstr ""
-#: awx/main/models/inventory.py:249
+#: awx/main/models/inventory.py:243
msgid "Slice number must be less than total number of slices."
msgstr ""
-#: awx/main/models/inventory.py:251
+#: awx/main/models/inventory.py:245
msgid "Slice number must be 1 or higher."
msgstr ""
-#: awx/main/models/inventory.py:388
+#: awx/main/models/inventory.py:382
msgid "Assignment not allowed for Smart Inventory"
msgstr ""
-#: awx/main/models/inventory.py:390 awx/main/models/projects.py:166
+#: awx/main/models/inventory.py:384 awx/main/models/projects.py:167
msgid "Credential kind must be 'insights'."
msgstr ""
-#: awx/main/models/inventory.py:475
+#: awx/main/models/inventory.py:469
msgid "Is this host online and available for running jobs?"
msgstr ""
-#: awx/main/models/inventory.py:481
+#: awx/main/models/inventory.py:475
msgid ""
"The value used by the remote inventory source to uniquely identify the host"
msgstr ""
-#: awx/main/models/inventory.py:486
+#: awx/main/models/inventory.py:480
msgid "Host variables in JSON or YAML format."
msgstr ""
-#: awx/main/models/inventory.py:509
+#: awx/main/models/inventory.py:503
msgid "Inventory source(s) that created or modified this host."
msgstr ""
-#: awx/main/models/inventory.py:514
+#: awx/main/models/inventory.py:508
msgid "Arbitrary JSON structure of most recent ansible_facts, per-host."
msgstr ""
-#: awx/main/models/inventory.py:520
+#: awx/main/models/inventory.py:514
msgid "The date and time ansible_facts was last modified."
msgstr ""
-#: awx/main/models/inventory.py:527
+#: awx/main/models/inventory.py:521
msgid "Red Hat Insights host unique identifier."
msgstr ""
-#: awx/main/models/inventory.py:641
+#: awx/main/models/inventory.py:635
msgid "Group variables in JSON or YAML format."
msgstr ""
-#: awx/main/models/inventory.py:647
+#: awx/main/models/inventory.py:641
msgid "Hosts associated directly with this group."
msgstr ""
-#: awx/main/models/inventory.py:653
+#: awx/main/models/inventory.py:647
msgid "Inventory source(s) that created or modified this group."
msgstr ""
-#: awx/main/models/inventory.py:825
+#: awx/main/models/inventory.py:819
msgid "File, Directory or Script"
msgstr ""
-#: awx/main/models/inventory.py:826
+#: awx/main/models/inventory.py:820
msgid "Sourced from a Project"
msgstr ""
-#: awx/main/models/inventory.py:827
+#: awx/main/models/inventory.py:821
msgid "Amazon EC2"
msgstr ""
-#: awx/main/models/inventory.py:836
+#: awx/main/models/inventory.py:829
msgid "Custom Script"
msgstr ""
-#: awx/main/models/inventory.py:953
+#: awx/main/models/inventory.py:863
msgid "Inventory source variables in YAML or JSON format."
msgstr ""
-#: awx/main/models/inventory.py:964
+#: awx/main/models/inventory.py:868
msgid ""
-"Comma-separated list of filter expressions (EC2 only). Hosts are imported "
-"when ANY of the filters match."
+"Retrieve the enabled state from the given dict of host variables. The "
+"enabled variable may be specified as \"foo.bar\", in which case the lookup "
+"will traverse into nested dicts, equivalent to: from_dict.get(\"foo\", {})."
+"get(\"bar\", default)"
msgstr ""
-#: awx/main/models/inventory.py:970
-msgid "Limit groups automatically created from inventory source (EC2 only)."
+#: awx/main/models/inventory.py:876
+msgid ""
+"Only used when enabled_var is set. Value when the host is considered "
+"enabled. For example if enabled_var=\"status.power_state\"and enabled_value="
+"\"powered_on\" with host variables:{ \"status\": { \"power_state\": "
+"\"powered_on\", \"created\": \"2020-08-04T18:13:04+00:00\", \"healthy"
+"\": true }, \"name\": \"foobar\", \"ip_address\": \"192.168.2.1\"}"
+"The host would be marked enabled. If power_state where any value other than "
+"powered_on then the host would be disabled when imported into Tower. If the "
+"key is not found then the host will be enabled"
msgstr ""
-#: awx/main/models/inventory.py:974
+#: awx/main/models/inventory.py:896
+msgid "Regex where only matching hosts will be imported into Tower."
+msgstr ""
+
+#: awx/main/models/inventory.py:900
msgid "Overwrite local groups and hosts from remote inventory source."
msgstr ""
-#: awx/main/models/inventory.py:978
+#: awx/main/models/inventory.py:904
msgid "Overwrite local variables from remote inventory source."
msgstr ""
-#: awx/main/models/inventory.py:983 awx/main/models/jobs.py:154
-#: awx/main/models/projects.py:135
+#: awx/main/models/inventory.py:909 awx/main/models/jobs.py:154
+#: awx/main/models/projects.py:136
msgid "The amount of time (in seconds) to run before the task is canceled."
msgstr ""
-#: awx/main/models/inventory.py:1016
-msgid "Image ID"
-msgstr ""
-
-#: awx/main/models/inventory.py:1017
-msgid "Availability Zone"
-msgstr ""
-
-#: awx/main/models/inventory.py:1019
-msgid "Instance ID"
-msgstr ""
-
-#: awx/main/models/inventory.py:1020
-msgid "Instance State"
-msgstr ""
-
-#: awx/main/models/inventory.py:1021
-msgid "Platform"
-msgstr ""
-
-#: awx/main/models/inventory.py:1022
-msgid "Instance Type"
-msgstr ""
-
-#: awx/main/models/inventory.py:1024
-msgid "Region"
-msgstr ""
-
-#: awx/main/models/inventory.py:1025
-msgid "Security Group"
-msgstr ""
-
-#: awx/main/models/inventory.py:1026
-msgid "Tags"
-msgstr ""
-
-#: awx/main/models/inventory.py:1027
-msgid "Tag None"
-msgstr ""
-
-#: awx/main/models/inventory.py:1028
-msgid "VPC ID"
-msgstr ""
-
-#: awx/main/models/inventory.py:1096
+#: awx/main/models/inventory.py:926
#, python-format
msgid ""
"Cloud-based inventory sources (such as %s) require credentials for the "
"matching cloud service."
msgstr ""
-#: awx/main/models/inventory.py:1102
+#: awx/main/models/inventory.py:932
msgid "Credential is required for a cloud source."
msgstr ""
-#: awx/main/models/inventory.py:1105
+#: awx/main/models/inventory.py:935
msgid ""
"Credentials of type machine, source control, insights and vault are "
"disallowed for custom inventory sources."
msgstr ""
-#: awx/main/models/inventory.py:1110
+#: awx/main/models/inventory.py:940
msgid ""
"Credentials of type insights and vault are disallowed for scm inventory "
"sources."
msgstr ""
-#: awx/main/models/inventory.py:1170
-#, python-format
-msgid "Invalid %(source)s region: %(region)s"
-msgstr ""
-
-#: awx/main/models/inventory.py:1194
-#, python-format
-msgid "Invalid filter expression: %(filter)s"
-msgstr ""
-
-#: awx/main/models/inventory.py:1215
-#, python-format
-msgid "Invalid group by choice: %(choice)s"
-msgstr ""
-
-#: awx/main/models/inventory.py:1243
+#: awx/main/models/inventory.py:1004
msgid "Project containing inventory file used as source."
msgstr ""
-#: awx/main/models/inventory.py:1416
+#: awx/main/models/inventory.py:1177
msgid ""
"More than one SCM-based inventory source with update on project update per-"
"inventory not allowed."
msgstr ""
-#: awx/main/models/inventory.py:1423
+#: awx/main/models/inventory.py:1184
msgid ""
"Cannot update SCM-based inventory source on launch if set to update on "
"project update. Instead, configure the corresponding source project to "
"update on launch."
msgstr ""
-#: awx/main/models/inventory.py:1429
+#: awx/main/models/inventory.py:1190
msgid "Cannot set source_path if not SCM type."
msgstr ""
-#: awx/main/models/inventory.py:1472
+#: awx/main/models/inventory.py:1233
msgid ""
"Inventory files from this Project Update were used for the inventory update."
msgstr ""
-#: awx/main/models/inventory.py:1583
+#: awx/main/models/inventory.py:1344
msgid "Inventory script contents"
msgstr ""
-#: awx/main/models/inventory.py:1588
+#: awx/main/models/inventory.py:1349
msgid "Organization owning this inventory script"
msgstr ""
@@ -3980,8 +4030,8 @@ msgstr ""
msgid "Job Template {} is missing or undefined."
msgstr ""
-#: awx/main/models/jobs.py:570 awx/main/models/projects.py:278
-#: awx/main/models/projects.py:497
+#: awx/main/models/jobs.py:570 awx/main/models/projects.py:284
+#: awx/main/models/projects.py:508
msgid "SCM Revision"
msgstr ""
@@ -4081,63 +4131,59 @@ msgstr ""
msgid "Unique identifier of the event that triggered this webhook"
msgstr ""
-#: awx/main/models/notifications.py:42
+#: awx/main/models/notifications.py:41
msgid "Email"
msgstr ""
-#: awx/main/models/notifications.py:43
+#: awx/main/models/notifications.py:42
msgid "Slack"
msgstr ""
-#: awx/main/models/notifications.py:44
+#: awx/main/models/notifications.py:43
msgid "Twilio"
msgstr ""
-#: awx/main/models/notifications.py:45
+#: awx/main/models/notifications.py:44
msgid "Pagerduty"
msgstr ""
-#: awx/main/models/notifications.py:46
+#: awx/main/models/notifications.py:45
msgid "Grafana"
msgstr ""
-#: awx/main/models/notifications.py:47
-msgid "HipChat"
-msgstr ""
-
-#: awx/main/models/notifications.py:48 awx/main/models/unified_jobs.py:544
+#: awx/main/models/notifications.py:46 awx/main/models/unified_jobs.py:544
msgid "Webhook"
msgstr ""
-#: awx/main/models/notifications.py:49
+#: awx/main/models/notifications.py:47
msgid "Mattermost"
msgstr ""
-#: awx/main/models/notifications.py:50
+#: awx/main/models/notifications.py:48
msgid "Rocket.Chat"
msgstr ""
-#: awx/main/models/notifications.py:51
+#: awx/main/models/notifications.py:49
msgid "IRC"
msgstr ""
-#: awx/main/models/notifications.py:82
+#: awx/main/models/notifications.py:80
msgid "Optional custom messages for notification template."
msgstr ""
-#: awx/main/models/notifications.py:212 awx/main/models/unified_jobs.py:70
+#: awx/main/models/notifications.py:210 awx/main/models/unified_jobs.py:70
msgid "Pending"
msgstr ""
-#: awx/main/models/notifications.py:213 awx/main/models/unified_jobs.py:73
+#: awx/main/models/notifications.py:211 awx/main/models/unified_jobs.py:73
msgid "Successful"
msgstr ""
-#: awx/main/models/notifications.py:214 awx/main/models/unified_jobs.py:74
+#: awx/main/models/notifications.py:212 awx/main/models/unified_jobs.py:74
msgid "Failed"
msgstr ""
-#: awx/main/models/notifications.py:467
+#: awx/main/models/notifications.py:470
msgid "status must be either running, succeeded or failed"
msgstr ""
@@ -4206,7 +4252,7 @@ msgid ""
"authentication provider ({})"
msgstr ""
-#: awx/main/models/organization.py:51
+#: awx/main/models/organization.py:57
msgid "Maximum number of hosts allowed to be managed by this organization."
msgstr ""
@@ -4230,118 +4276,122 @@ msgstr ""
msgid "Red Hat Insights"
msgstr ""
-#: awx/main/models/projects.py:83
+#: awx/main/models/projects.py:58
+msgid "Remote Archive"
+msgstr ""
+
+#: awx/main/models/projects.py:84
msgid ""
"Local path (relative to PROJECTS_ROOT) containing playbooks and related "
"files for this project."
msgstr ""
-#: awx/main/models/projects.py:92
+#: awx/main/models/projects.py:93
msgid "SCM Type"
msgstr ""
-#: awx/main/models/projects.py:93
+#: awx/main/models/projects.py:94
msgid "Specifies the source control system used to store the project."
msgstr ""
-#: awx/main/models/projects.py:99
+#: awx/main/models/projects.py:100
msgid "SCM URL"
msgstr ""
-#: awx/main/models/projects.py:100
+#: awx/main/models/projects.py:101
msgid "The location where the project is stored."
msgstr ""
-#: awx/main/models/projects.py:106
+#: awx/main/models/projects.py:107
msgid "SCM Branch"
msgstr ""
-#: awx/main/models/projects.py:107
+#: awx/main/models/projects.py:108
msgid "Specific branch, tag or commit to checkout."
msgstr ""
-#: awx/main/models/projects.py:113
+#: awx/main/models/projects.py:114
msgid "SCM refspec"
msgstr ""
-#: awx/main/models/projects.py:114
+#: awx/main/models/projects.py:115
msgid "For git projects, an additional refspec to fetch."
msgstr ""
-#: awx/main/models/projects.py:118
+#: awx/main/models/projects.py:119
msgid "Discard any local changes before syncing the project."
msgstr ""
-#: awx/main/models/projects.py:122
+#: awx/main/models/projects.py:123
msgid "Delete the project before syncing."
msgstr ""
-#: awx/main/models/projects.py:151
+#: awx/main/models/projects.py:152
msgid "Invalid SCM URL."
msgstr ""
-#: awx/main/models/projects.py:154
+#: awx/main/models/projects.py:155
msgid "SCM URL is required."
msgstr ""
-#: awx/main/models/projects.py:162
+#: awx/main/models/projects.py:163
msgid "Insights Credential is required for an Insights Project."
msgstr ""
-#: awx/main/models/projects.py:168
+#: awx/main/models/projects.py:169
msgid "Credential kind must be 'scm'."
msgstr ""
-#: awx/main/models/projects.py:185
+#: awx/main/models/projects.py:186
msgid "Invalid credential."
msgstr ""
-#: awx/main/models/projects.py:259
+#: awx/main/models/projects.py:265
msgid "Update the project when a job is launched that uses the project."
msgstr ""
-#: awx/main/models/projects.py:264
+#: awx/main/models/projects.py:270
msgid ""
"The number of seconds after the last project update ran that a new project "
"update will be launched as a job dependency."
msgstr ""
-#: awx/main/models/projects.py:269
+#: awx/main/models/projects.py:275
msgid ""
"Allow changing the SCM branch or revision in a job template that uses this "
"project."
msgstr ""
-#: awx/main/models/projects.py:279
+#: awx/main/models/projects.py:285
msgid "The last revision fetched by a project update"
msgstr ""
-#: awx/main/models/projects.py:286
+#: awx/main/models/projects.py:292
msgid "Playbook Files"
msgstr ""
-#: awx/main/models/projects.py:287
+#: awx/main/models/projects.py:293
msgid "List of playbooks found in the project"
msgstr ""
-#: awx/main/models/projects.py:294
+#: awx/main/models/projects.py:300
msgid "Inventory Files"
msgstr ""
-#: awx/main/models/projects.py:295
+#: awx/main/models/projects.py:301
msgid ""
"Suggested list of content that could be Ansible inventory in the project"
msgstr ""
-#: awx/main/models/projects.py:332
+#: awx/main/models/projects.py:338
msgid "Organization cannot be changed when in use by job templates."
msgstr ""
-#: awx/main/models/projects.py:490
+#: awx/main/models/projects.py:501
msgid "Parts of the project update playbook that will be run."
msgstr ""
-#: awx/main/models/projects.py:498
+#: awx/main/models/projects.py:509
msgid ""
"The SCM Revision discovered by this update for the given project and branch."
msgstr ""
@@ -4697,41 +4747,33 @@ msgid ""
"Shows when an approval node (with a timeout assigned to it) has timed out."
msgstr ""
-#: awx/main/notifications/grafana_backend.py:86
+#: awx/main/notifications/grafana_backend.py:81
msgid "Error converting time {} or timeEnd {} to int."
msgstr ""
-#: awx/main/notifications/grafana_backend.py:88
+#: awx/main/notifications/grafana_backend.py:83
msgid "Error converting time {} and/or timeEnd {} to int."
msgstr ""
-#: awx/main/notifications/grafana_backend.py:102
-#: awx/main/notifications/grafana_backend.py:104
+#: awx/main/notifications/grafana_backend.py:97
+#: awx/main/notifications/grafana_backend.py:99
msgid "Error sending notification grafana: {}"
msgstr ""
-#: awx/main/notifications/hipchat_backend.py:50
-msgid "Error sending messages: {}"
-msgstr ""
-
-#: awx/main/notifications/hipchat_backend.py:52
-msgid "Error sending message to hipchat: {}"
-msgstr ""
-
#: awx/main/notifications/irc_backend.py:56
msgid "Exception connecting to irc server: {}"
msgstr ""
-#: awx/main/notifications/mattermost_backend.py:50
-#: awx/main/notifications/mattermost_backend.py:52
+#: awx/main/notifications/mattermost_backend.py:49
+#: awx/main/notifications/mattermost_backend.py:51
msgid "Error sending notification mattermost: {}"
msgstr ""
-#: awx/main/notifications/pagerduty_backend.py:64
+#: awx/main/notifications/pagerduty_backend.py:75
msgid "Exception connecting to PagerDuty: {}"
msgstr ""
-#: awx/main/notifications/pagerduty_backend.py:73
+#: awx/main/notifications/pagerduty_backend.py:84
#: awx/main/notifications/slack_backend.py:58
#: awx/main/notifications/twilio_backend.py:48
msgid "Exception sending messages: {}"
@@ -4758,46 +4800,52 @@ msgid ""
"job node(s) missing unified job template and error handling path [{no_ufjt}]."
msgstr ""
-#: awx/main/scheduler/task_manager.py:118
+#: awx/main/scheduler/task_manager.py:127
msgid ""
"Workflow Job spawned from workflow could not start because it would result "
"in recursion (spawn order, most recent first: {})"
msgstr ""
-#: awx/main/scheduler/task_manager.py:126
+#: awx/main/scheduler/task_manager.py:135
msgid ""
"Job spawned from workflow could not start because it was missing a related "
"resource such as project or inventory"
msgstr ""
-#: awx/main/scheduler/task_manager.py:135
+#: awx/main/scheduler/task_manager.py:144
msgid ""
"Job spawned from workflow could not start because it was not in the right "
"state or required manual credentials"
msgstr ""
-#: awx/main/scheduler/task_manager.py:176
+#: awx/main/scheduler/task_manager.py:185
msgid "No error handling paths found, marking workflow as failed"
msgstr ""
-#: awx/main/scheduler/task_manager.py:508
+#: awx/main/scheduler/task_manager.py:523
#, python-brace-format
msgid "The approval node {name} ({pk}) has expired after {timeout} seconds."
msgstr ""
-#: awx/main/tasks.py:1046
+#: awx/main/tasks.py:599
+msgid ""
+"Scheduled job could not start because it was not in the "
+"right state or required manual credentials"
+msgstr ""
+
+#: awx/main/tasks.py:1070
msgid "Invalid virtual environment selected: {}"
msgstr ""
-#: awx/main/tasks.py:1849
+#: awx/main/tasks.py:1857
msgid "Job could not start because it does not have a valid inventory."
msgstr ""
-#: awx/main/tasks.py:1853
+#: awx/main/tasks.py:1861
msgid "Job could not start because it does not have a valid project."
msgstr ""
-#: awx/main/tasks.py:1858
+#: awx/main/tasks.py:1866
msgid ""
"The project revision for this job template is unknown due to a failed update."
msgstr ""
@@ -4822,53 +4870,53 @@ msgstr ""
msgid "Unable to convert \"%s\" to boolean"
msgstr ""
-#: awx/main/utils/common.py:261
+#: awx/main/utils/common.py:248
#, python-format
msgid "Unsupported SCM type \"%s\""
msgstr ""
-#: awx/main/utils/common.py:268 awx/main/utils/common.py:280
-#: awx/main/utils/common.py:299
+#: awx/main/utils/common.py:255 awx/main/utils/common.py:267
+#: awx/main/utils/common.py:286
#, python-format
msgid "Invalid %s URL"
msgstr ""
-#: awx/main/utils/common.py:270 awx/main/utils/common.py:309
+#: awx/main/utils/common.py:257 awx/main/utils/common.py:297
#, python-format
msgid "Unsupported %s URL"
msgstr ""
-#: awx/main/utils/common.py:311
+#: awx/main/utils/common.py:299
#, python-format
msgid "Unsupported host \"%s\" for file:// URL"
msgstr ""
-#: awx/main/utils/common.py:313
+#: awx/main/utils/common.py:301
#, python-format
msgid "Host is required for %s URL"
msgstr ""
-#: awx/main/utils/common.py:331
+#: awx/main/utils/common.py:319
#, python-format
msgid "Username must be \"git\" for SSH access to %s."
msgstr ""
-#: awx/main/utils/common.py:337
+#: awx/main/utils/common.py:325
#, python-format
msgid "Username must be \"hg\" for SSH access to %s."
msgstr ""
-#: awx/main/utils/common.py:668
+#: awx/main/utils/common.py:656
#, python-brace-format
msgid "Input type `{data_type}` is not a dictionary"
msgstr ""
-#: awx/main/utils/common.py:701
+#: awx/main/utils/common.py:689
#, python-brace-format
msgid "Variables not compatible with JSON standard (error: {json_error})"
msgstr ""
-#: awx/main/utils/common.py:707
+#: awx/main/utils/common.py:695
#, python-brace-format
msgid ""
"Cannot parse as JSON (error: {json_error}) or YAML (error: {yaml_error})."
@@ -4980,290 +5028,6 @@ msgstr ""
msgid "A server error has occurred."
msgstr ""
-#: awx/settings/defaults.py:683
-msgid "US East (Northern Virginia)"
-msgstr ""
-
-#: awx/settings/defaults.py:684
-msgid "US East (Ohio)"
-msgstr ""
-
-#: awx/settings/defaults.py:685
-msgid "US West (Oregon)"
-msgstr ""
-
-#: awx/settings/defaults.py:686
-msgid "US West (Northern California)"
-msgstr ""
-
-#: awx/settings/defaults.py:687
-msgid "Canada (Central)"
-msgstr ""
-
-#: awx/settings/defaults.py:688
-msgid "EU (Frankfurt)"
-msgstr ""
-
-#: awx/settings/defaults.py:689
-msgid "EU (Ireland)"
-msgstr ""
-
-#: awx/settings/defaults.py:690
-msgid "EU (London)"
-msgstr ""
-
-#: awx/settings/defaults.py:691
-msgid "Asia Pacific (Singapore)"
-msgstr ""
-
-#: awx/settings/defaults.py:692
-msgid "Asia Pacific (Sydney)"
-msgstr ""
-
-#: awx/settings/defaults.py:693
-msgid "Asia Pacific (Tokyo)"
-msgstr ""
-
-#: awx/settings/defaults.py:694
-msgid "Asia Pacific (Seoul)"
-msgstr ""
-
-#: awx/settings/defaults.py:695
-msgid "Asia Pacific (Mumbai)"
-msgstr ""
-
-#: awx/settings/defaults.py:696
-msgid "South America (Sao Paulo)"
-msgstr ""
-
-#: awx/settings/defaults.py:697
-msgid "US West (GovCloud)"
-msgstr ""
-
-#: awx/settings/defaults.py:698
-msgid "China (Beijing)"
-msgstr ""
-
-#: awx/settings/defaults.py:747
-msgid "US East 1 (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:748
-msgid "US East 1 (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:749
-msgid "US East 1 (D)"
-msgstr ""
-
-#: awx/settings/defaults.py:750
-msgid "US East 4 (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:751
-msgid "US East 4 (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:752
-msgid "US East 4 (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:753
-msgid "US Central (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:754
-msgid "US Central (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:755
-msgid "US Central (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:756
-msgid "US Central (F)"
-msgstr ""
-
-#: awx/settings/defaults.py:757
-msgid "US West (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:758
-msgid "US West (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:759
-msgid "US West (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:760
-msgid "Europe West 1 (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:761
-msgid "Europe West 1 (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:762
-msgid "Europe West 1 (D)"
-msgstr ""
-
-#: awx/settings/defaults.py:763
-msgid "Europe West 2 (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:764
-msgid "Europe West 2 (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:765
-msgid "Europe West 2 (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:766
-msgid "Asia East (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:767
-msgid "Asia East (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:768
-msgid "Asia East (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:769
-msgid "Asia Southeast (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:770
-msgid "Asia Southeast (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:771
-msgid "Asia Northeast (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:772
-msgid "Asia Northeast (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:773
-msgid "Asia Northeast (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:774
-msgid "Australia Southeast (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:775
-msgid "Australia Southeast (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:776
-msgid "Australia Southeast (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:798
-msgid "US East"
-msgstr ""
-
-#: awx/settings/defaults.py:799
-msgid "US East 2"
-msgstr ""
-
-#: awx/settings/defaults.py:800
-msgid "US Central"
-msgstr ""
-
-#: awx/settings/defaults.py:801
-msgid "US North Central"
-msgstr ""
-
-#: awx/settings/defaults.py:802
-msgid "US South Central"
-msgstr ""
-
-#: awx/settings/defaults.py:803
-msgid "US West Central"
-msgstr ""
-
-#: awx/settings/defaults.py:804
-msgid "US West"
-msgstr ""
-
-#: awx/settings/defaults.py:805
-msgid "US West 2"
-msgstr ""
-
-#: awx/settings/defaults.py:806
-msgid "Canada East"
-msgstr ""
-
-#: awx/settings/defaults.py:807
-msgid "Canada Central"
-msgstr ""
-
-#: awx/settings/defaults.py:808
-msgid "Brazil South"
-msgstr ""
-
-#: awx/settings/defaults.py:809
-msgid "Europe North"
-msgstr ""
-
-#: awx/settings/defaults.py:810
-msgid "Europe West"
-msgstr ""
-
-#: awx/settings/defaults.py:811
-msgid "UK West"
-msgstr ""
-
-#: awx/settings/defaults.py:812
-msgid "UK South"
-msgstr ""
-
-#: awx/settings/defaults.py:813
-msgid "Asia East"
-msgstr ""
-
-#: awx/settings/defaults.py:814
-msgid "Asia Southeast"
-msgstr ""
-
-#: awx/settings/defaults.py:815
-msgid "Australia East"
-msgstr ""
-
-#: awx/settings/defaults.py:816
-msgid "Australia Southeast"
-msgstr ""
-
-#: awx/settings/defaults.py:817
-msgid "India West"
-msgstr ""
-
-#: awx/settings/defaults.py:818
-msgid "India South"
-msgstr ""
-
-#: awx/settings/defaults.py:819
-msgid "Japan East"
-msgstr ""
-
-#: awx/settings/defaults.py:820
-msgid "Japan West"
-msgstr ""
-
-#: awx/settings/defaults.py:821
-msgid "Korea Central"
-msgstr ""
-
-#: awx/settings/defaults.py:822
-msgid "Korea South"
-msgstr ""
-
#: awx/sso/apps.py:9
msgid "Single Sign-On"
msgstr ""
@@ -5536,7 +5300,7 @@ msgid "Hostname of TACACS+ server."
msgstr ""
#: awx/sso/conf.py:480 awx/sso/conf.py:492 awx/sso/conf.py:504
-#: awx/sso/conf.py:516 awx/sso/conf.py:527 awx/sso/models.py:15
+#: awx/sso/conf.py:516 awx/sso/conf.py:528 awx/sso/models.py:15
msgid "TACACS+"
msgstr ""
@@ -5564,159 +5328,159 @@ msgstr ""
msgid "TACACS+ session timeout value in seconds, 0 disables timeout."
msgstr ""
-#: awx/sso/conf.py:525
+#: awx/sso/conf.py:526
msgid "TACACS+ Authentication Protocol"
msgstr ""
-#: awx/sso/conf.py:526
+#: awx/sso/conf.py:527
msgid "Choose the authentication protocol used by TACACS+ client."
msgstr ""
-#: awx/sso/conf.py:540
+#: awx/sso/conf.py:541
msgid "Google OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:541 awx/sso/conf.py:634 awx/sso/conf.py:699
+#: awx/sso/conf.py:542 awx/sso/conf.py:635 awx/sso/conf.py:700
msgid ""
"Provide this URL as the callback URL for your application as part of your "
"registration process. Refer to the Ansible Tower documentation for more "
"detail."
msgstr ""
-#: awx/sso/conf.py:544 awx/sso/conf.py:556 awx/sso/conf.py:568
-#: awx/sso/conf.py:581 awx/sso/conf.py:595 awx/sso/conf.py:607
-#: awx/sso/conf.py:619
+#: awx/sso/conf.py:545 awx/sso/conf.py:557 awx/sso/conf.py:569
+#: awx/sso/conf.py:582 awx/sso/conf.py:596 awx/sso/conf.py:608
+#: awx/sso/conf.py:620
msgid "Google OAuth2"
msgstr ""
-#: awx/sso/conf.py:554
+#: awx/sso/conf.py:555
msgid "Google OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:555
+#: awx/sso/conf.py:556
msgid "The OAuth2 key from your web application."
msgstr ""
-#: awx/sso/conf.py:566
+#: awx/sso/conf.py:567
msgid "Google OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:567
+#: awx/sso/conf.py:568
msgid "The OAuth2 secret from your web application."
msgstr ""
-#: awx/sso/conf.py:578
-msgid "Google OAuth2 Whitelisted Domains"
+#: awx/sso/conf.py:579
+msgid "Google OAuth2 Allowed Domains"
msgstr ""
-#: awx/sso/conf.py:579
+#: awx/sso/conf.py:580
msgid ""
"Update this setting to restrict the domains who are allowed to login using "
"Google OAuth2."
msgstr ""
-#: awx/sso/conf.py:590
+#: awx/sso/conf.py:591
msgid "Google OAuth2 Extra Arguments"
msgstr ""
-#: awx/sso/conf.py:591
+#: awx/sso/conf.py:592
msgid ""
"Extra arguments for Google OAuth2 login. You can restrict it to only allow a "
"single domain to authenticate, even if the user is logged in with multple "
"Google accounts. Refer to the Ansible Tower documentation for more detail."
msgstr ""
-#: awx/sso/conf.py:605
+#: awx/sso/conf.py:606
msgid "Google OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:617
+#: awx/sso/conf.py:618
msgid "Google OAuth2 Team Map"
msgstr ""
-#: awx/sso/conf.py:633
+#: awx/sso/conf.py:634
msgid "GitHub OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:637 awx/sso/conf.py:649 awx/sso/conf.py:660
-#: awx/sso/conf.py:672 awx/sso/conf.py:684
+#: awx/sso/conf.py:638 awx/sso/conf.py:650 awx/sso/conf.py:661
+#: awx/sso/conf.py:673 awx/sso/conf.py:685
msgid "GitHub OAuth2"
msgstr ""
-#: awx/sso/conf.py:647
+#: awx/sso/conf.py:648
msgid "GitHub OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:648
+#: awx/sso/conf.py:649
msgid "The OAuth2 key (Client ID) from your GitHub developer application."
msgstr ""
-#: awx/sso/conf.py:658
+#: awx/sso/conf.py:659
msgid "GitHub OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:659
+#: awx/sso/conf.py:660
msgid ""
"The OAuth2 secret (Client Secret) from your GitHub developer application."
msgstr ""
-#: awx/sso/conf.py:670
+#: awx/sso/conf.py:671
msgid "GitHub OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:682
+#: awx/sso/conf.py:683
msgid "GitHub OAuth2 Team Map"
msgstr ""
-#: awx/sso/conf.py:698
+#: awx/sso/conf.py:699
msgid "GitHub Organization OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:702 awx/sso/conf.py:714 awx/sso/conf.py:725
-#: awx/sso/conf.py:738 awx/sso/conf.py:749 awx/sso/conf.py:761
+#: awx/sso/conf.py:703 awx/sso/conf.py:715 awx/sso/conf.py:726
+#: awx/sso/conf.py:739 awx/sso/conf.py:750 awx/sso/conf.py:762
msgid "GitHub Organization OAuth2"
msgstr ""
-#: awx/sso/conf.py:712
+#: awx/sso/conf.py:713
msgid "GitHub Organization OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:713 awx/sso/conf.py:791
+#: awx/sso/conf.py:714 awx/sso/conf.py:792
msgid "The OAuth2 key (Client ID) from your GitHub organization application."
msgstr ""
-#: awx/sso/conf.py:723
+#: awx/sso/conf.py:724
msgid "GitHub Organization OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:724 awx/sso/conf.py:802
+#: awx/sso/conf.py:725 awx/sso/conf.py:803
msgid ""
"The OAuth2 secret (Client Secret) from your GitHub organization application."
msgstr ""
-#: awx/sso/conf.py:735
+#: awx/sso/conf.py:736
msgid "GitHub Organization Name"
msgstr ""
-#: awx/sso/conf.py:736
+#: awx/sso/conf.py:737
msgid ""
"The name of your GitHub organization, as used in your organization's URL: "
"https://github.com//."
msgstr ""
-#: awx/sso/conf.py:747
+#: awx/sso/conf.py:748
msgid "GitHub Organization OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:759
+#: awx/sso/conf.py:760
msgid "GitHub Organization OAuth2 Team Map"
msgstr ""
-#: awx/sso/conf.py:775
+#: awx/sso/conf.py:776
msgid "GitHub Team OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:776
+#: awx/sso/conf.py:777
msgid ""
"Create an organization-owned application at https://github.com/organizations/"
"/settings/applications and obtain an OAuth2 key (Client ID) and "
@@ -5724,172 +5488,182 @@ msgid ""
"application."
msgstr ""
-#: awx/sso/conf.py:780 awx/sso/conf.py:792 awx/sso/conf.py:803
-#: awx/sso/conf.py:816 awx/sso/conf.py:827 awx/sso/conf.py:839
+#: awx/sso/conf.py:781 awx/sso/conf.py:793 awx/sso/conf.py:804
+#: awx/sso/conf.py:817 awx/sso/conf.py:828 awx/sso/conf.py:840
msgid "GitHub Team OAuth2"
msgstr ""
-#: awx/sso/conf.py:790
+#: awx/sso/conf.py:791
msgid "GitHub Team OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:801
+#: awx/sso/conf.py:802
msgid "GitHub Team OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:813
+#: awx/sso/conf.py:814
msgid "GitHub Team ID"
msgstr ""
-#: awx/sso/conf.py:814
+#: awx/sso/conf.py:815
msgid ""
"Find the numeric team ID using the Github API: http://fabian-kostadinov."
"github.io/2015/01/16/how-to-find-a-github-team-id/."
msgstr ""
-#: awx/sso/conf.py:825
+#: awx/sso/conf.py:826
msgid "GitHub Team OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:837
+#: awx/sso/conf.py:838
msgid "GitHub Team OAuth2 Team Map"
msgstr ""
-#: awx/sso/conf.py:853
+#: awx/sso/conf.py:854
msgid "Azure AD OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:854
+#: awx/sso/conf.py:855
msgid ""
"Provide this URL as the callback URL for your application as part of your "
"registration process. Refer to the Ansible Tower documentation for more "
"detail. "
msgstr ""
-#: awx/sso/conf.py:857 awx/sso/conf.py:869 awx/sso/conf.py:880
-#: awx/sso/conf.py:892 awx/sso/conf.py:904
+#: awx/sso/conf.py:858 awx/sso/conf.py:870 awx/sso/conf.py:881
+#: awx/sso/conf.py:893 awx/sso/conf.py:905
msgid "Azure AD OAuth2"
msgstr ""
-#: awx/sso/conf.py:867
+#: awx/sso/conf.py:868
msgid "Azure AD OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:868
+#: awx/sso/conf.py:869
msgid "The OAuth2 key (Client ID) from your Azure AD application."
msgstr ""
-#: awx/sso/conf.py:878
+#: awx/sso/conf.py:879
msgid "Azure AD OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:879
+#: awx/sso/conf.py:880
msgid "The OAuth2 secret (Client Secret) from your Azure AD application."
msgstr ""
-#: awx/sso/conf.py:890
+#: awx/sso/conf.py:891
msgid "Azure AD OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:902
+#: awx/sso/conf.py:903
msgid "Azure AD OAuth2 Team Map"
msgstr ""
#: awx/sso/conf.py:927
-msgid "SAML Assertion Consumer Service (ACS) URL"
+msgid "Automatically Create Organizations and Teams on SAML Login"
msgstr ""
#: awx/sso/conf.py:928
msgid ""
+"When enabled (the default), mapped Organizations and Teams will be created "
+"automatically on successful SAML login."
+msgstr ""
+
+#: awx/sso/conf.py:930 awx/sso/conf.py:943 awx/sso/conf.py:956
+#: awx/sso/conf.py:969 awx/sso/conf.py:983 awx/sso/conf.py:996
+#: awx/sso/conf.py:1008 awx/sso/conf.py:1028 awx/sso/conf.py:1045
+#: awx/sso/conf.py:1063 awx/sso/conf.py:1098 awx/sso/conf.py:1129
+#: awx/sso/conf.py:1142 awx/sso/conf.py:1158 awx/sso/conf.py:1170
+#: awx/sso/conf.py:1182 awx/sso/conf.py:1201 awx/sso/models.py:16
+msgid "SAML"
+msgstr ""
+
+#: awx/sso/conf.py:939
+msgid "SAML Assertion Consumer Service (ACS) URL"
+msgstr ""
+
+#: awx/sso/conf.py:940
+msgid ""
"Register Tower as a service provider (SP) with each identity provider (IdP) "
"you have configured. Provide your SP Entity ID and this ACS URL for your "
"application."
msgstr ""
-#: awx/sso/conf.py:931 awx/sso/conf.py:944 awx/sso/conf.py:957
-#: awx/sso/conf.py:971 awx/sso/conf.py:984 awx/sso/conf.py:996
-#: awx/sso/conf.py:1016 awx/sso/conf.py:1033 awx/sso/conf.py:1051
-#: awx/sso/conf.py:1086 awx/sso/conf.py:1117 awx/sso/conf.py:1130
-#: awx/sso/conf.py:1146 awx/sso/conf.py:1158 awx/sso/conf.py:1170
-#: awx/sso/conf.py:1189 awx/sso/models.py:16
-msgid "SAML"
-msgstr ""
-
-#: awx/sso/conf.py:941
+#: awx/sso/conf.py:953
msgid "SAML Service Provider Metadata URL"
msgstr ""
-#: awx/sso/conf.py:942
+#: awx/sso/conf.py:954
msgid ""
"If your identity provider (IdP) allows uploading an XML metadata file, you "
"can download one from this URL."
msgstr ""
-#: awx/sso/conf.py:953
+#: awx/sso/conf.py:965
msgid "SAML Service Provider Entity ID"
msgstr ""
-#: awx/sso/conf.py:954
+#: awx/sso/conf.py:966
msgid ""
"The application-defined unique identifier used as the audience of the SAML "
"service provider (SP) configuration. This is usually the URL for Tower."
msgstr ""
-#: awx/sso/conf.py:968
+#: awx/sso/conf.py:980
msgid "SAML Service Provider Public Certificate"
msgstr ""
-#: awx/sso/conf.py:969
+#: awx/sso/conf.py:981
msgid ""
"Create a keypair for Tower to use as a service provider (SP) and include the "
"certificate content here."
msgstr ""
-#: awx/sso/conf.py:981
+#: awx/sso/conf.py:993
msgid "SAML Service Provider Private Key"
msgstr ""
-#: awx/sso/conf.py:982
+#: awx/sso/conf.py:994
msgid ""
"Create a keypair for Tower to use as a service provider (SP) and include the "
"private key content here."
msgstr ""
-#: awx/sso/conf.py:993
+#: awx/sso/conf.py:1005
msgid "SAML Service Provider Organization Info"
msgstr ""
-#: awx/sso/conf.py:994
+#: awx/sso/conf.py:1006
msgid ""
"Provide the URL, display name, and the name of your app. Refer to the "
"Ansible Tower documentation for example syntax."
msgstr ""
-#: awx/sso/conf.py:1012
+#: awx/sso/conf.py:1024
msgid "SAML Service Provider Technical Contact"
msgstr ""
-#: awx/sso/conf.py:1013
+#: awx/sso/conf.py:1025
msgid ""
"Provide the name and email address of the technical contact for your service "
"provider. Refer to the Ansible Tower documentation for example syntax."
msgstr ""
-#: awx/sso/conf.py:1029
+#: awx/sso/conf.py:1041
msgid "SAML Service Provider Support Contact"
msgstr ""
-#: awx/sso/conf.py:1030
+#: awx/sso/conf.py:1042
msgid ""
"Provide the name and email address of the support contact for your service "
"provider. Refer to the Ansible Tower documentation for example syntax."
msgstr ""
-#: awx/sso/conf.py:1045
+#: awx/sso/conf.py:1057
msgid "SAML Enabled Identity Providers"
msgstr ""
-#: awx/sso/conf.py:1046
+#: awx/sso/conf.py:1058
msgid ""
"Configure the Entity ID, SSO URL and certificate for each identity provider "
"(IdP) in use. Multiple SAML IdPs are supported. Some IdPs may provide user "
@@ -5898,57 +5672,57 @@ msgid ""
"additional details and syntax."
msgstr ""
-#: awx/sso/conf.py:1082
+#: awx/sso/conf.py:1094
msgid "SAML Security Config"
msgstr ""
-#: awx/sso/conf.py:1083
+#: awx/sso/conf.py:1095
msgid ""
"A dict of key value pairs that are passed to the underlying python-saml "
"security setting https://github.com/onelogin/python-saml#settings"
msgstr ""
-#: awx/sso/conf.py:1114
+#: awx/sso/conf.py:1126
msgid "SAML Service Provider extra configuration data"
msgstr ""
-#: awx/sso/conf.py:1115
+#: awx/sso/conf.py:1127
msgid ""
"A dict of key value pairs to be passed to the underlying python-saml Service "
"Provider configuration setting."
msgstr ""
-#: awx/sso/conf.py:1127
+#: awx/sso/conf.py:1139
msgid "SAML IDP to extra_data attribute mapping"
msgstr ""
-#: awx/sso/conf.py:1128
+#: awx/sso/conf.py:1140
msgid ""
"A list of tuples that maps IDP attributes to extra_attributes. Each "
"attribute will be a list of values, even if only 1 value."
msgstr ""
-#: awx/sso/conf.py:1144
+#: awx/sso/conf.py:1156
msgid "SAML Organization Map"
msgstr ""
-#: awx/sso/conf.py:1156
+#: awx/sso/conf.py:1168
msgid "SAML Team Map"
msgstr ""
-#: awx/sso/conf.py:1168
+#: awx/sso/conf.py:1180
msgid "SAML Organization Attribute Mapping"
msgstr ""
-#: awx/sso/conf.py:1169
+#: awx/sso/conf.py:1181
msgid "Used to translate user organization membership into Tower."
msgstr ""
-#: awx/sso/conf.py:1187
+#: awx/sso/conf.py:1199
msgid "SAML Team Attribute Mapping"
msgstr ""
-#: awx/sso/conf.py:1188
+#: awx/sso/conf.py:1200
msgid "Used to translate user team membership into Tower."
msgstr ""
@@ -6015,12 +5789,12 @@ msgstr ""
msgid "Invalid language code(s) for org info: {invalid_lang_codes}."
msgstr ""
-#: awx/sso/pipeline.py:27
+#: awx/sso/pipeline.py:28
#, python-brace-format
msgid "An account cannot be found for {0}"
msgstr ""
-#: awx/sso/pipeline.py:33
+#: awx/sso/pipeline.py:34
msgid "Your account is inactive"
msgstr ""
@@ -6092,8 +5866,8 @@ msgstr ""
msgid ""
"If needed, you can add specific information (such as a legal notice or a "
"disclaimer) to a text box in the login modal using this setting. Any content "
-"added must be in plain text, as custom HTML or other markup languages are "
-"not supported."
+"added must be in plain text or an HTML fragment, as other markup languages "
+"are not supported."
msgstr ""
#: awx/ui/conf.py:45
diff --git a/awx/locale/en-us/LC_MESSAGES/django.po b/awx/locale/en-us/LC_MESSAGES/django.po
index dfdd2e72ef..3d2cf41999 100644
--- a/awx/locale/en-us/LC_MESSAGES/django.po
+++ b/awx/locale/en-us/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-05-16 02:52+0000\n"
+"POT-Creation-Date: 2020-10-05 19:43+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -27,35 +27,42 @@ msgid ""
"again."
msgstr ""
-#: awx/api/conf.py:17 awx/api/conf.py:26 awx/api/conf.py:34 awx/api/conf.py:50
-#: awx/api/conf.py:62 awx/api/conf.py:74 awx/sso/conf.py:97 awx/sso/conf.py:108
+#: awx/api/conf.py:17 awx/api/conf.py:27 awx/api/conf.py:35 awx/api/conf.py:51
+#: awx/api/conf.py:64 awx/api/conf.py:76 awx/sso/conf.py:97 awx/sso/conf.py:108
#: awx/sso/conf.py:120 awx/sso/conf.py:135
msgid "Authentication"
msgstr ""
-#: awx/api/conf.py:24
-msgid "Maximum number of simultaneous logged in sessions"
+#: awx/api/conf.py:19 awx/api/conf.py:53 awx/main/conf.py:256
+#: awx/main/conf.py:268 awx/main/conf.py:281 awx/main/conf.py:503
+#: awx/main/conf.py:516 awx/main/conf.py:529 awx/main/conf.py:544
+#: awx/main/conf.py:682 awx/main/conf.py:764 awx/sso/conf.py:518
+msgid "seconds"
msgstr ""
#: awx/api/conf.py:25
+msgid "Maximum number of simultaneous logged in sessions"
+msgstr ""
+
+#: awx/api/conf.py:26
msgid ""
"Maximum number of simultaneous logged in sessions a user may have. To "
"disable enter -1."
msgstr ""
-#: awx/api/conf.py:32
+#: awx/api/conf.py:33
msgid "Enable HTTP Basic Auth"
msgstr ""
-#: awx/api/conf.py:33
+#: awx/api/conf.py:34
msgid "Enable HTTP Basic Auth for the API Browser."
msgstr ""
-#: awx/api/conf.py:43
+#: awx/api/conf.py:44
msgid "OAuth 2 Timeout Settings"
msgstr ""
-#: awx/api/conf.py:44
+#: awx/api/conf.py:45
msgid ""
"Dictionary for customizing OAuth 2 timeouts, available items are "
"`ACCESS_TOKEN_EXPIRE_SECONDS`, the duration of access tokens in the number "
@@ -65,11 +72,11 @@ msgid ""
"expired access tokens, in the number of seconds."
msgstr ""
-#: awx/api/conf.py:57
+#: awx/api/conf.py:59
msgid "Allow External Users to Create OAuth2 Tokens"
msgstr ""
-#: awx/api/conf.py:58
+#: awx/api/conf.py:60
msgid ""
"For security reasons, users from external auth providers (LDAP, SAML, SSO, "
"Radius, and others) are not allowed to create OAuth2 tokens. To change this "
@@ -77,11 +84,11 @@ msgid ""
"setting is toggled off."
msgstr ""
-#: awx/api/conf.py:71
+#: awx/api/conf.py:73
msgid "Login redirect override URL"
msgstr ""
-#: awx/api/conf.py:72
+#: awx/api/conf.py:74
msgid ""
"URL to which unauthorized users will be redirected to log in. If blank, "
"users will be sent to the Tower login page."
@@ -126,27 +133,27 @@ msgstr ""
msgid "Invalid {field_name} id: {field_id}"
msgstr ""
-#: awx/api/filters.py:333
+#: awx/api/filters.py:338
msgid ""
"Cannot apply role_level filter to this list because its model does not use "
"roles for access control."
msgstr ""
-#: awx/api/generics.py:182
+#: awx/api/generics.py:183
msgid ""
"You did not use correct Content-Type in your HTTP request. If you are using "
"our REST API, the Content-Type must be application/json"
msgstr ""
-#: awx/api/generics.py:623 awx/api/generics.py:685
+#: awx/api/generics.py:647 awx/api/generics.py:709
msgid "\"id\" field must be an integer."
msgstr ""
-#: awx/api/generics.py:682
+#: awx/api/generics.py:706
msgid "\"id\" is required to disassociate"
msgstr ""
-#: awx/api/generics.py:733
+#: awx/api/generics.py:757
msgid "{} 'id' field is missing."
msgstr ""
@@ -248,1127 +255,1161 @@ msgid ""
"saved to the database."
msgstr ""
-#: awx/api/serializers.py:878
+#: awx/api/serializers.py:880
msgid "Write-only field used to change the password."
msgstr ""
-#: awx/api/serializers.py:880
+#: awx/api/serializers.py:882
msgid "Set if the account is managed by an external service"
msgstr ""
-#: awx/api/serializers.py:907
+#: awx/api/serializers.py:909
msgid "Password required for new User."
msgstr ""
-#: awx/api/serializers.py:992
+#: awx/api/serializers.py:994
#, python-format
msgid "Unable to change %s on user managed by LDAP."
msgstr ""
-#: awx/api/serializers.py:1088
+#: awx/api/serializers.py:1090
msgid "Must be a simple space-separated string with allowed scopes {}."
msgstr ""
-#: awx/api/serializers.py:1186
+#: awx/api/serializers.py:1188
msgid "Authorization Grant Type"
msgstr ""
-#: awx/api/serializers.py:1188 awx/main/credential_plugins/azure_kv.py:30
-#: awx/main/models/credential/__init__.py:964
+#: awx/api/serializers.py:1190 awx/main/credential_plugins/azure_kv.py:30
+#: awx/main/models/credential/__init__.py:972
msgid "Client Secret"
msgstr ""
-#: awx/api/serializers.py:1191
+#: awx/api/serializers.py:1193
msgid "Client Type"
msgstr ""
-#: awx/api/serializers.py:1194
+#: awx/api/serializers.py:1196
msgid "Redirect URIs"
msgstr ""
-#: awx/api/serializers.py:1197
+#: awx/api/serializers.py:1199
msgid "Skip Authorization"
msgstr ""
-#: awx/api/serializers.py:1303
+#: awx/api/serializers.py:1306
msgid "Cannot change max_hosts."
msgstr ""
-#: awx/api/serializers.py:1336
+#: awx/api/serializers.py:1339
msgid "This path is already being used by another manual project."
msgstr ""
-#: awx/api/serializers.py:1338
+#: awx/api/serializers.py:1341
+msgid "SCM branch cannot be used with archive projects."
+msgstr ""
+
+#: awx/api/serializers.py:1343
msgid "SCM refspec can only be used with git projects."
msgstr ""
-#: awx/api/serializers.py:1415
+#: awx/api/serializers.py:1420
msgid ""
"One or more job templates depend on branch override behavior for this "
"project (ids: {})."
msgstr ""
-#: awx/api/serializers.py:1422
+#: awx/api/serializers.py:1427
msgid "Update options must be set to false for manual projects."
msgstr ""
-#: awx/api/serializers.py:1428
+#: awx/api/serializers.py:1433
msgid "Array of playbooks available within this project."
msgstr ""
-#: awx/api/serializers.py:1447
+#: awx/api/serializers.py:1452
msgid ""
"Array of inventory files and directories available within this project, not "
"comprehensive."
msgstr ""
-#: awx/api/serializers.py:1495 awx/api/serializers.py:3034
-#: awx/api/serializers.py:3246
+#: awx/api/serializers.py:1500 awx/api/serializers.py:3089
+#: awx/api/serializers.py:3301
msgid "A count of hosts uniquely assigned to each status."
msgstr ""
-#: awx/api/serializers.py:1498 awx/api/serializers.py:3037
+#: awx/api/serializers.py:1503 awx/api/serializers.py:3092
msgid "A count of all plays and tasks for the job run."
msgstr ""
-#: awx/api/serializers.py:1625
+#: awx/api/serializers.py:1630
msgid "Smart inventories must specify host_filter"
msgstr ""
-#: awx/api/serializers.py:1713
+#: awx/api/serializers.py:1722
#, python-format
msgid "Invalid port specification: %s"
msgstr ""
-#: awx/api/serializers.py:1724
+#: awx/api/serializers.py:1733
msgid "Cannot create Host for Smart Inventory"
msgstr ""
-#: awx/api/serializers.py:1808
+#: awx/api/serializers.py:1751
+msgid "A Group with that name already exists."
+msgstr ""
+
+#: awx/api/serializers.py:1822
+msgid "A Host with that name already exists."
+msgstr ""
+
+#: awx/api/serializers.py:1827
msgid "Invalid group name."
msgstr ""
-#: awx/api/serializers.py:1813
+#: awx/api/serializers.py:1832
msgid "Cannot create Group for Smart Inventory"
msgstr ""
-#: awx/api/serializers.py:1888
+#: awx/api/serializers.py:1907
msgid ""
"Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python"
msgstr ""
-#: awx/api/serializers.py:1917
+#: awx/api/serializers.py:1936
msgid "Cloud credential to use for inventory updates."
msgstr ""
-#: awx/api/serializers.py:1938
+#: awx/api/serializers.py:1957
msgid "`{}` is a prohibited environment variable"
msgstr ""
-#: awx/api/serializers.py:1949
+#: awx/api/serializers.py:1968
msgid "If 'source' is 'custom', 'source_script' must be provided."
msgstr ""
-#: awx/api/serializers.py:1955
+#: awx/api/serializers.py:1974
msgid "Must provide an inventory."
msgstr ""
-#: awx/api/serializers.py:1959
+#: awx/api/serializers.py:1978
msgid ""
"The 'source_script' does not belong to the same organization as the "
"inventory."
msgstr ""
-#: awx/api/serializers.py:1961
+#: awx/api/serializers.py:1980
msgid "'source_script' doesn't exist."
msgstr ""
-#: awx/api/serializers.py:2063
+#: awx/api/serializers.py:2082
msgid "Cannot use manual project for SCM-based inventory."
msgstr ""
-#: awx/api/serializers.py:2068
+#: awx/api/serializers.py:2087
msgid "Setting not compatible with existing schedules."
msgstr ""
-#: awx/api/serializers.py:2073
+#: awx/api/serializers.py:2092
msgid "Cannot create Inventory Source for Smart Inventory"
msgstr ""
-#: awx/api/serializers.py:2121
+#: awx/api/serializers.py:2140
msgid "Project required for scm type sources."
msgstr ""
-#: awx/api/serializers.py:2130
+#: awx/api/serializers.py:2149
#, python-format
msgid "Cannot set %s if not SCM type."
msgstr ""
-#: awx/api/serializers.py:2200
+#: awx/api/serializers.py:2219
msgid "The project used for this job."
msgstr ""
-#: awx/api/serializers.py:2456
+#: awx/api/serializers.py:2475
msgid "Modifications not allowed for managed credential types"
msgstr ""
-#: awx/api/serializers.py:2468
+#: awx/api/serializers.py:2487
msgid ""
"Modifications to inputs are not allowed for credential types that are in use"
msgstr ""
-#: awx/api/serializers.py:2473
+#: awx/api/serializers.py:2492
#, python-format
msgid "Must be 'cloud' or 'net', not %s"
msgstr ""
-#: awx/api/serializers.py:2479
+#: awx/api/serializers.py:2498
msgid "'ask_at_runtime' is not supported for custom credentials."
msgstr ""
-#: awx/api/serializers.py:2527
+#: awx/api/serializers.py:2547
msgid "Credential Type"
msgstr ""
-#: awx/api/serializers.py:2608
+#: awx/api/serializers.py:2611
+msgid "Modifications not allowed for managed credentials"
+msgstr ""
+
+#: awx/api/serializers.py:2629 awx/api/serializers.py:2703
+msgid "Galaxy credentials must be owned by an Organization."
+msgstr ""
+
+#: awx/api/serializers.py:2646
msgid ""
"You cannot change the credential type of the credential, as it may break the "
"functionality of the resources using it."
msgstr ""
-#: awx/api/serializers.py:2620
+#: awx/api/serializers.py:2658
msgid ""
"Write-only field used to add user to owner role. If provided, do not give "
"either team or organization. Only valid for creation."
msgstr ""
-#: awx/api/serializers.py:2625
+#: awx/api/serializers.py:2663
msgid ""
"Write-only field used to add team to owner role. If provided, do not give "
"either user or organization. Only valid for creation."
msgstr ""
-#: awx/api/serializers.py:2630
+#: awx/api/serializers.py:2668
msgid ""
"Inherit permissions from organization roles. If provided on creation, do not "
"give either user or team."
msgstr ""
-#: awx/api/serializers.py:2646
+#: awx/api/serializers.py:2685
msgid "Missing 'user', 'team', or 'organization'."
msgstr ""
-#: awx/api/serializers.py:2663
+#: awx/api/serializers.py:2690
+msgid ""
+"Only one of 'user', 'team', or 'organization' should be provided, received "
+"{} fields."
+msgstr ""
+
+#: awx/api/serializers.py:2718
msgid ""
"Credential organization must be set and match before assigning to a team"
msgstr ""
-#: awx/api/serializers.py:2789
+#: awx/api/serializers.py:2844
msgid "This field is required."
msgstr ""
-#: awx/api/serializers.py:2798
+#: awx/api/serializers.py:2853
msgid "Playbook not found for project."
msgstr ""
-#: awx/api/serializers.py:2800
+#: awx/api/serializers.py:2855
msgid "Must select playbook for project."
msgstr ""
-#: awx/api/serializers.py:2802 awx/api/serializers.py:2804
+#: awx/api/serializers.py:2857 awx/api/serializers.py:2859
msgid "Project does not allow overriding branch."
msgstr ""
-#: awx/api/serializers.py:2841
+#: awx/api/serializers.py:2896
msgid "Must be a Personal Access Token."
msgstr ""
-#: awx/api/serializers.py:2844
+#: awx/api/serializers.py:2899
msgid "Must match the selected webhook service."
msgstr ""
-#: awx/api/serializers.py:2915
+#: awx/api/serializers.py:2970
msgid "Cannot enable provisioning callback without an inventory set."
msgstr ""
-#: awx/api/serializers.py:2918
+#: awx/api/serializers.py:2973
msgid "Must either set a default value or ask to prompt on launch."
msgstr ""
-#: awx/api/serializers.py:2920 awx/main/models/jobs.py:299
+#: awx/api/serializers.py:2975 awx/main/models/jobs.py:299
msgid "Job Templates must have a project assigned."
msgstr ""
-#: awx/api/serializers.py:3078
+#: awx/api/serializers.py:3133
msgid "No change to job limit"
msgstr ""
-#: awx/api/serializers.py:3079
+#: awx/api/serializers.py:3134
msgid "All failed and unreachable hosts"
msgstr ""
-#: awx/api/serializers.py:3094
+#: awx/api/serializers.py:3149
msgid "Missing passwords needed to start: {}"
msgstr ""
-#: awx/api/serializers.py:3113
+#: awx/api/serializers.py:3168
msgid "Relaunch by host status not available until job finishes running."
msgstr ""
-#: awx/api/serializers.py:3127
+#: awx/api/serializers.py:3182
msgid "Job Template Project is missing or undefined."
msgstr ""
-#: awx/api/serializers.py:3129
+#: awx/api/serializers.py:3184
msgid "Job Template Inventory is missing or undefined."
msgstr ""
-#: awx/api/serializers.py:3167
+#: awx/api/serializers.py:3222
msgid "Unknown, job may have been ran before launch configurations were saved."
msgstr ""
-#: awx/api/serializers.py:3238 awx/main/tasks.py:2799 awx/main/tasks.py:2817
+#: awx/api/serializers.py:3293 awx/main/tasks.py:2838 awx/main/tasks.py:2856
msgid "{} are prohibited from use in ad hoc commands."
msgstr ""
-#: awx/api/serializers.py:3326 awx/api/views/__init__.py:4169
+#: awx/api/serializers.py:3381 awx/api/views/__init__.py:4211
#, python-brace-format
msgid ""
"Standard Output too large to display ({text_size} bytes), only download "
"supported for sizes over {supported_size} bytes."
msgstr ""
-#: awx/api/serializers.py:3639
+#: awx/api/serializers.py:3694
msgid "Provided variable {} has no database value to replace with."
msgstr ""
-#: awx/api/serializers.py:3657
+#: awx/api/serializers.py:3712
msgid "\"$encrypted$ is a reserved keyword, may not be used for {}.\""
msgstr ""
-#: awx/api/serializers.py:4064
+#: awx/api/serializers.py:4119
msgid "A project is required to run a job."
msgstr ""
-#: awx/api/serializers.py:4066
+#: awx/api/serializers.py:4121
msgid "Missing a revision to run due to failed project update."
msgstr ""
-#: awx/api/serializers.py:4070
+#: awx/api/serializers.py:4125
msgid "The inventory associated with this Job Template is being deleted."
msgstr ""
-#: awx/api/serializers.py:4072 awx/api/serializers.py:4188
+#: awx/api/serializers.py:4127 awx/api/serializers.py:4247
msgid "The provided inventory is being deleted."
msgstr ""
-#: awx/api/serializers.py:4080
+#: awx/api/serializers.py:4135
msgid "Cannot assign multiple {} credentials."
msgstr ""
-#: awx/api/serializers.py:4084
+#: awx/api/serializers.py:4140
msgid "Cannot assign a Credential of kind `{}`"
msgstr ""
-#: awx/api/serializers.py:4097
+#: awx/api/serializers.py:4153
msgid ""
"Removing {} credential at launch time without replacement is not supported. "
"Provided list lacked credential(s): {}."
msgstr ""
-#: awx/api/serializers.py:4186
+#: awx/api/serializers.py:4245
msgid "The inventory associated with this Workflow is being deleted."
msgstr ""
-#: awx/api/serializers.py:4257
+#: awx/api/serializers.py:4316
msgid "Message type '{}' invalid, must be either 'message' or 'body'"
msgstr ""
-#: awx/api/serializers.py:4263
+#: awx/api/serializers.py:4322
msgid "Expected string for '{}', found {}, "
msgstr ""
-#: awx/api/serializers.py:4267
+#: awx/api/serializers.py:4326
msgid "Messages cannot contain newlines (found newline in {} event)"
msgstr ""
-#: awx/api/serializers.py:4273
+#: awx/api/serializers.py:4332
msgid "Expected dict for 'messages' field, found {}"
msgstr ""
-#: awx/api/serializers.py:4277
+#: awx/api/serializers.py:4336
msgid ""
"Event '{}' invalid, must be one of 'started', 'success', 'error', or "
"'workflow_approval'"
msgstr ""
-#: awx/api/serializers.py:4283
+#: awx/api/serializers.py:4342
msgid "Expected dict for event '{}', found {}"
msgstr ""
-#: awx/api/serializers.py:4288
+#: awx/api/serializers.py:4347
msgid ""
"Workflow Approval event '{}' invalid, must be one of 'running', 'approved', "
"'timed_out', or 'denied'"
msgstr ""
-#: awx/api/serializers.py:4295
+#: awx/api/serializers.py:4354
msgid "Expected dict for workflow approval event '{}', found {}"
msgstr ""
-#: awx/api/serializers.py:4322
+#: awx/api/serializers.py:4381
msgid "Unable to render message '{}': {}"
msgstr ""
-#: awx/api/serializers.py:4324
+#: awx/api/serializers.py:4383
msgid "Field '{}' unavailable"
msgstr ""
-#: awx/api/serializers.py:4326
+#: awx/api/serializers.py:4385
msgid "Security error due to field '{}'"
msgstr ""
-#: awx/api/serializers.py:4346
+#: awx/api/serializers.py:4405
msgid "Webhook body for '{}' should be a json dictionary. Found type '{}'."
msgstr ""
-#: awx/api/serializers.py:4349
+#: awx/api/serializers.py:4408
msgid "Webhook body for '{}' is not a valid json dictionary ({})."
msgstr ""
-#: awx/api/serializers.py:4367
+#: awx/api/serializers.py:4426
msgid ""
"Missing required fields for Notification Configuration: notification_type"
msgstr ""
-#: awx/api/serializers.py:4394
+#: awx/api/serializers.py:4453
msgid "No values specified for field '{}'"
msgstr ""
-#: awx/api/serializers.py:4399
+#: awx/api/serializers.py:4458
msgid "HTTP method must be either 'POST' or 'PUT'."
msgstr ""
-#: awx/api/serializers.py:4401
+#: awx/api/serializers.py:4460
msgid "Missing required fields for Notification Configuration: {}."
msgstr ""
-#: awx/api/serializers.py:4404
+#: awx/api/serializers.py:4463
msgid "Configuration field '{}' incorrect type, expected {}."
msgstr ""
-#: awx/api/serializers.py:4421
+#: awx/api/serializers.py:4480
msgid "Notification body"
msgstr ""
-#: awx/api/serializers.py:4501
+#: awx/api/serializers.py:4560
msgid ""
"Valid DTSTART required in rrule. Value should start with: DTSTART:"
"YYYYMMDDTHHMMSSZ"
msgstr ""
-#: awx/api/serializers.py:4503
+#: awx/api/serializers.py:4562
msgid ""
"DTSTART cannot be a naive datetime. Specify ;TZINFO= or YYYYMMDDTHHMMSSZZ."
msgstr ""
-#: awx/api/serializers.py:4505
+#: awx/api/serializers.py:4564
msgid "Multiple DTSTART is not supported."
msgstr ""
-#: awx/api/serializers.py:4507
+#: awx/api/serializers.py:4566
msgid "RRULE required in rrule."
msgstr ""
-#: awx/api/serializers.py:4509
+#: awx/api/serializers.py:4568
msgid "Multiple RRULE is not supported."
msgstr ""
-#: awx/api/serializers.py:4511
+#: awx/api/serializers.py:4570
msgid "INTERVAL required in rrule."
msgstr ""
-#: awx/api/serializers.py:4513
+#: awx/api/serializers.py:4572
msgid "SECONDLY is not supported."
msgstr ""
-#: awx/api/serializers.py:4515
+#: awx/api/serializers.py:4574
msgid "Multiple BYMONTHDAYs not supported."
msgstr ""
-#: awx/api/serializers.py:4517
+#: awx/api/serializers.py:4576
msgid "Multiple BYMONTHs not supported."
msgstr ""
-#: awx/api/serializers.py:4519
+#: awx/api/serializers.py:4578
msgid "BYDAY with numeric prefix not supported."
msgstr ""
-#: awx/api/serializers.py:4521
+#: awx/api/serializers.py:4580
msgid "BYYEARDAY not supported."
msgstr ""
-#: awx/api/serializers.py:4523
+#: awx/api/serializers.py:4582
msgid "BYWEEKNO not supported."
msgstr ""
-#: awx/api/serializers.py:4525
+#: awx/api/serializers.py:4584
msgid "RRULE may not contain both COUNT and UNTIL"
msgstr ""
-#: awx/api/serializers.py:4529
+#: awx/api/serializers.py:4588
msgid "COUNT > 999 is unsupported."
msgstr ""
-#: awx/api/serializers.py:4535
+#: awx/api/serializers.py:4594
msgid "rrule parsing failed validation: {}"
msgstr ""
-#: awx/api/serializers.py:4597
+#: awx/api/serializers.py:4656
msgid "Inventory Source must be a cloud resource."
msgstr ""
-#: awx/api/serializers.py:4599
+#: awx/api/serializers.py:4658
msgid "Manual Project cannot have a schedule set."
msgstr ""
-#: awx/api/serializers.py:4602
+#: awx/api/serializers.py:4661
msgid ""
"Inventory sources with `update_on_project_update` cannot be scheduled. "
"Schedule its source project `{}` instead."
msgstr ""
-#: awx/api/serializers.py:4612
+#: awx/api/serializers.py:4671
msgid ""
"Count of jobs in the running or waiting state that are targeted for this "
"instance"
msgstr ""
-#: awx/api/serializers.py:4617
+#: awx/api/serializers.py:4676
msgid "Count of all jobs that target this instance"
msgstr ""
-#: awx/api/serializers.py:4650
+#: awx/api/serializers.py:4711
msgid ""
"Count of jobs in the running or waiting state that are targeted for this "
"instance group"
msgstr ""
-#: awx/api/serializers.py:4655
+#: awx/api/serializers.py:4716
msgid "Count of all jobs that target this instance group"
msgstr ""
-#: awx/api/serializers.py:4660
+#: awx/api/serializers.py:4721
msgid "Indicates whether instance group controls any other group"
msgstr ""
-#: awx/api/serializers.py:4664
+#: awx/api/serializers.py:4725
msgid ""
"Indicates whether instances in this group are isolated.Isolated groups have "
"a designated controller group."
msgstr ""
-#: awx/api/serializers.py:4669
+#: awx/api/serializers.py:4730
msgid ""
"Indicates whether instances in this group are containerized.Containerized "
"groups have a designated Openshift or Kubernetes cluster."
msgstr ""
-#: awx/api/serializers.py:4677
+#: awx/api/serializers.py:4738
msgid "Policy Instance Percentage"
msgstr ""
-#: awx/api/serializers.py:4678
+#: awx/api/serializers.py:4739
msgid ""
"Minimum percentage of all instances that will be automatically assigned to "
"this group when new instances come online."
msgstr ""
-#: awx/api/serializers.py:4683
+#: awx/api/serializers.py:4744
msgid "Policy Instance Minimum"
msgstr ""
-#: awx/api/serializers.py:4684
+#: awx/api/serializers.py:4745
msgid ""
"Static minimum number of Instances that will be automatically assign to this "
"group when new instances come online."
msgstr ""
-#: awx/api/serializers.py:4689
+#: awx/api/serializers.py:4750
msgid "Policy Instance List"
msgstr ""
-#: awx/api/serializers.py:4690
+#: awx/api/serializers.py:4751
msgid "List of exact-match Instances that will be assigned to this group"
msgstr ""
-#: awx/api/serializers.py:4716
+#: awx/api/serializers.py:4777
msgid "Duplicate entry {}."
msgstr ""
-#: awx/api/serializers.py:4718
+#: awx/api/serializers.py:4779
msgid "{} is not a valid hostname of an existing instance."
msgstr ""
-#: awx/api/serializers.py:4720 awx/api/views/mixin.py:98
+#: awx/api/serializers.py:4781 awx/api/views/mixin.py:98
msgid ""
"Isolated instances may not be added or removed from instances groups via the "
"API."
msgstr ""
-#: awx/api/serializers.py:4722 awx/api/views/mixin.py:102
+#: awx/api/serializers.py:4783 awx/api/views/mixin.py:102
msgid "Isolated instance group membership may not be managed via the API."
msgstr ""
-#: awx/api/serializers.py:4724 awx/api/serializers.py:4729
-#: awx/api/serializers.py:4734
+#: awx/api/serializers.py:4785 awx/api/serializers.py:4790
+#: awx/api/serializers.py:4795
msgid "Containerized instances may not be managed via the API"
msgstr ""
-#: awx/api/serializers.py:4739
+#: awx/api/serializers.py:4800
msgid "tower instance group name may not be changed."
msgstr ""
-#: awx/api/serializers.py:4744
+#: awx/api/serializers.py:4805
msgid "Only Kubernetes credentials can be associated with an Instance Group"
msgstr ""
-#: awx/api/serializers.py:4783
+#: awx/api/serializers.py:4844
msgid ""
"When present, shows the field name of the role or relationship that changed."
msgstr ""
-#: awx/api/serializers.py:4785
+#: awx/api/serializers.py:4846
msgid ""
"When present, shows the model on which the role or relationship was defined."
msgstr ""
-#: awx/api/serializers.py:4818
+#: awx/api/serializers.py:4879
msgid ""
"A summary of the new and changed values when an object is created, updated, "
"or deleted"
msgstr ""
-#: awx/api/serializers.py:4820
+#: awx/api/serializers.py:4881
msgid ""
"For create, update, and delete events this is the object type that was "
"affected. For associate and disassociate events this is the object type "
"associated or disassociated with object2."
msgstr ""
-#: awx/api/serializers.py:4823
+#: awx/api/serializers.py:4884
msgid ""
"Unpopulated for create, update, and delete events. For associate and "
"disassociate events this is the object type that object1 is being associated "
"with."
msgstr ""
-#: awx/api/serializers.py:4826
+#: awx/api/serializers.py:4887
msgid "The action taken with respect to the given object(s)."
msgstr ""
-#: awx/api/views/__init__.py:181
+#: awx/api/views/__init__.py:185
+msgid "Not found."
+msgstr ""
+
+#: awx/api/views/__init__.py:193
msgid "Dashboard"
msgstr ""
-#: awx/api/views/__init__.py:271
+#: awx/api/views/__init__.py:290
msgid "Dashboard Jobs Graphs"
msgstr ""
-#: awx/api/views/__init__.py:307
+#: awx/api/views/__init__.py:326
#, python-format
msgid "Unknown period \"%s\""
msgstr ""
-#: awx/api/views/__init__.py:321
+#: awx/api/views/__init__.py:340
msgid "Instances"
msgstr ""
-#: awx/api/views/__init__.py:329
+#: awx/api/views/__init__.py:348
msgid "Instance Detail"
msgstr ""
-#: awx/api/views/__init__.py:346
+#: awx/api/views/__init__.py:365
msgid "Instance Jobs"
msgstr ""
-#: awx/api/views/__init__.py:360
+#: awx/api/views/__init__.py:379
msgid "Instance's Instance Groups"
msgstr ""
-#: awx/api/views/__init__.py:369
+#: awx/api/views/__init__.py:388
msgid "Instance Groups"
msgstr ""
-#: awx/api/views/__init__.py:377
+#: awx/api/views/__init__.py:396
msgid "Instance Group Detail"
msgstr ""
-#: awx/api/views/__init__.py:392
+#: awx/api/views/__init__.py:411
msgid "Isolated Groups can not be removed from the API"
msgstr ""
-#: awx/api/views/__init__.py:394
+#: awx/api/views/__init__.py:413
msgid ""
"Instance Groups acting as a controller for an Isolated Group can not be "
"removed from the API"
msgstr ""
-#: awx/api/views/__init__.py:400
+#: awx/api/views/__init__.py:419
msgid "Instance Group Running Jobs"
msgstr ""
-#: awx/api/views/__init__.py:409
+#: awx/api/views/__init__.py:428
msgid "Instance Group's Instances"
msgstr ""
-#: awx/api/views/__init__.py:419
+#: awx/api/views/__init__.py:438
msgid "Schedules"
msgstr ""
-#: awx/api/views/__init__.py:433
+#: awx/api/views/__init__.py:452
msgid "Schedule Recurrence Rule Preview"
msgstr ""
-#: awx/api/views/__init__.py:480
+#: awx/api/views/__init__.py:499
msgid "Cannot assign credential when related template is null."
msgstr ""
-#: awx/api/views/__init__.py:485
+#: awx/api/views/__init__.py:504
msgid "Related template cannot accept {} on launch."
msgstr ""
-#: awx/api/views/__init__.py:487
+#: awx/api/views/__init__.py:506
msgid ""
"Credential that requires user input on launch cannot be used in saved launch "
"configuration."
msgstr ""
-#: awx/api/views/__init__.py:493
+#: awx/api/views/__init__.py:512
msgid "Related template is not configured to accept credentials on launch."
msgstr ""
-#: awx/api/views/__init__.py:495
+#: awx/api/views/__init__.py:514
#, python-brace-format
msgid ""
"This launch configuration already provides a {credential_type} credential."
msgstr ""
-#: awx/api/views/__init__.py:498
+#: awx/api/views/__init__.py:517
#, python-brace-format
msgid "Related template already uses {credential_type} credential."
msgstr ""
-#: awx/api/views/__init__.py:516
+#: awx/api/views/__init__.py:535
msgid "Schedule Jobs List"
msgstr ""
-#: awx/api/views/__init__.py:600 awx/api/views/__init__.py:4378
+#: awx/api/views/__init__.py:619 awx/api/views/__init__.py:4420
msgid ""
"You cannot assign an Organization participation role as a child role for a "
"Team."
msgstr ""
-#: awx/api/views/__init__.py:604 awx/api/views/__init__.py:4392
+#: awx/api/views/__init__.py:623 awx/api/views/__init__.py:4434
msgid "You cannot grant system-level permissions to a team."
msgstr ""
-#: awx/api/views/__init__.py:611 awx/api/views/__init__.py:4384
+#: awx/api/views/__init__.py:630 awx/api/views/__init__.py:4426
msgid ""
"You cannot grant credential access to a team when the Organization field "
"isn't set, or belongs to a different organization"
msgstr ""
-#: awx/api/views/__init__.py:713
+#: awx/api/views/__init__.py:732
msgid "Project Schedules"
msgstr ""
-#: awx/api/views/__init__.py:724
+#: awx/api/views/__init__.py:743
msgid "Project SCM Inventory Sources"
msgstr ""
-#: awx/api/views/__init__.py:825
+#: awx/api/views/__init__.py:844
msgid "Project Update Events List"
msgstr ""
-#: awx/api/views/__init__.py:839
+#: awx/api/views/__init__.py:858
msgid "System Job Events List"
msgstr ""
-#: awx/api/views/__init__.py:873
+#: awx/api/views/__init__.py:892
msgid "Project Update SCM Inventory Updates"
msgstr ""
-#: awx/api/views/__init__.py:918
+#: awx/api/views/__init__.py:937
msgid "Me"
msgstr ""
-#: awx/api/views/__init__.py:927
+#: awx/api/views/__init__.py:946
msgid "OAuth 2 Applications"
msgstr ""
-#: awx/api/views/__init__.py:936
+#: awx/api/views/__init__.py:955
msgid "OAuth 2 Application Detail"
msgstr ""
-#: awx/api/views/__init__.py:949
+#: awx/api/views/__init__.py:968
msgid "OAuth 2 Application Tokens"
msgstr ""
-#: awx/api/views/__init__.py:971
+#: awx/api/views/__init__.py:990
msgid "OAuth2 Tokens"
msgstr ""
-#: awx/api/views/__init__.py:980
+#: awx/api/views/__init__.py:999
msgid "OAuth2 User Tokens"
msgstr ""
-#: awx/api/views/__init__.py:992
+#: awx/api/views/__init__.py:1011
msgid "OAuth2 User Authorized Access Tokens"
msgstr ""
-#: awx/api/views/__init__.py:1007
+#: awx/api/views/__init__.py:1026
msgid "Organization OAuth2 Applications"
msgstr ""
-#: awx/api/views/__init__.py:1019
+#: awx/api/views/__init__.py:1038
msgid "OAuth2 Personal Access Tokens"
msgstr ""
-#: awx/api/views/__init__.py:1034
+#: awx/api/views/__init__.py:1053
msgid "OAuth Token Detail"
msgstr ""
-#: awx/api/views/__init__.py:1096 awx/api/views/__init__.py:4345
+#: awx/api/views/__init__.py:1115 awx/api/views/__init__.py:4387
msgid ""
"You cannot grant credential access to a user not in the credentials' "
"organization"
msgstr ""
-#: awx/api/views/__init__.py:1100 awx/api/views/__init__.py:4349
+#: awx/api/views/__init__.py:1119 awx/api/views/__init__.py:4391
msgid "You cannot grant private credential access to another user"
msgstr ""
-#: awx/api/views/__init__.py:1198
+#: awx/api/views/__init__.py:1217
#, python-format
msgid "Cannot change %s."
msgstr ""
-#: awx/api/views/__init__.py:1204
+#: awx/api/views/__init__.py:1223
msgid "Cannot delete user."
msgstr ""
-#: awx/api/views/__init__.py:1228
+#: awx/api/views/__init__.py:1247
msgid "Deletion not allowed for managed credential types"
msgstr ""
-#: awx/api/views/__init__.py:1230
+#: awx/api/views/__init__.py:1249
msgid "Credential types that are in use cannot be deleted"
msgstr ""
-#: awx/api/views/__init__.py:1381
+#: awx/api/views/__init__.py:1362
+msgid "Deletion not allowed for managed credentials"
+msgstr ""
+
+#: awx/api/views/__init__.py:1407
msgid "External Credential Test"
msgstr ""
-#: awx/api/views/__init__.py:1408
+#: awx/api/views/__init__.py:1442
msgid "Credential Input Source Detail"
msgstr ""
-#: awx/api/views/__init__.py:1416 awx/api/views/__init__.py:1424
+#: awx/api/views/__init__.py:1450 awx/api/views/__init__.py:1458
msgid "Credential Input Sources"
msgstr ""
-#: awx/api/views/__init__.py:1439
+#: awx/api/views/__init__.py:1473
msgid "External Credential Type Test"
msgstr ""
-#: awx/api/views/__init__.py:1497
+#: awx/api/views/__init__.py:1539
msgid "The inventory for this host is already being deleted."
msgstr ""
-#: awx/api/views/__init__.py:1614
+#: awx/api/views/__init__.py:1656
msgid "SSLError while trying to connect to {}"
msgstr ""
-#: awx/api/views/__init__.py:1616
+#: awx/api/views/__init__.py:1658
msgid "Request to {} timed out."
msgstr ""
-#: awx/api/views/__init__.py:1618
+#: awx/api/views/__init__.py:1660
msgid "Unknown exception {} while trying to GET {}"
msgstr ""
-#: awx/api/views/__init__.py:1622
+#: awx/api/views/__init__.py:1664
msgid ""
"Unauthorized access. Please check your Insights Credential username and "
"password."
msgstr ""
-#: awx/api/views/__init__.py:1626
+#: awx/api/views/__init__.py:1668
msgid ""
"Failed to access the Insights API at URL {}. Server responded with {} status "
"code and message {}"
msgstr ""
-#: awx/api/views/__init__.py:1635
+#: awx/api/views/__init__.py:1677
msgid "Expected JSON response from Insights at URL {} but instead got {}"
msgstr ""
-#: awx/api/views/__init__.py:1653
+#: awx/api/views/__init__.py:1695
msgid "Could not translate Insights system ID {} into an Insights platform ID."
msgstr ""
-#: awx/api/views/__init__.py:1695
+#: awx/api/views/__init__.py:1737
msgid "This host is not recognized as an Insights host."
msgstr ""
-#: awx/api/views/__init__.py:1703
+#: awx/api/views/__init__.py:1745
msgid "The Insights Credential for \"{}\" was not found."
msgstr ""
-#: awx/api/views/__init__.py:1782
+#: awx/api/views/__init__.py:1824
msgid "Cyclical Group association."
msgstr ""
-#: awx/api/views/__init__.py:1948
+#: awx/api/views/__init__.py:1990
msgid "Inventory subset argument must be a string."
msgstr ""
-#: awx/api/views/__init__.py:1952
+#: awx/api/views/__init__.py:1994
msgid "Subset does not use any supported syntax."
msgstr ""
-#: awx/api/views/__init__.py:2002
+#: awx/api/views/__init__.py:2044
msgid "Inventory Source List"
msgstr ""
-#: awx/api/views/__init__.py:2014
+#: awx/api/views/__init__.py:2056
msgid "Inventory Sources Update"
msgstr ""
-#: awx/api/views/__init__.py:2047
+#: awx/api/views/__init__.py:2089
msgid "Could not start because `can_update` returned False"
msgstr ""
-#: awx/api/views/__init__.py:2055
+#: awx/api/views/__init__.py:2097
msgid "No inventory sources to update."
msgstr ""
-#: awx/api/views/__init__.py:2077
+#: awx/api/views/__init__.py:2119
msgid "Inventory Source Schedules"
msgstr ""
-#: awx/api/views/__init__.py:2104
+#: awx/api/views/__init__.py:2146
msgid "Notification Templates can only be assigned when source is one of {}."
msgstr ""
-#: awx/api/views/__init__.py:2202
+#: awx/api/views/__init__.py:2244
msgid "Source already has credential assigned."
msgstr ""
-#: awx/api/views/__init__.py:2418
+#: awx/api/views/__init__.py:2460
msgid "Job Template Schedules"
msgstr ""
-#: awx/api/views/__init__.py:2467
+#: awx/api/views/__init__.py:2509
msgid "Field '{}' is missing from survey spec."
msgstr ""
-#: awx/api/views/__init__.py:2469
+#: awx/api/views/__init__.py:2511
msgid "Expected {} for field '{}', received {} type."
msgstr ""
-#: awx/api/views/__init__.py:2473
+#: awx/api/views/__init__.py:2515
msgid "'spec' doesn't contain any items."
msgstr ""
-#: awx/api/views/__init__.py:2487
+#: awx/api/views/__init__.py:2529
#, python-format
msgid "Survey question %s is not a json object."
msgstr ""
-#: awx/api/views/__init__.py:2490
+#: awx/api/views/__init__.py:2532
#, python-brace-format
msgid "'{field_name}' missing from survey question {idx}"
msgstr ""
-#: awx/api/views/__init__.py:2500
+#: awx/api/views/__init__.py:2542
#, python-brace-format
msgid "'{field_name}' in survey question {idx} expected to be {type_label}."
msgstr ""
-#: awx/api/views/__init__.py:2504
+#: awx/api/views/__init__.py:2546
#, python-format
msgid "'variable' '%(item)s' duplicated in survey question %(survey)s."
msgstr ""
-#: awx/api/views/__init__.py:2514
+#: awx/api/views/__init__.py:2556
#, python-brace-format
msgid ""
"'{survey_item[type]}' in survey question {idx} is not one of "
"'{allowed_types}' allowed question types."
msgstr ""
-#: awx/api/views/__init__.py:2524
+#: awx/api/views/__init__.py:2566
#, python-brace-format
msgid ""
"Default value {survey_item[default]} in survey question {idx} expected to be "
"{type_label}."
msgstr ""
-#: awx/api/views/__init__.py:2534
+#: awx/api/views/__init__.py:2576
#, python-brace-format
msgid "The {min_or_max} limit in survey question {idx} expected to be integer."
msgstr ""
-#: awx/api/views/__init__.py:2544
+#: awx/api/views/__init__.py:2586
#, python-brace-format
msgid "Survey question {idx} of type {survey_item[type]} must specify choices."
msgstr ""
-#: awx/api/views/__init__.py:2558
+#: awx/api/views/__init__.py:2600
msgid "Multiple Choice (Single Select) can only have one default value."
msgstr ""
-#: awx/api/views/__init__.py:2562
+#: awx/api/views/__init__.py:2604
msgid "Default choice must be answered from the choices listed."
msgstr ""
-#: awx/api/views/__init__.py:2571
+#: awx/api/views/__init__.py:2613
#, python-brace-format
msgid ""
"$encrypted$ is a reserved keyword for password question defaults, survey "
"question {idx} is type {survey_item[type]}."
msgstr ""
-#: awx/api/views/__init__.py:2585
+#: awx/api/views/__init__.py:2627
#, python-brace-format
msgid ""
"$encrypted$ is a reserved keyword, may not be used for new default in "
"position {idx}."
msgstr ""
-#: awx/api/views/__init__.py:2657
+#: awx/api/views/__init__.py:2699
#, python-brace-format
msgid "Cannot assign multiple {credential_type} credentials."
msgstr ""
-#: awx/api/views/__init__.py:2661
+#: awx/api/views/__init__.py:2703
msgid "Cannot assign a Credential of kind `{}`."
msgstr ""
-#: awx/api/views/__init__.py:2684
+#: awx/api/views/__init__.py:2726
msgid "Maximum number of labels for {} reached."
msgstr ""
-#: awx/api/views/__init__.py:2807
+#: awx/api/views/__init__.py:2849
msgid "No matching host could be found!"
msgstr ""
-#: awx/api/views/__init__.py:2810
+#: awx/api/views/__init__.py:2852
msgid "Multiple hosts matched the request!"
msgstr ""
-#: awx/api/views/__init__.py:2815
+#: awx/api/views/__init__.py:2857
msgid "Cannot start automatically, user input required!"
msgstr ""
-#: awx/api/views/__init__.py:2823
+#: awx/api/views/__init__.py:2865
msgid "Host callback job already pending."
msgstr ""
-#: awx/api/views/__init__.py:2839 awx/api/views/__init__.py:3590
+#: awx/api/views/__init__.py:2881 awx/api/views/__init__.py:3632
msgid "Error starting job!"
msgstr ""
-#: awx/api/views/__init__.py:2963 awx/api/views/__init__.py:2983
+#: awx/api/views/__init__.py:3005 awx/api/views/__init__.py:3025
msgid "Cycle detected."
msgstr ""
-#: awx/api/views/__init__.py:2975
+#: awx/api/views/__init__.py:3017
msgid "Relationship not allowed."
msgstr ""
-#: awx/api/views/__init__.py:3204
+#: awx/api/views/__init__.py:3246
msgid "Cannot relaunch slice workflow job orphaned from job template."
msgstr ""
-#: awx/api/views/__init__.py:3206
+#: awx/api/views/__init__.py:3248
msgid "Cannot relaunch sliced workflow job after slice count has changed."
msgstr ""
-#: awx/api/views/__init__.py:3239
+#: awx/api/views/__init__.py:3281
msgid "Workflow Job Template Schedules"
msgstr ""
-#: awx/api/views/__init__.py:3382 awx/api/views/__init__.py:4013
+#: awx/api/views/__init__.py:3424 awx/api/views/__init__.py:4055
msgid "Superuser privileges needed."
msgstr ""
-#: awx/api/views/__init__.py:3415
+#: awx/api/views/__init__.py:3457
msgid "System Job Template Schedules"
msgstr ""
-#: awx/api/views/__init__.py:3573
+#: awx/api/views/__init__.py:3615
#, python-brace-format
msgid "Wait until job finishes before retrying on {status_value} hosts."
msgstr ""
-#: awx/api/views/__init__.py:3578
+#: awx/api/views/__init__.py:3620
#, python-brace-format
msgid "Cannot retry on {status_value} hosts, playbook stats not available."
msgstr ""
-#: awx/api/views/__init__.py:3583
+#: awx/api/views/__init__.py:3625
#, python-brace-format
msgid "Cannot relaunch because previous job had 0 {status_value} hosts."
msgstr ""
-#: awx/api/views/__init__.py:3612
+#: awx/api/views/__init__.py:3654
msgid "Cannot create schedule because job requires credential passwords."
msgstr ""
-#: awx/api/views/__init__.py:3617
+#: awx/api/views/__init__.py:3659
msgid "Cannot create schedule because job was launched by legacy method."
msgstr ""
-#: awx/api/views/__init__.py:3619
+#: awx/api/views/__init__.py:3661
msgid "Cannot create schedule because a related resource is missing."
msgstr ""
-#: awx/api/views/__init__.py:3674
+#: awx/api/views/__init__.py:3716
msgid "Job Host Summaries List"
msgstr ""
-#: awx/api/views/__init__.py:3728
+#: awx/api/views/__init__.py:3770
msgid "Job Event Children List"
msgstr ""
-#: awx/api/views/__init__.py:3744
+#: awx/api/views/__init__.py:3786
msgid "Job Event Hosts List"
msgstr ""
-#: awx/api/views/__init__.py:3759
+#: awx/api/views/__init__.py:3801
msgid "Job Events List"
msgstr ""
-#: awx/api/views/__init__.py:3970
+#: awx/api/views/__init__.py:4012
msgid "Ad Hoc Command Events List"
msgstr ""
-#: awx/api/views/__init__.py:4215
+#: awx/api/views/__init__.py:4257
msgid "Delete not allowed while there are pending notifications"
msgstr ""
-#: awx/api/views/__init__.py:4223
+#: awx/api/views/__init__.py:4265
msgid "Notification Template Test"
msgstr ""
-#: awx/api/views/__init__.py:4483 awx/api/views/__init__.py:4498
+#: awx/api/views/__init__.py:4525 awx/api/views/__init__.py:4540
msgid "User does not have permission to approve or deny this workflow."
msgstr ""
-#: awx/api/views/__init__.py:4485 awx/api/views/__init__.py:4500
+#: awx/api/views/__init__.py:4527 awx/api/views/__init__.py:4542
msgid "This workflow step has already been approved or denied."
msgstr ""
@@ -1380,7 +1421,11 @@ msgstr ""
msgid "Cannot delete inventory script."
msgstr ""
-#: awx/api/views/inventory.py:149
+#: awx/api/views/inventory.py:137
+msgid "You cannot turn a regular inventory into a \"smart\" inventory."
+msgstr ""
+
+#: awx/api/views/inventory.py:150
#, python-brace-format
msgid "{0}"
msgstr ""
@@ -1405,71 +1450,76 @@ msgstr ""
msgid "Related job {} is still processing events."
msgstr ""
-#: awx/api/views/root.py:49 awx/templates/rest_framework/api.html:28
+#: awx/api/views/organization.py:230
+#, python-brace-format
+msgid "Credential must be a Galaxy credential, not {sub.credential_type.name}."
+msgstr ""
+
+#: awx/api/views/root.py:50 awx/templates/rest_framework/api.html:28
msgid "REST API"
msgstr ""
-#: awx/api/views/root.py:59 awx/templates/rest_framework/api.html:4
+#: awx/api/views/root.py:60 awx/templates/rest_framework/api.html:4
msgid "AWX REST API"
msgstr ""
-#: awx/api/views/root.py:72
+#: awx/api/views/root.py:73
msgid "API OAuth 2 Authorization Root"
msgstr ""
-#: awx/api/views/root.py:139
+#: awx/api/views/root.py:140
msgid "Version 2"
msgstr ""
-#: awx/api/views/root.py:148
+#: awx/api/views/root.py:149
msgid "Ping"
msgstr ""
-#: awx/api/views/root.py:180 awx/api/views/root.py:225 awx/conf/apps.py:10
+#: awx/api/views/root.py:181 awx/api/views/root.py:226 awx/conf/apps.py:10
msgid "Configuration"
msgstr ""
-#: awx/api/views/root.py:202 awx/api/views/root.py:308
+#: awx/api/views/root.py:203 awx/api/views/root.py:310
msgid "Invalid License"
msgstr ""
-#: awx/api/views/root.py:207
+#: awx/api/views/root.py:208
msgid "The provided credentials are invalid (HTTP 401)."
msgstr ""
-#: awx/api/views/root.py:209
+#: awx/api/views/root.py:210
msgid "Unable to connect to proxy server."
msgstr ""
-#: awx/api/views/root.py:211
+#: awx/api/views/root.py:212
msgid "Could not connect to subscription service."
msgstr ""
-#: awx/api/views/root.py:284
+#: awx/api/views/root.py:286
msgid "Invalid license data"
msgstr ""
-#: awx/api/views/root.py:286
+#: awx/api/views/root.py:288
msgid "Missing 'eula_accepted' property"
msgstr ""
-#: awx/api/views/root.py:290
+#: awx/api/views/root.py:292
msgid "'eula_accepted' value is invalid"
msgstr ""
-#: awx/api/views/root.py:293
+#: awx/api/views/root.py:295
msgid "'eula_accepted' must be True"
msgstr ""
-#: awx/api/views/root.py:300
+#: awx/api/views/root.py:302
msgid "Invalid JSON"
msgstr ""
-#: awx/api/views/root.py:319
+#: awx/api/views/root.py:321
msgid "Invalid license"
msgstr ""
-#: awx/api/views/root.py:327
+#: awx/api/views/root.py:329
msgid "Failed to remove license."
msgstr ""
@@ -1660,11 +1710,11 @@ msgstr ""
msgid "Expected a list of tuples of max length 2 but got {input_type} instead."
msgstr ""
-#: awx/conf/registry.py:73 awx/conf/tests/unit/test_registry.py:155
+#: awx/conf/registry.py:73 awx/conf/tests/unit/test_registry.py:156
msgid "All"
msgstr ""
-#: awx/conf/registry.py:74 awx/conf/tests/unit/test_registry.py:156
+#: awx/conf/registry.py:74 awx/conf/tests/unit/test_registry.py:157
msgid "Changed"
msgstr ""
@@ -1672,59 +1722,57 @@ msgstr ""
msgid "User-Defaults"
msgstr ""
-#: awx/conf/registry.py:143
+#: awx/conf/registry.py:145
msgid "This value has been set manually in a settings file."
msgstr ""
-#: awx/conf/tests/unit/test_registry.py:46
-#: awx/conf/tests/unit/test_registry.py:56
-#: awx/conf/tests/unit/test_registry.py:72
-#: awx/conf/tests/unit/test_registry.py:87
-#: awx/conf/tests/unit/test_registry.py:100
-#: awx/conf/tests/unit/test_registry.py:106
-#: awx/conf/tests/unit/test_registry.py:126
-#: awx/conf/tests/unit/test_registry.py:132
-#: awx/conf/tests/unit/test_registry.py:145
-#: awx/conf/tests/unit/test_registry.py:157
-#: awx/conf/tests/unit/test_registry.py:166
-#: awx/conf/tests/unit/test_registry.py:172
-#: awx/conf/tests/unit/test_registry.py:184
-#: awx/conf/tests/unit/test_registry.py:191
-#: awx/conf/tests/unit/test_registry.py:233
-#: awx/conf/tests/unit/test_registry.py:251
-#: awx/conf/tests/unit/test_settings.py:79
-#: awx/conf/tests/unit/test_settings.py:97
-#: awx/conf/tests/unit/test_settings.py:112
-#: awx/conf/tests/unit/test_settings.py:127
-#: awx/conf/tests/unit/test_settings.py:143
-#: awx/conf/tests/unit/test_settings.py:156
-#: awx/conf/tests/unit/test_settings.py:173
-#: awx/conf/tests/unit/test_settings.py:189
-#: awx/conf/tests/unit/test_settings.py:200
-#: awx/conf/tests/unit/test_settings.py:216
-#: awx/conf/tests/unit/test_settings.py:237
-#: awx/conf/tests/unit/test_settings.py:259
-#: awx/conf/tests/unit/test_settings.py:285
-#: awx/conf/tests/unit/test_settings.py:299
-#: awx/conf/tests/unit/test_settings.py:323
+#: awx/conf/tests/unit/test_registry.py:47
+#: awx/conf/tests/unit/test_registry.py:57
+#: awx/conf/tests/unit/test_registry.py:73
+#: awx/conf/tests/unit/test_registry.py:88
+#: awx/conf/tests/unit/test_registry.py:101
+#: awx/conf/tests/unit/test_registry.py:107
+#: awx/conf/tests/unit/test_registry.py:127
+#: awx/conf/tests/unit/test_registry.py:133
+#: awx/conf/tests/unit/test_registry.py:146
+#: awx/conf/tests/unit/test_registry.py:158
+#: awx/conf/tests/unit/test_registry.py:167
+#: awx/conf/tests/unit/test_registry.py:173
+#: awx/conf/tests/unit/test_registry.py:185
+#: awx/conf/tests/unit/test_registry.py:192
+#: awx/conf/tests/unit/test_registry.py:234
+#: awx/conf/tests/unit/test_registry.py:252
+#: awx/conf/tests/unit/test_settings.py:73
+#: awx/conf/tests/unit/test_settings.py:91
+#: awx/conf/tests/unit/test_settings.py:106
+#: awx/conf/tests/unit/test_settings.py:121
+#: awx/conf/tests/unit/test_settings.py:137
+#: awx/conf/tests/unit/test_settings.py:150
+#: awx/conf/tests/unit/test_settings.py:167
+#: awx/conf/tests/unit/test_settings.py:183
+#: awx/conf/tests/unit/test_settings.py:194
+#: awx/conf/tests/unit/test_settings.py:210
+#: awx/conf/tests/unit/test_settings.py:231
+#: awx/conf/tests/unit/test_settings.py:254
+#: awx/conf/tests/unit/test_settings.py:268
+#: awx/conf/tests/unit/test_settings.py:292
+#: awx/conf/tests/unit/test_settings.py:312
+#: awx/conf/tests/unit/test_settings.py:329
#: awx/conf/tests/unit/test_settings.py:343
-#: awx/conf/tests/unit/test_settings.py:360
-#: awx/conf/tests/unit/test_settings.py:374
-#: awx/conf/tests/unit/test_settings.py:398
-#: awx/conf/tests/unit/test_settings.py:411
-#: awx/conf/tests/unit/test_settings.py:430
-#: awx/conf/tests/unit/test_settings.py:466 awx/main/conf.py:24
-#: awx/main/conf.py:33 awx/main/conf.py:43 awx/main/conf.py:53
-#: awx/main/conf.py:65 awx/main/conf.py:78 awx/main/conf.py:91
-#: awx/main/conf.py:116 awx/main/conf.py:129 awx/main/conf.py:142
-#: awx/main/conf.py:154 awx/main/conf.py:162 awx/main/conf.py:173
-#: awx/main/conf.py:405 awx/main/conf.py:830 awx/main/conf.py:840
-#: awx/main/conf.py:852
+#: awx/conf/tests/unit/test_settings.py:367
+#: awx/conf/tests/unit/test_settings.py:380
+#: awx/conf/tests/unit/test_settings.py:399
+#: awx/conf/tests/unit/test_settings.py:435 awx/main/conf.py:23
+#: awx/main/conf.py:32 awx/main/conf.py:42 awx/main/conf.py:52
+#: awx/main/conf.py:64 awx/main/conf.py:77 awx/main/conf.py:90
+#: awx/main/conf.py:115 awx/main/conf.py:128 awx/main/conf.py:141
+#: awx/main/conf.py:153 awx/main/conf.py:161 awx/main/conf.py:172
+#: awx/main/conf.py:395 awx/main/conf.py:750 awx/main/conf.py:762
msgid "System"
msgstr ""
-#: awx/conf/tests/unit/test_registry.py:151
-#: awx/conf/tests/unit/test_registry.py:158
+#: awx/conf/tests/unit/test_registry.py:152
+#: awx/conf/tests/unit/test_registry.py:159
msgid "OtherSystem"
msgstr ""
@@ -1791,112 +1839,172 @@ msgstr ""
msgid "Unable to change inventory on a group."
msgstr ""
-#: awx/main/access.py:1264
+#: awx/main/access.py:1261
msgid "Unable to change organization on a team."
msgstr ""
-#: awx/main/access.py:1280
+#: awx/main/access.py:1277
msgid "The {} role cannot be assigned to a team"
msgstr ""
-#: awx/main/access.py:1474
+#: awx/main/access.py:1471
msgid "Insufficient access to Job Template credentials."
msgstr ""
-#: awx/main/access.py:1639 awx/main/access.py:2063
+#: awx/main/access.py:1635 awx/main/access.py:2059
msgid "Job was launched with secret prompts provided by another user."
msgstr ""
-#: awx/main/access.py:1648
+#: awx/main/access.py:1644
msgid "Job has been orphaned from its job template and organization."
msgstr ""
-#: awx/main/access.py:1650
+#: awx/main/access.py:1646
msgid "Job was launched with prompted fields you do not have access to."
msgstr ""
-#: awx/main/access.py:1652
+#: awx/main/access.py:1648
msgid ""
"Job was launched with unknown prompted fields. Organization admin "
"permissions required."
msgstr ""
-#: awx/main/access.py:2053
+#: awx/main/access.py:2049
msgid "Workflow Job was launched with unknown prompts."
msgstr ""
-#: awx/main/access.py:2065
+#: awx/main/access.py:2061
msgid "Job was launched with prompts you lack access to."
msgstr ""
-#: awx/main/access.py:2067
+#: awx/main/access.py:2063
msgid "Job was launched with prompts no longer accepted."
msgstr ""
-#: awx/main/access.py:2079
+#: awx/main/access.py:2075
msgid ""
"You do not have permission to the workflow job resources required for "
"relaunch."
msgstr ""
+#: awx/main/analytics/collectors.py:36
+msgid "General platform configuration."
+msgstr ""
+
+#: awx/main/analytics/collectors.py:68
+msgid "Counts of objects such as organizations, inventories, and projects"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:103
+msgid "Counts of users and teams by organization"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:115
+msgid "Counts of credentials by credential type"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:127
+msgid "Inventories, their inventory sources, and host counts"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:152
+msgid "Counts of projects by source control type"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:171
+msgid "Cluster topology and capacity"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:197
+msgid "Counts of jobs by status"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:207
+msgid "Counts of jobs by execution node"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:222
+msgid "Metadata about the analytics collected"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:285
+msgid "Automation task records"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:314
+msgid "Data on jobs run"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:351
+msgid "Data on job templates"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:374
+msgid "Data on workflow runs"
+msgstr ""
+
+#: awx/main/analytics/collectors.py:410
+msgid "Data on workflows"
+msgstr ""
+
#: awx/main/apps.py:8
msgid "Main"
msgstr ""
-#: awx/main/conf.py:22
+#: awx/main/conf.py:21
msgid "Enable Activity Stream"
msgstr ""
-#: awx/main/conf.py:23
+#: awx/main/conf.py:22
msgid "Enable capturing activity for the activity stream."
msgstr ""
-#: awx/main/conf.py:31
+#: awx/main/conf.py:30
msgid "Enable Activity Stream for Inventory Sync"
msgstr ""
-#: awx/main/conf.py:32
+#: awx/main/conf.py:31
msgid ""
"Enable capturing activity for the activity stream when running inventory "
"sync."
msgstr ""
-#: awx/main/conf.py:40
+#: awx/main/conf.py:39
msgid "All Users Visible to Organization Admins"
msgstr ""
-#: awx/main/conf.py:41
+#: awx/main/conf.py:40
msgid ""
"Controls whether any Organization Admin can view all users and teams, even "
"those not associated with their Organization."
msgstr ""
-#: awx/main/conf.py:50
+#: awx/main/conf.py:49
msgid "Organization Admins Can Manage Users and Teams"
msgstr ""
-#: awx/main/conf.py:51
+#: awx/main/conf.py:50
msgid ""
"Controls whether any Organization Admin has the privileges to create and "
"manage users and teams. You may want to disable this ability if you are "
"using an LDAP or SAML integration."
msgstr ""
-#: awx/main/conf.py:62
+#: awx/main/conf.py:61
msgid "Base URL of the Tower host"
msgstr ""
-#: awx/main/conf.py:63
+#: awx/main/conf.py:62
msgid ""
"This setting is used by services like notifications to render a valid url to "
"the Tower host."
msgstr ""
-#: awx/main/conf.py:72
+#: awx/main/conf.py:71
msgid "Remote Host Headers"
msgstr ""
-#: awx/main/conf.py:73
+#: awx/main/conf.py:72
msgid ""
"HTTP headers and meta keys to search to determine remote host name or IP. "
"Add additional items to this list, such as \"HTTP_X_FORWARDED_FOR\", if "
@@ -1904,114 +2012,112 @@ msgid ""
"Adminstrator guide for more details."
msgstr ""
-#: awx/main/conf.py:85
-msgid "Proxy IP Whitelist"
+#: awx/main/conf.py:84
+msgid "Proxy IP Allowed List"
msgstr ""
-#: awx/main/conf.py:86
+#: awx/main/conf.py:85
msgid ""
"If Tower is behind a reverse proxy/load balancer, use this setting to "
-"whitelist the proxy IP addresses from which Tower should trust custom "
+"configure the proxy IP addresses from which Tower should trust custom "
"REMOTE_HOST_HEADERS header values. If this setting is an empty list (the "
"default), the headers specified by REMOTE_HOST_HEADERS will be trusted "
"unconditionally')"
msgstr ""
-#: awx/main/conf.py:112
+#: awx/main/conf.py:111
msgid "License"
msgstr ""
-#: awx/main/conf.py:113
+#: awx/main/conf.py:112
msgid ""
"The license controls which features and functionality are enabled. Use /api/"
"v2/config/ to update or change the license."
msgstr ""
-#: awx/main/conf.py:127
+#: awx/main/conf.py:126
msgid "Red Hat customer username"
msgstr ""
-#: awx/main/conf.py:128
+#: awx/main/conf.py:127
msgid ""
"This username is used to retrieve license information and to send Automation "
"Analytics"
msgstr ""
-#: awx/main/conf.py:140
+#: awx/main/conf.py:139
msgid "Red Hat customer password"
msgstr ""
-#: awx/main/conf.py:141
+#: awx/main/conf.py:140
msgid ""
"This password is used to retrieve license information and to send Automation "
"Analytics"
msgstr ""
-#: awx/main/conf.py:152
-msgid "Automation Analytics upload URL."
+#: awx/main/conf.py:151
+msgid "Automation Analytics upload URL"
msgstr ""
-#: awx/main/conf.py:153
+#: awx/main/conf.py:152
msgid ""
"This setting is used to to configure data collection for the Automation "
"Analytics dashboard"
msgstr ""
-#: awx/main/conf.py:161
+#: awx/main/conf.py:160
msgid "Unique identifier for an AWX/Tower installation"
msgstr ""
-#: awx/main/conf.py:170
+#: awx/main/conf.py:169
msgid "Custom virtual environment paths"
msgstr ""
-#: awx/main/conf.py:171
+#: awx/main/conf.py:170
msgid ""
"Paths where Tower will look for custom virtual environments (in addition to /"
"var/lib/awx/venv/). Enter one path per line."
msgstr ""
-#: awx/main/conf.py:181
+#: awx/main/conf.py:180
msgid "Ansible Modules Allowed for Ad Hoc Jobs"
msgstr ""
-#: awx/main/conf.py:182
+#: awx/main/conf.py:181
msgid "List of modules allowed to be used by ad-hoc jobs."
msgstr ""
-#: awx/main/conf.py:183 awx/main/conf.py:205 awx/main/conf.py:214
-#: awx/main/conf.py:225 awx/main/conf.py:235 awx/main/conf.py:245
-#: awx/main/conf.py:256 awx/main/conf.py:267 awx/main/conf.py:278
-#: awx/main/conf.py:290 awx/main/conf.py:299 awx/main/conf.py:312
-#: awx/main/conf.py:325 awx/main/conf.py:337 awx/main/conf.py:348
-#: awx/main/conf.py:359 awx/main/conf.py:371 awx/main/conf.py:383
-#: awx/main/conf.py:394 awx/main/conf.py:414 awx/main/conf.py:424
-#: awx/main/conf.py:434 awx/main/conf.py:450 awx/main/conf.py:463
-#: awx/main/conf.py:477 awx/main/conf.py:491 awx/main/conf.py:503
-#: awx/main/conf.py:513 awx/main/conf.py:524 awx/main/conf.py:534
-#: awx/main/conf.py:545 awx/main/conf.py:555 awx/main/conf.py:565
-#: awx/main/conf.py:577 awx/main/conf.py:589 awx/main/conf.py:601
-#: awx/main/conf.py:615 awx/main/conf.py:627
+#: awx/main/conf.py:182 awx/main/conf.py:204 awx/main/conf.py:213
+#: awx/main/conf.py:224 awx/main/conf.py:234 awx/main/conf.py:244
+#: awx/main/conf.py:254 awx/main/conf.py:266 awx/main/conf.py:279
+#: awx/main/conf.py:289 awx/main/conf.py:302 awx/main/conf.py:315
+#: awx/main/conf.py:327 awx/main/conf.py:338 awx/main/conf.py:349
+#: awx/main/conf.py:361 awx/main/conf.py:373 awx/main/conf.py:384
+#: awx/main/conf.py:404 awx/main/conf.py:414 awx/main/conf.py:424
+#: awx/main/conf.py:437 awx/main/conf.py:448 awx/main/conf.py:458
+#: awx/main/conf.py:469 awx/main/conf.py:479 awx/main/conf.py:489
+#: awx/main/conf.py:501 awx/main/conf.py:514 awx/main/conf.py:527
+#: awx/main/conf.py:542 awx/main/conf.py:555
msgid "Jobs"
msgstr ""
-#: awx/main/conf.py:192
+#: awx/main/conf.py:191
msgid "Always"
msgstr ""
-#: awx/main/conf.py:193
+#: awx/main/conf.py:192
msgid "Never"
msgstr ""
-#: awx/main/conf.py:194
+#: awx/main/conf.py:193
msgid "Only On Job Template Definitions"
msgstr ""
-#: awx/main/conf.py:197
+#: awx/main/conf.py:196
msgid "When can extra variables contain Jinja templates?"
msgstr ""
-#: awx/main/conf.py:199
+#: awx/main/conf.py:198
msgid ""
"Ansible allows variable substitution via the Jinja2 templating language for "
"--extra-vars. This poses a potential security risk where Tower users with "
@@ -2020,358 +2126,294 @@ msgid ""
"to \"template\" or \"never\"."
msgstr ""
-#: awx/main/conf.py:212
+#: awx/main/conf.py:211
msgid "Enable job isolation"
msgstr ""
-#: awx/main/conf.py:213
+#: awx/main/conf.py:212
msgid ""
"Isolates an Ansible job from protected parts of the system to prevent "
"exposing sensitive information."
msgstr ""
-#: awx/main/conf.py:221
+#: awx/main/conf.py:220
msgid "Job execution path"
msgstr ""
-#: awx/main/conf.py:222
+#: awx/main/conf.py:221
msgid ""
"The directory in which Tower will create new temporary directories for job "
"execution and isolation (such as credential files and custom inventory "
"scripts)."
msgstr ""
-#: awx/main/conf.py:233
+#: awx/main/conf.py:232
msgid "Paths to hide from isolated jobs"
msgstr ""
-#: awx/main/conf.py:234
+#: awx/main/conf.py:233
msgid ""
"Additional paths to hide from isolated processes. Enter one path per line."
msgstr ""
-#: awx/main/conf.py:243
+#: awx/main/conf.py:242
msgid "Paths to expose to isolated jobs"
msgstr ""
-#: awx/main/conf.py:244
+#: awx/main/conf.py:243
msgid ""
-"Whitelist of paths that would otherwise be hidden to expose to isolated "
-"jobs. Enter one path per line."
+"List of paths that would otherwise be hidden to expose to isolated jobs. "
+"Enter one path per line."
msgstr ""
-#: awx/main/conf.py:254
-msgid "Verbosity level for isolated node management tasks"
-msgstr ""
-
-#: awx/main/conf.py:255
-msgid ""
-"This can be raised to aid in debugging connection issues for isolated task "
-"execution"
-msgstr ""
-
-#: awx/main/conf.py:265
+#: awx/main/conf.py:252
msgid "Isolated status check interval"
msgstr ""
-#: awx/main/conf.py:266
+#: awx/main/conf.py:253
msgid ""
"The number of seconds to sleep between status checks for jobs running on "
"isolated instances."
msgstr ""
-#: awx/main/conf.py:275
+#: awx/main/conf.py:263
msgid "Isolated launch timeout"
msgstr ""
-#: awx/main/conf.py:276
+#: awx/main/conf.py:264
msgid ""
"The timeout (in seconds) for launching jobs on isolated instances. This "
"includes the time needed to copy source control files (playbooks) to the "
"isolated instance."
msgstr ""
-#: awx/main/conf.py:287
+#: awx/main/conf.py:276
msgid "Isolated connection timeout"
msgstr ""
-#: awx/main/conf.py:288
+#: awx/main/conf.py:277
msgid ""
"Ansible SSH connection timeout (in seconds) to use when communicating with "
"isolated instances. Value should be substantially greater than expected "
"network latency."
msgstr ""
-#: awx/main/conf.py:297
+#: awx/main/conf.py:287
msgid "Isolated host key checking"
msgstr ""
-#: awx/main/conf.py:298
+#: awx/main/conf.py:288
msgid ""
"When set to True, AWX will enforce strict host key checking for "
"communication with isolated nodes."
msgstr ""
-#: awx/main/conf.py:308
+#: awx/main/conf.py:298
msgid "Generate RSA keys for isolated instances"
msgstr ""
-#: awx/main/conf.py:309
+#: awx/main/conf.py:299
msgid ""
"If set, a random RSA key will be generated and distributed to isolated "
"instances. To disable this behavior and manage authentication for isolated "
"instances outside of Tower, disable this setting."
msgstr ""
-#: awx/main/conf.py:323 awx/main/conf.py:324
+#: awx/main/conf.py:313 awx/main/conf.py:314
msgid "The RSA private key for SSH traffic to isolated instances"
msgstr ""
-#: awx/main/conf.py:335 awx/main/conf.py:336
+#: awx/main/conf.py:325 awx/main/conf.py:326
msgid "The RSA public key for SSH traffic to isolated instances"
msgstr ""
-#: awx/main/conf.py:345
+#: awx/main/conf.py:335
msgid "Enable detailed resource profiling on all playbook runs"
msgstr ""
-#: awx/main/conf.py:346
+#: awx/main/conf.py:336
msgid ""
"If set, detailed resource profiling data will be collected on all jobs. This "
"data can be gathered with `sosreport`."
msgstr ""
-#: awx/main/conf.py:356
+#: awx/main/conf.py:346
msgid "Interval (in seconds) between polls for cpu usage."
msgstr ""
-#: awx/main/conf.py:357
+#: awx/main/conf.py:347
msgid ""
"Interval (in seconds) between polls for cpu usage. Setting this lower than "
"the default will affect playbook performance."
msgstr ""
-#: awx/main/conf.py:368
+#: awx/main/conf.py:358
msgid "Interval (in seconds) between polls for memory usage."
msgstr ""
-#: awx/main/conf.py:369
+#: awx/main/conf.py:359
msgid ""
"Interval (in seconds) between polls for memory usage. Setting this lower "
"than the default will affect playbook performance."
msgstr ""
-#: awx/main/conf.py:380
+#: awx/main/conf.py:370
msgid "Interval (in seconds) between polls for PID count."
msgstr ""
-#: awx/main/conf.py:381
+#: awx/main/conf.py:371
msgid ""
"Interval (in seconds) between polls for PID count. Setting this lower than "
"the default will affect playbook performance."
msgstr ""
-#: awx/main/conf.py:392
+#: awx/main/conf.py:382
msgid "Extra Environment Variables"
msgstr ""
-#: awx/main/conf.py:393
+#: awx/main/conf.py:383
msgid ""
"Additional environment variables set for playbook runs, inventory updates, "
"project updates, and notification sending."
msgstr ""
-#: awx/main/conf.py:403
+#: awx/main/conf.py:393
msgid "Gather data for Automation Analytics"
msgstr ""
-#: awx/main/conf.py:404
+#: awx/main/conf.py:394
msgid "Enables Tower to gather data on automation and send it to Red Hat."
msgstr ""
-#: awx/main/conf.py:412
+#: awx/main/conf.py:402
msgid "Run Project Updates With Higher Verbosity"
msgstr ""
-#: awx/main/conf.py:413
+#: awx/main/conf.py:403
msgid ""
"Adds the CLI -vvv flag to ansible-playbook runs of project_update.yml used "
"for project updates."
msgstr ""
-#: awx/main/conf.py:422
+#: awx/main/conf.py:412
msgid "Enable Role Download"
msgstr ""
-#: awx/main/conf.py:423
+#: awx/main/conf.py:413
msgid ""
"Allows roles to be dynamically downloaded from a requirements.yml file for "
"SCM projects."
msgstr ""
-#: awx/main/conf.py:432
+#: awx/main/conf.py:422
msgid "Enable Collection(s) Download"
msgstr ""
-#: awx/main/conf.py:433
+#: awx/main/conf.py:423
msgid ""
"Allows collections to be dynamically downloaded from a requirements.yml file "
"for SCM projects."
msgstr ""
-#: awx/main/conf.py:443
-msgid "Primary Galaxy Server URL"
+#: awx/main/conf.py:432
+msgid "Follow symlinks"
+msgstr ""
+
+#: awx/main/conf.py:434
+msgid ""
+"Follow symbolic links when scanning for playbooks. Be aware that setting "
+"this to True can lead to infinite recursion if a link points to a parent "
+"directory of itself."
msgstr ""
#: awx/main/conf.py:445
-msgid ""
-"For organizations that run their own Galaxy service, this gives the option "
-"to specify a host as the primary galaxy server. Requirements will be "
-"downloaded from the primary if the specific role or collection is available "
-"there. If the content is not avilable in the primary, or if this field is "
-"left blank, it will default to galaxy.ansible.com."
-msgstr ""
-
-#: awx/main/conf.py:459
-msgid "Primary Galaxy Server Username"
-msgstr ""
-
-#: awx/main/conf.py:460
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The username to use for basic authentication against the Galaxy "
-"instance, this is mutually exclusive with PRIMARY_GALAXY_TOKEN."
-msgstr ""
-
-#: awx/main/conf.py:473
-msgid "Primary Galaxy Server Password"
-msgstr ""
-
-#: awx/main/conf.py:474
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The password to use for basic authentication against the Galaxy "
-"instance, this is mutually exclusive with PRIMARY_GALAXY_TOKEN."
-msgstr ""
-
-#: awx/main/conf.py:487
-msgid "Primary Galaxy Server Token"
-msgstr ""
-
-#: awx/main/conf.py:488
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The token to use for connecting with the Galaxy instance, this is "
-"mutually exclusive with corresponding username and password settings."
-msgstr ""
-
-#: awx/main/conf.py:500
-msgid "Primary Galaxy Authentication URL"
-msgstr ""
-
-#: awx/main/conf.py:501
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The token_endpoint of a Keycloak server."
-msgstr ""
-
-#: awx/main/conf.py:511
-msgid "Allow Access to Public Galaxy"
-msgstr ""
-
-#: awx/main/conf.py:512
-msgid ""
-"Allow or deny access to the public Ansible Galaxy during project updates."
-msgstr ""
-
-#: awx/main/conf.py:521
msgid "Ignore Ansible Galaxy SSL Certificate Verification"
msgstr ""
-#: awx/main/conf.py:522
+#: awx/main/conf.py:446
msgid ""
-"If set to true, certificate validation will not be done wheninstalling "
+"If set to true, certificate validation will not be done when installing "
"content from any Galaxy server."
msgstr ""
-#: awx/main/conf.py:532
+#: awx/main/conf.py:456
msgid "Standard Output Maximum Display Size"
msgstr ""
-#: awx/main/conf.py:533
+#: awx/main/conf.py:457
msgid ""
"Maximum Size of Standard Output in bytes to display before requiring the "
"output be downloaded."
msgstr ""
-#: awx/main/conf.py:542
+#: awx/main/conf.py:466
msgid "Job Event Standard Output Maximum Display Size"
msgstr ""
-#: awx/main/conf.py:544
+#: awx/main/conf.py:468
msgid ""
"Maximum Size of Standard Output in bytes to display for a single job or ad "
"hoc command event. `stdout` will end with `…` when truncated."
msgstr ""
-#: awx/main/conf.py:553
+#: awx/main/conf.py:477
msgid "Maximum Scheduled Jobs"
msgstr ""
-#: awx/main/conf.py:554
+#: awx/main/conf.py:478
msgid ""
"Maximum number of the same job template that can be waiting to run when "
"launching from a schedule before no more are created."
msgstr ""
-#: awx/main/conf.py:563
+#: awx/main/conf.py:487
msgid "Ansible Callback Plugins"
msgstr ""
-#: awx/main/conf.py:564
+#: awx/main/conf.py:488
msgid ""
"List of paths to search for extra callback plugins to be used when running "
"jobs. Enter one path per line."
msgstr ""
-#: awx/main/conf.py:574
+#: awx/main/conf.py:498
msgid "Default Job Timeout"
msgstr ""
-#: awx/main/conf.py:575
+#: awx/main/conf.py:499
msgid ""
"Maximum time in seconds to allow jobs to run. Use value of 0 to indicate "
"that no timeout should be imposed. A timeout set on an individual job "
"template will override this."
msgstr ""
-#: awx/main/conf.py:586
+#: awx/main/conf.py:511
msgid "Default Inventory Update Timeout"
msgstr ""
-#: awx/main/conf.py:587
+#: awx/main/conf.py:512
msgid ""
"Maximum time in seconds to allow inventory updates to run. Use value of 0 to "
"indicate that no timeout should be imposed. A timeout set on an individual "
"inventory source will override this."
msgstr ""
-#: awx/main/conf.py:598
+#: awx/main/conf.py:524
msgid "Default Project Update Timeout"
msgstr ""
-#: awx/main/conf.py:599
+#: awx/main/conf.py:525
msgid ""
"Maximum time in seconds to allow project updates to run. Use value of 0 to "
"indicate that no timeout should be imposed. A timeout set on an individual "
"project will override this."
msgstr ""
-#: awx/main/conf.py:610
+#: awx/main/conf.py:537
msgid "Per-Host Ansible Fact Cache Timeout"
msgstr ""
-#: awx/main/conf.py:611
+#: awx/main/conf.py:538
msgid ""
"Maximum time, in seconds, that stored Ansible facts are considered valid "
"since the last time they were modified. Only valid, non-stale, facts will be "
@@ -2380,74 +2422,74 @@ msgid ""
"timeout should be imposed."
msgstr ""
-#: awx/main/conf.py:624
-msgid "Maximum number of forks per job."
+#: awx/main/conf.py:552
+msgid "Maximum number of forks per job"
msgstr ""
-#: awx/main/conf.py:625
+#: awx/main/conf.py:553
msgid ""
"Saving a Job Template with more than this number of forks will result in an "
"error. When set to 0, no limit is applied."
msgstr ""
-#: awx/main/conf.py:636
+#: awx/main/conf.py:564
msgid "Logging Aggregator"
msgstr ""
-#: awx/main/conf.py:637
+#: awx/main/conf.py:565
msgid "Hostname/IP where external logs will be sent to."
msgstr ""
-#: awx/main/conf.py:638 awx/main/conf.py:649 awx/main/conf.py:661
-#: awx/main/conf.py:671 awx/main/conf.py:683 awx/main/conf.py:698
-#: awx/main/conf.py:710 awx/main/conf.py:719 awx/main/conf.py:729
-#: awx/main/conf.py:741 awx/main/conf.py:752 awx/main/conf.py:764
-#: awx/main/conf.py:777 awx/main/conf.py:787 awx/main/conf.py:799
-#: awx/main/conf.py:810 awx/main/conf.py:820
+#: awx/main/conf.py:566 awx/main/conf.py:577 awx/main/conf.py:589
+#: awx/main/conf.py:599 awx/main/conf.py:611 awx/main/conf.py:626
+#: awx/main/conf.py:638 awx/main/conf.py:647 awx/main/conf.py:657
+#: awx/main/conf.py:669 awx/main/conf.py:680 awx/main/conf.py:693
+#: awx/main/conf.py:706 awx/main/conf.py:718 awx/main/conf.py:729
+#: awx/main/conf.py:739
msgid "Logging"
msgstr ""
-#: awx/main/conf.py:646
+#: awx/main/conf.py:574
msgid "Logging Aggregator Port"
msgstr ""
-#: awx/main/conf.py:647
+#: awx/main/conf.py:575
msgid ""
"Port on Logging Aggregator to send logs to (if required and not provided in "
"Logging Aggregator)."
msgstr ""
-#: awx/main/conf.py:659
+#: awx/main/conf.py:587
msgid "Logging Aggregator Type"
msgstr ""
-#: awx/main/conf.py:660
+#: awx/main/conf.py:588
msgid "Format messages for the chosen log aggregator."
msgstr ""
-#: awx/main/conf.py:669
+#: awx/main/conf.py:597
msgid "Logging Aggregator Username"
msgstr ""
-#: awx/main/conf.py:670
+#: awx/main/conf.py:598
msgid "Username for external log aggregator (if required; HTTP/s only)."
msgstr ""
-#: awx/main/conf.py:681
+#: awx/main/conf.py:609
msgid "Logging Aggregator Password/Token"
msgstr ""
-#: awx/main/conf.py:682
+#: awx/main/conf.py:610
msgid ""
"Password or authentication token for external log aggregator (if required; "
"HTTP/s only)."
msgstr ""
-#: awx/main/conf.py:691
+#: awx/main/conf.py:619
msgid "Loggers Sending Data to Log Aggregator Form"
msgstr ""
-#: awx/main/conf.py:692
+#: awx/main/conf.py:620
msgid ""
"List of loggers that will send HTTP logs to the collector, these can include "
"any or all of: \n"
@@ -2457,11 +2499,11 @@ msgid ""
"system_tracking - facts gathered from scan jobs."
msgstr ""
-#: awx/main/conf.py:705
+#: awx/main/conf.py:633
msgid "Log System Tracking Facts Individually"
msgstr ""
-#: awx/main/conf.py:706
+#: awx/main/conf.py:634
msgid ""
"If set, system tracking facts will be sent for each package, service, or "
"other item found in a scan, allowing for greater search query granularity. "
@@ -2469,47 +2511,47 @@ msgid ""
"efficiency in fact processing."
msgstr ""
-#: awx/main/conf.py:717
+#: awx/main/conf.py:645
msgid "Enable External Logging"
msgstr ""
-#: awx/main/conf.py:718
+#: awx/main/conf.py:646
msgid "Enable sending logs to external log aggregator."
msgstr ""
-#: awx/main/conf.py:727
+#: awx/main/conf.py:655
msgid "Cluster-wide Tower unique identifier."
msgstr ""
-#: awx/main/conf.py:728
+#: awx/main/conf.py:656
msgid "Useful to uniquely identify Tower instances."
msgstr ""
-#: awx/main/conf.py:737
+#: awx/main/conf.py:665
msgid "Logging Aggregator Protocol"
msgstr ""
-#: awx/main/conf.py:738
+#: awx/main/conf.py:666
msgid ""
"Protocol used to communicate with log aggregator. HTTPS/HTTP assumes HTTPS "
"unless http:// is explicitly used in the Logging Aggregator hostname."
msgstr ""
-#: awx/main/conf.py:748
+#: awx/main/conf.py:676
msgid "TCP Connection Timeout"
msgstr ""
-#: awx/main/conf.py:749
+#: awx/main/conf.py:677
msgid ""
"Number of seconds for a TCP connection to external log aggregator to "
"timeout. Applies to HTTPS and TCP log aggregator protocols."
msgstr ""
-#: awx/main/conf.py:759
+#: awx/main/conf.py:688
msgid "Enable/disable HTTPS certificate verification"
msgstr ""
-#: awx/main/conf.py:760
+#: awx/main/conf.py:689
msgid ""
"Flag to control enable/disable of certificate verification when "
"LOG_AGGREGATOR_PROTOCOL is \"https\". If enabled, Tower's log handler will "
@@ -2517,11 +2559,11 @@ msgid ""
"connection."
msgstr ""
-#: awx/main/conf.py:772
+#: awx/main/conf.py:701
msgid "Logging Aggregator Level Threshold"
msgstr ""
-#: awx/main/conf.py:773
+#: awx/main/conf.py:702
msgid ""
"Level threshold used by log handler. Severities from lowest to highest are "
"DEBUG, INFO, WARNING, ERROR, CRITICAL. Messages less severe than the "
@@ -2529,198 +2571,144 @@ msgid ""
"anlytics ignore this setting)"
msgstr ""
-#: awx/main/conf.py:785
-msgid "Enabled external log aggregation auditing"
-msgstr ""
-
-#: awx/main/conf.py:786
-msgid ""
-"When enabled, all external logs emitted by Tower will also be written to /"
-"var/log/tower/external.log. This is an experimental setting intended to be "
-"used for debugging external log aggregation issues (and may be subject to "
-"change in the future)."
-msgstr ""
-
-#: awx/main/conf.py:795
+#: awx/main/conf.py:714
msgid "Maximum disk persistance for external log aggregation (in GB)"
msgstr ""
-#: awx/main/conf.py:796
+#: awx/main/conf.py:715
msgid ""
"Amount of data to store (in gigabytes) during an outage of the external log "
"aggregator (defaults to 1). Equivalent to the rsyslogd queue.maxdiskspace "
"setting."
msgstr ""
-#: awx/main/conf.py:806
+#: awx/main/conf.py:725
msgid "File system location for rsyslogd disk persistence"
msgstr ""
-#: awx/main/conf.py:807
+#: awx/main/conf.py:726
msgid ""
"Location to persist logs that should be retried after an outage of the "
"external log aggregator (defaults to /var/lib/awx). Equivalent to the "
"rsyslogd queue.spoolDirectory setting."
msgstr ""
-#: awx/main/conf.py:817
+#: awx/main/conf.py:736
msgid "Enable rsyslogd debugging"
msgstr ""
-#: awx/main/conf.py:818
+#: awx/main/conf.py:737
msgid ""
"Enabled high verbosity debugging for rsyslogd. Useful for debugging "
"connection issues for external log aggregation."
msgstr ""
-#: awx/main/conf.py:828
-msgid "Message Durability"
-msgstr ""
-
-#: awx/main/conf.py:829
-msgid ""
-"When set (the default), underlying queues will be persisted to disk. "
-"Disable this to enable higher message bus throughput."
-msgstr ""
-
-#: awx/main/conf.py:838
+#: awx/main/conf.py:748
msgid "Last gather date for Automation Analytics."
msgstr ""
-#: awx/main/conf.py:848
+#: awx/main/conf.py:758
msgid "Automation Analytics Gather Interval"
msgstr ""
-#: awx/main/conf.py:849
+#: awx/main/conf.py:759
msgid "Interval (in seconds) between data gathering."
msgstr ""
-#: awx/main/conf.py:871 awx/sso/conf.py:1239
+#: awx/main/conf.py:782 awx/sso/conf.py:1251
msgid "\n"
msgstr ""
-#: awx/main/conf.py:892
-msgid ""
-"A URL for Primary Galaxy must be defined before disabling public Galaxy."
-msgstr ""
-
-#: awx/main/conf.py:912
-msgid "Cannot provide field if PRIMARY_GALAXY_URL is not set."
-msgstr ""
-
-#: awx/main/conf.py:925
-#, python-brace-format
-msgid ""
-"Galaxy server settings are not available until Ansible {min_version}, you "
-"are running {current_version}."
-msgstr ""
-
-#: awx/main/conf.py:934
-msgid ""
-"Setting Galaxy token and authentication URL is mutually exclusive with "
-"username and password."
-msgstr ""
-
-#: awx/main/conf.py:937
-msgid "If authenticating via username and password, both must be provided."
-msgstr ""
-
-#: awx/main/conf.py:943
-msgid ""
-"If authenticating via token, both token and authentication URL must be "
-"provided."
-msgstr ""
-
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Sudo"
msgstr ""
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Su"
msgstr ""
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Pbrun"
msgstr ""
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Pfexec"
msgstr ""
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "DZDO"
msgstr ""
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "Pmrun"
msgstr ""
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "Runas"
msgstr ""
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Enable"
msgstr ""
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Doas"
msgstr ""
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Ksu"
msgstr ""
-#: awx/main/constants.py:20
+#: awx/main/constants.py:19
msgid "Machinectl"
msgstr ""
-#: awx/main/constants.py:20
+#: awx/main/constants.py:19
msgid "Sesu"
msgstr ""
-#: awx/main/constants.py:22
+#: awx/main/constants.py:21
msgid "None"
msgstr ""
-#: awx/main/credential_plugins/aim.py:16
+#: awx/main/credential_plugins/aim.py:11
msgid "CyberArk AIM URL"
msgstr ""
-#: awx/main/credential_plugins/aim.py:21
+#: awx/main/credential_plugins/aim.py:16
msgid "Application ID"
msgstr ""
-#: awx/main/credential_plugins/aim.py:26
+#: awx/main/credential_plugins/aim.py:21
msgid "Client Key"
msgstr ""
-#: awx/main/credential_plugins/aim.py:32
+#: awx/main/credential_plugins/aim.py:27
msgid "Client Certificate"
msgstr ""
-#: awx/main/credential_plugins/aim.py:38
+#: awx/main/credential_plugins/aim.py:33
msgid "Verify SSL Certificates"
msgstr ""
-#: awx/main/credential_plugins/aim.py:44
+#: awx/main/credential_plugins/aim.py:39
msgid "Object Query"
msgstr ""
-#: awx/main/credential_plugins/aim.py:46
+#: awx/main/credential_plugins/aim.py:41
msgid ""
"Lookup query for the object. Ex: Safe=TestSafe;Object=testAccountName123"
msgstr ""
-#: awx/main/credential_plugins/aim.py:49
+#: awx/main/credential_plugins/aim.py:44
msgid "Object Query Format"
msgstr ""
-#: awx/main/credential_plugins/aim.py:55
+#: awx/main/credential_plugins/aim.py:50
msgid "Reason"
msgstr ""
-#: awx/main/credential_plugins/aim.py:57
+#: awx/main/credential_plugins/aim.py:52
msgid ""
"Object request reason. This is only needed if it is required by the object's "
"policy."
@@ -2731,12 +2719,12 @@ msgid "Vault URL (DNS Name)"
msgstr ""
#: awx/main/credential_plugins/azure_kv.py:26
-#: awx/main/models/credential/__init__.py:960
+#: awx/main/models/credential/__init__.py:968
msgid "Client ID"
msgstr ""
#: awx/main/credential_plugins/azure_kv.py:35
-#: awx/main/models/credential/__init__.py:969
+#: awx/main/models/credential/__init__.py:977
msgid "Tenant ID"
msgstr ""
@@ -2757,166 +2745,177 @@ msgid "The name of the secret to look up."
msgstr ""
#: awx/main/credential_plugins/azure_kv.py:51
-#: awx/main/credential_plugins/conjur.py:47
+#: awx/main/credential_plugins/conjur.py:42
msgid "Secret Version"
msgstr ""
#: awx/main/credential_plugins/azure_kv.py:53
-#: awx/main/credential_plugins/conjur.py:49
-#: awx/main/credential_plugins/hashivault.py:86
+#: awx/main/credential_plugins/conjur.py:44
+#: awx/main/credential_plugins/hashivault.py:89
msgid ""
"Used to specify a specific secret version (if left empty, the latest version "
"will be used)."
msgstr ""
-#: awx/main/credential_plugins/conjur.py:18
+#: awx/main/credential_plugins/conjur.py:13
msgid "Conjur URL"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:23
+#: awx/main/credential_plugins/conjur.py:18
msgid "API Key"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:28 awx/main/models/inventory.py:1018
+#: awx/main/credential_plugins/conjur.py:23
+#: awx/main/migrations/_inventory_source_vars.py:142
msgid "Account"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:32
-#: awx/main/models/credential/__init__.py:598
-#: awx/main/models/credential/__init__.py:654
-#: awx/main/models/credential/__init__.py:712
-#: awx/main/models/credential/__init__.py:785
-#: awx/main/models/credential/__init__.py:838
-#: awx/main/models/credential/__init__.py:864
-#: awx/main/models/credential/__init__.py:891
-#: awx/main/models/credential/__init__.py:951
-#: awx/main/models/credential/__init__.py:1024
-#: awx/main/models/credential/__init__.py:1055
-#: awx/main/models/credential/__init__.py:1105
+#: awx/main/credential_plugins/conjur.py:27
+#: awx/main/models/credential/__init__.py:606
+#: awx/main/models/credential/__init__.py:662
+#: awx/main/models/credential/__init__.py:720
+#: awx/main/models/credential/__init__.py:793
+#: awx/main/models/credential/__init__.py:846
+#: awx/main/models/credential/__init__.py:872
+#: awx/main/models/credential/__init__.py:899
+#: awx/main/models/credential/__init__.py:959
+#: awx/main/models/credential/__init__.py:1032
+#: awx/main/models/credential/__init__.py:1063
+#: awx/main/models/credential/__init__.py:1113
msgid "Username"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:36
+#: awx/main/credential_plugins/conjur.py:31
msgid "Public Key Certificate"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:42
+#: awx/main/credential_plugins/conjur.py:37
msgid "Secret Identifier"
msgstr ""
-#: awx/main/credential_plugins/conjur.py:44
+#: awx/main/credential_plugins/conjur.py:39
msgid "The identifier for the secret e.g., /some/identifier"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:19
+#: awx/main/credential_plugins/hashivault.py:14
msgid "Server URL"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:22
+#: awx/main/credential_plugins/hashivault.py:17
msgid "The URL to the HashiCorp Vault"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:25
-#: awx/main/models/credential/__init__.py:990
-#: awx/main/models/credential/__init__.py:1007
+#: awx/main/credential_plugins/hashivault.py:20
+#: awx/main/models/credential/__init__.py:998
+#: awx/main/models/credential/__init__.py:1015
msgid "Token"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:28
+#: awx/main/credential_plugins/hashivault.py:23
msgid "The access token used to authenticate to the Vault server"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:31
+#: awx/main/credential_plugins/hashivault.py:26
msgid "CA Certificate"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:34
+#: awx/main/credential_plugins/hashivault.py:29
msgid ""
"The CA certificate used to verify the SSL certificate of the Vault server"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:37
+#: awx/main/credential_plugins/hashivault.py:32
msgid "AppRole role_id"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:40
+#: awx/main/credential_plugins/hashivault.py:35
msgid "The Role ID for AppRole Authentication"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:43
+#: awx/main/credential_plugins/hashivault.py:38
msgid "AppRole secret_id"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:47
+#: awx/main/credential_plugins/hashivault.py:42
msgid "The Secret ID for AppRole Authentication"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:52
-msgid "Path to Secret"
+#: awx/main/credential_plugins/hashivault.py:45
+msgid "Path to Approle Auth"
+msgstr ""
+
+#: awx/main/credential_plugins/hashivault.py:49
+msgid ""
+"The AppRole Authentication path to use if one isn't provided in the metadata "
+"when linking to an input field. Defaults to 'approle'"
msgstr ""
#: awx/main/credential_plugins/hashivault.py:54
+msgid "Path to Secret"
+msgstr ""
+
+#: awx/main/credential_plugins/hashivault.py:56
msgid "The path to the secret stored in the secret backend e.g, /some/secret/"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:57
+#: awx/main/credential_plugins/hashivault.py:59
msgid "Path to Auth"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:59
+#: awx/main/credential_plugins/hashivault.py:62
msgid "The path where the Authentication method is mounted e.g, approle"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:67
+#: awx/main/credential_plugins/hashivault.py:70
msgid "API Version"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:69
+#: awx/main/credential_plugins/hashivault.py:72
msgid ""
"API v1 is for static key/value lookups. API v2 is for versioned key/value "
"lookups."
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:74
+#: awx/main/credential_plugins/hashivault.py:77
msgid "Name of Secret Backend"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:76
+#: awx/main/credential_plugins/hashivault.py:79
msgid ""
"The name of the kv secret backend (if left empty, the first segment of the "
"secret path will be used)."
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:79
-#: awx/main/models/inventory.py:1023
+#: awx/main/credential_plugins/hashivault.py:82
+#: awx/main/migrations/_inventory_source_vars.py:147
msgid "Key Name"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:81
+#: awx/main/credential_plugins/hashivault.py:84
msgid "The name of the key to look up in the secret."
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:84
+#: awx/main/credential_plugins/hashivault.py:87
msgid "Secret Version (v2 only)"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:93
+#: awx/main/credential_plugins/hashivault.py:96
msgid "Unsigned Public Key"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:98
+#: awx/main/credential_plugins/hashivault.py:101
msgid "Role Name"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:100
+#: awx/main/credential_plugins/hashivault.py:103
msgid "The name of the role used to sign."
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:103
+#: awx/main/credential_plugins/hashivault.py:106
msgid "Valid Principals"
msgstr ""
-#: awx/main/credential_plugins/hashivault.py:105
+#: awx/main/credential_plugins/hashivault.py:108
msgid ""
"Valid principals (either usernames or hostnames) that the certificate should "
"be signed for."
@@ -2951,70 +2950,74 @@ msgstr ""
msgid "secret values must be of type string, not {}"
msgstr ""
-#: awx/main/fields.py:667
+#: awx/main/fields.py:675
#, python-format
msgid "cannot be set unless \"%s\" is set"
msgstr ""
-#: awx/main/fields.py:702
+#: awx/main/fields.py:710
msgid "must be set when SSH key is encrypted."
msgstr ""
-#: awx/main/fields.py:710
+#: awx/main/fields.py:718
msgid "should not be set when SSH key is not encrypted."
msgstr ""
-#: awx/main/fields.py:769
+#: awx/main/fields.py:777
msgid "'dependencies' is not supported for custom credentials."
msgstr ""
-#: awx/main/fields.py:783
+#: awx/main/fields.py:791
msgid "\"tower\" is a reserved field name"
msgstr ""
-#: awx/main/fields.py:790
+#: awx/main/fields.py:798
#, python-format
msgid "field IDs must be unique (%s)"
msgstr ""
-#: awx/main/fields.py:805
+#: awx/main/fields.py:813
msgid "{} is not a {}"
msgstr ""
-#: awx/main/fields.py:811
+#: awx/main/fields.py:819
#, python-brace-format
msgid "{sub_key} not allowed for {element_type} type ({element_id})"
msgstr ""
-#: awx/main/fields.py:869
+#: awx/main/fields.py:877
msgid ""
"Environment variable {} may affect Ansible configuration so its use is not "
"allowed in credentials."
msgstr ""
-#: awx/main/fields.py:875
-msgid "Environment variable {} is blacklisted from use in credentials."
+#: awx/main/fields.py:883
+msgid "Environment variable {} is not allowed to be used in credentials."
msgstr ""
-#: awx/main/fields.py:903
+#: awx/main/fields.py:911
msgid ""
"Must define unnamed file injector in order to reference `tower.filename`."
msgstr ""
-#: awx/main/fields.py:910
+#: awx/main/fields.py:918
msgid "Cannot directly reference reserved `tower` namespace container."
msgstr ""
-#: awx/main/fields.py:920
+#: awx/main/fields.py:928
msgid "Must use multi-file syntax when injecting multiple files"
msgstr ""
-#: awx/main/fields.py:940
+#: awx/main/fields.py:948
#, python-brace-format
msgid "{sub_key} uses an undefined field ({error_msg})"
msgstr ""
-#: awx/main/fields.py:947
+#: awx/main/fields.py:955
+msgid "Encountered unsafe code execution: {}"
+msgstr ""
+
+#: awx/main/fields.py:959
#, python-brace-format
msgid ""
"Syntax error rendering template for {sub_key} inside of {type} ({error_msg})"
@@ -3044,6 +3047,50 @@ msgid ""
"this list to programmatically generate named URLs for resources"
msgstr ""
+#: awx/main/migrations/_inventory_source_vars.py:140
+msgid "Image ID"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:141
+msgid "Availability Zone"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:143
+msgid "Instance ID"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:144
+msgid "Instance State"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:145
+msgid "Platform"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:146
+msgid "Instance Type"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:148
+msgid "Region"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:149
+msgid "Security Group"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:150
+msgid "Tags"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:151
+msgid "Tag None"
+msgstr ""
+
+#: awx/main/migrations/_inventory_source_vars.py:152
+msgid "VPC ID"
+msgstr ""
+
#: awx/main/models/activity_stream.py:28
msgid "Entity Created"
msgstr ""
@@ -3090,17 +3137,17 @@ msgstr ""
msgid "No argument passed to %s module."
msgstr ""
-#: awx/main/models/base.py:33 awx/main/models/base.py:39
-#: awx/main/models/base.py:44 awx/main/models/base.py:49
+#: awx/main/models/base.py:34 awx/main/models/base.py:40
+#: awx/main/models/base.py:45 awx/main/models/base.py:50
msgid "Run"
msgstr ""
-#: awx/main/models/base.py:34 awx/main/models/base.py:40
-#: awx/main/models/base.py:45 awx/main/models/base.py:50
+#: awx/main/models/base.py:35 awx/main/models/base.py:41
+#: awx/main/models/base.py:46 awx/main/models/base.py:51
msgid "Check"
msgstr ""
-#: awx/main/models/base.py:35
+#: awx/main/models/base.py:36
msgid "Scan"
msgstr ""
@@ -3110,819 +3157,822 @@ msgid ""
"Tower documentation for details on each type."
msgstr ""
-#: awx/main/models/credential/__init__.py:110
-#: awx/main/models/credential/__init__.py:353
+#: awx/main/models/credential/__init__.py:114
+#: awx/main/models/credential/__init__.py:358
msgid ""
"Enter inputs using either JSON or YAML syntax. Refer to the Ansible Tower "
"documentation for example syntax."
msgstr ""
-#: awx/main/models/credential/__init__.py:325
-#: awx/main/models/credential/__init__.py:594
+#: awx/main/models/credential/__init__.py:329
+#: awx/main/models/credential/__init__.py:602
msgid "Machine"
msgstr ""
-#: awx/main/models/credential/__init__.py:326
-#: awx/main/models/credential/__init__.py:680
+#: awx/main/models/credential/__init__.py:330
+#: awx/main/models/credential/__init__.py:688
msgid "Vault"
msgstr ""
-#: awx/main/models/credential/__init__.py:327
-#: awx/main/models/credential/__init__.py:707
+#: awx/main/models/credential/__init__.py:331
+#: awx/main/models/credential/__init__.py:715
msgid "Network"
msgstr ""
-#: awx/main/models/credential/__init__.py:328
-#: awx/main/models/credential/__init__.py:649
+#: awx/main/models/credential/__init__.py:332
+#: awx/main/models/credential/__init__.py:657
msgid "Source Control"
msgstr ""
-#: awx/main/models/credential/__init__.py:329
+#: awx/main/models/credential/__init__.py:333
msgid "Cloud"
msgstr ""
-#: awx/main/models/credential/__init__.py:330
+#: awx/main/models/credential/__init__.py:334
msgid "Personal Access Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:331
-#: awx/main/models/credential/__init__.py:1019
+#: awx/main/models/credential/__init__.py:335
+#: awx/main/models/credential/__init__.py:1027
msgid "Insights"
msgstr ""
-#: awx/main/models/credential/__init__.py:332
+#: awx/main/models/credential/__init__.py:336
msgid "External"
msgstr ""
-#: awx/main/models/credential/__init__.py:333
+#: awx/main/models/credential/__init__.py:337
msgid "Kubernetes"
msgstr ""
-#: awx/main/models/credential/__init__.py:359
+#: awx/main/models/credential/__init__.py:338
+msgid "Galaxy/Automation Hub"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:364
msgid ""
"Enter injectors using either JSON or YAML syntax. Refer to the Ansible Tower "
"documentation for example syntax."
msgstr ""
-#: awx/main/models/credential/__init__.py:428
+#: awx/main/models/credential/__init__.py:433
#, python-format
msgid "adding %s credential type"
msgstr ""
-#: awx/main/models/credential/__init__.py:602
-#: awx/main/models/credential/__init__.py:658
-#: awx/main/models/credential/__init__.py:716
-#: awx/main/models/credential/__init__.py:842
-#: awx/main/models/credential/__init__.py:868
-#: awx/main/models/credential/__init__.py:895
-#: awx/main/models/credential/__init__.py:955
-#: awx/main/models/credential/__init__.py:1028
-#: awx/main/models/credential/__init__.py:1059
-#: awx/main/models/credential/__init__.py:1109
+#: awx/main/models/credential/__init__.py:610
+#: awx/main/models/credential/__init__.py:666
+#: awx/main/models/credential/__init__.py:724
+#: awx/main/models/credential/__init__.py:850
+#: awx/main/models/credential/__init__.py:876
+#: awx/main/models/credential/__init__.py:903
+#: awx/main/models/credential/__init__.py:963
+#: awx/main/models/credential/__init__.py:1036
+#: awx/main/models/credential/__init__.py:1067
+#: awx/main/models/credential/__init__.py:1119
msgid "Password"
msgstr ""
-#: awx/main/models/credential/__init__.py:608
-#: awx/main/models/credential/__init__.py:721
+#: awx/main/models/credential/__init__.py:616
+#: awx/main/models/credential/__init__.py:729
msgid "SSH Private Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:615
+#: awx/main/models/credential/__init__.py:623
msgid "Signed SSH Certificate"
msgstr ""
-#: awx/main/models/credential/__init__.py:621
-#: awx/main/models/credential/__init__.py:670
-#: awx/main/models/credential/__init__.py:728
+#: awx/main/models/credential/__init__.py:629
+#: awx/main/models/credential/__init__.py:678
+#: awx/main/models/credential/__init__.py:736
msgid "Private Key Passphrase"
msgstr ""
-#: awx/main/models/credential/__init__.py:627
+#: awx/main/models/credential/__init__.py:635
msgid "Privilege Escalation Method"
msgstr ""
-#: awx/main/models/credential/__init__.py:629
+#: awx/main/models/credential/__init__.py:637
msgid ""
"Specify a method for \"become\" operations. This is equivalent to specifying "
"the --become-method Ansible parameter."
msgstr ""
-#: awx/main/models/credential/__init__.py:634
+#: awx/main/models/credential/__init__.py:642
msgid "Privilege Escalation Username"
msgstr ""
-#: awx/main/models/credential/__init__.py:638
+#: awx/main/models/credential/__init__.py:646
msgid "Privilege Escalation Password"
msgstr ""
-#: awx/main/models/credential/__init__.py:663
+#: awx/main/models/credential/__init__.py:671
msgid "SCM Private Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:685
+#: awx/main/models/credential/__init__.py:693
msgid "Vault Password"
msgstr ""
-#: awx/main/models/credential/__init__.py:691
+#: awx/main/models/credential/__init__.py:699
msgid "Vault Identifier"
msgstr ""
-#: awx/main/models/credential/__init__.py:694
+#: awx/main/models/credential/__init__.py:702
msgid ""
"Specify an (optional) Vault ID. This is equivalent to specifying the --vault-"
"id Ansible parameter for providing multiple Vault passwords. Note: this "
"feature only works in Ansible 2.4+."
msgstr ""
-#: awx/main/models/credential/__init__.py:733
+#: awx/main/models/credential/__init__.py:741
msgid "Authorize"
msgstr ""
-#: awx/main/models/credential/__init__.py:737
+#: awx/main/models/credential/__init__.py:745
msgid "Authorize Password"
msgstr ""
-#: awx/main/models/credential/__init__.py:751
+#: awx/main/models/credential/__init__.py:759
msgid "Amazon Web Services"
msgstr ""
-#: awx/main/models/credential/__init__.py:756
+#: awx/main/models/credential/__init__.py:764
msgid "Access Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:760
+#: awx/main/models/credential/__init__.py:768
msgid "Secret Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:765
+#: awx/main/models/credential/__init__.py:773
msgid "STS Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:768
+#: awx/main/models/credential/__init__.py:776
msgid ""
"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."
msgstr ""
-#: awx/main/models/credential/__init__.py:780 awx/main/models/inventory.py:833
+#: awx/main/models/credential/__init__.py:788 awx/main/models/inventory.py:826
msgid "OpenStack"
msgstr ""
-#: awx/main/models/credential/__init__.py:789
+#: awx/main/models/credential/__init__.py:797
msgid "Password (API Key)"
msgstr ""
-#: awx/main/models/credential/__init__.py:794
-#: awx/main/models/credential/__init__.py:1050
+#: awx/main/models/credential/__init__.py:802
+#: awx/main/models/credential/__init__.py:1058
msgid "Host (Authentication URL)"
msgstr ""
-#: awx/main/models/credential/__init__.py:796
+#: awx/main/models/credential/__init__.py:804
msgid ""
"The host to authenticate with. For example, https://openstack.business.com/"
"v2.0/"
msgstr ""
-#: awx/main/models/credential/__init__.py:800
+#: awx/main/models/credential/__init__.py:808
msgid "Project (Tenant Name)"
msgstr ""
-#: awx/main/models/credential/__init__.py:804
+#: awx/main/models/credential/__init__.py:812
msgid "Project (Domain Name)"
msgstr ""
-#: awx/main/models/credential/__init__.py:808
+#: awx/main/models/credential/__init__.py:816
msgid "Domain Name"
msgstr ""
-#: awx/main/models/credential/__init__.py:810
+#: awx/main/models/credential/__init__.py:818
msgid ""
"OpenStack domains define administrative boundaries. It is only needed for "
"Keystone v3 authentication URLs. Refer to Ansible Tower documentation for "
"common scenarios."
msgstr ""
-#: awx/main/models/credential/__init__.py:816
-#: awx/main/models/credential/__init__.py:1114
-#: awx/main/models/credential/__init__.py:1148
+#: awx/main/models/credential/__init__.py:824
+#: awx/main/models/credential/__init__.py:1131
+#: awx/main/models/credential/__init__.py:1166
msgid "Verify SSL"
msgstr ""
-#: awx/main/models/credential/__init__.py:827 awx/main/models/inventory.py:830
+#: awx/main/models/credential/__init__.py:835 awx/main/models/inventory.py:824
msgid "VMware vCenter"
msgstr ""
-#: awx/main/models/credential/__init__.py:832
+#: awx/main/models/credential/__init__.py:840
msgid "VCenter Host"
msgstr ""
-#: awx/main/models/credential/__init__.py:834
+#: awx/main/models/credential/__init__.py:842
msgid ""
"Enter the hostname or IP address that corresponds to your VMware vCenter."
msgstr ""
-#: awx/main/models/credential/__init__.py:853 awx/main/models/inventory.py:831
+#: awx/main/models/credential/__init__.py:861 awx/main/models/inventory.py:825
msgid "Red Hat Satellite 6"
msgstr ""
-#: awx/main/models/credential/__init__.py:858
+#: awx/main/models/credential/__init__.py:866
msgid "Satellite 6 URL"
msgstr ""
-#: awx/main/models/credential/__init__.py:860
+#: awx/main/models/credential/__init__.py:868
msgid ""
"Enter the URL that corresponds to your Red Hat Satellite 6 server. For "
"example, https://satellite.example.org"
msgstr ""
-#: awx/main/models/credential/__init__.py:879 awx/main/models/inventory.py:832
+#: awx/main/models/credential/__init__.py:887
msgid "Red Hat CloudForms"
msgstr ""
-#: awx/main/models/credential/__init__.py:884
+#: awx/main/models/credential/__init__.py:892
msgid "CloudForms URL"
msgstr ""
-#: awx/main/models/credential/__init__.py:886
+#: awx/main/models/credential/__init__.py:894
msgid ""
"Enter the URL for the virtual machine that corresponds to your CloudForms "
"instance. For example, https://cloudforms.example.org"
msgstr ""
-#: awx/main/models/credential/__init__.py:906 awx/main/models/inventory.py:828
+#: awx/main/models/credential/__init__.py:914 awx/main/models/inventory.py:822
msgid "Google Compute Engine"
msgstr ""
-#: awx/main/models/credential/__init__.py:911
+#: awx/main/models/credential/__init__.py:919
msgid "Service Account Email Address"
msgstr ""
-#: awx/main/models/credential/__init__.py:913
+#: awx/main/models/credential/__init__.py:921
msgid ""
"The email address assigned to the Google Compute Engine service account."
msgstr ""
-#: awx/main/models/credential/__init__.py:919
+#: awx/main/models/credential/__init__.py:927
msgid ""
"The Project ID is the GCE assigned identification. It is often constructed "
"as three words or two words followed by a three-digit number. Examples: "
"project-id-000 and another-project-id"
msgstr ""
-#: awx/main/models/credential/__init__.py:925
+#: awx/main/models/credential/__init__.py:933
msgid "RSA Private Key"
msgstr ""
-#: awx/main/models/credential/__init__.py:930
+#: awx/main/models/credential/__init__.py:938
msgid ""
"Paste the contents of the PEM file associated with the service account email."
msgstr ""
-#: awx/main/models/credential/__init__.py:940 awx/main/models/inventory.py:829
+#: awx/main/models/credential/__init__.py:948 awx/main/models/inventory.py:823
msgid "Microsoft Azure Resource Manager"
msgstr ""
-#: awx/main/models/credential/__init__.py:945
+#: awx/main/models/credential/__init__.py:953
msgid "Subscription ID"
msgstr ""
-#: awx/main/models/credential/__init__.py:947
+#: awx/main/models/credential/__init__.py:955
msgid "Subscription ID is an Azure construct, which is mapped to a username."
msgstr ""
-#: awx/main/models/credential/__init__.py:973
+#: awx/main/models/credential/__init__.py:981
msgid "Azure Cloud Environment"
msgstr ""
-#: awx/main/models/credential/__init__.py:975
+#: awx/main/models/credential/__init__.py:983
msgid ""
"Environment variable AZURE_CLOUD_ENVIRONMENT when using Azure GovCloud or "
"Azure stack."
msgstr ""
-#: awx/main/models/credential/__init__.py:985
+#: awx/main/models/credential/__init__.py:993
msgid "GitHub Personal Access Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:993
+#: awx/main/models/credential/__init__.py:1001
msgid "This token needs to come from your profile settings in GitHub"
msgstr ""
-#: awx/main/models/credential/__init__.py:1002
+#: awx/main/models/credential/__init__.py:1010
msgid "GitLab Personal Access Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:1010
+#: awx/main/models/credential/__init__.py:1018
msgid "This token needs to come from your profile settings in GitLab"
msgstr ""
-#: awx/main/models/credential/__init__.py:1045 awx/main/models/inventory.py:834
+#: awx/main/models/credential/__init__.py:1053 awx/main/models/inventory.py:827
msgid "Red Hat Virtualization"
msgstr ""
-#: awx/main/models/credential/__init__.py:1052
+#: awx/main/models/credential/__init__.py:1060
msgid "The host to authenticate with."
msgstr ""
-#: awx/main/models/credential/__init__.py:1064
+#: awx/main/models/credential/__init__.py:1072
msgid "CA File"
msgstr ""
-#: awx/main/models/credential/__init__.py:1066
+#: awx/main/models/credential/__init__.py:1074
msgid "Absolute file path to the CA file to use (optional)"
msgstr ""
-#: awx/main/models/credential/__init__.py:1095 awx/main/models/inventory.py:835
+#: awx/main/models/credential/__init__.py:1103 awx/main/models/inventory.py:828
msgid "Ansible Tower"
msgstr ""
-#: awx/main/models/credential/__init__.py:1100
+#: awx/main/models/credential/__init__.py:1108
msgid "Ansible Tower Hostname"
msgstr ""
-#: awx/main/models/credential/__init__.py:1102
+#: awx/main/models/credential/__init__.py:1110
msgid "The Ansible Tower base URL to authenticate with."
msgstr ""
-#: awx/main/models/credential/__init__.py:1134
+#: awx/main/models/credential/__init__.py:1115
+msgid ""
+"The Ansible Tower user to authenticate as.This should not be set if an OAuth "
+"token is being used."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1124
+msgid "OAuth Token"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1127
+msgid ""
+"An OAuth token to use to authenticate to Tower with.This should not be set "
+"if username/password are being used."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1152
msgid "OpenShift or Kubernetes API Bearer Token"
msgstr ""
-#: awx/main/models/credential/__init__.py:1138
+#: awx/main/models/credential/__init__.py:1156
msgid "OpenShift or Kubernetes API Endpoint"
msgstr ""
-#: awx/main/models/credential/__init__.py:1140
+#: awx/main/models/credential/__init__.py:1158
msgid "The OpenShift or Kubernetes API Endpoint to authenticate with."
msgstr ""
-#: awx/main/models/credential/__init__.py:1143
+#: awx/main/models/credential/__init__.py:1161
msgid "API authentication bearer token"
msgstr ""
-#: awx/main/models/credential/__init__.py:1153
+#: awx/main/models/credential/__init__.py:1171
msgid "Certificate Authority data"
msgstr ""
-#: awx/main/models/credential/__init__.py:1194
+#: awx/main/models/credential/__init__.py:1184
+msgid "Ansible Galaxy/Automation Hub API Token"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1188
+msgid "Galaxy Server URL"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1190
+msgid "The URL of the Galaxy instance to connect to."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1193
+msgid "Auth Server URL"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1196
+msgid "The URL of a Keycloak server token_endpoint, if using SSO auth."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1201
+msgid "API Token"
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1205
+msgid "A token to use for authentication against the Galaxy instance."
+msgstr ""
+
+#: awx/main/models/credential/__init__.py:1244
msgid "Target must be a non-external credential"
msgstr ""
-#: awx/main/models/credential/__init__.py:1199
+#: awx/main/models/credential/__init__.py:1249
msgid "Source must be an external credential"
msgstr ""
-#: awx/main/models/credential/__init__.py:1206
+#: awx/main/models/credential/__init__.py:1256
msgid "Input field must be defined on target credential (options are {})."
msgstr ""
-#: awx/main/models/events.py:152 awx/main/models/events.py:674
+#: awx/main/models/events.py:165 awx/main/models/events.py:707
msgid "Host Failed"
msgstr ""
-#: awx/main/models/events.py:153
+#: awx/main/models/events.py:166
msgid "Host Started"
msgstr ""
-#: awx/main/models/events.py:154 awx/main/models/events.py:675
+#: awx/main/models/events.py:167 awx/main/models/events.py:708
msgid "Host OK"
msgstr ""
-#: awx/main/models/events.py:155
+#: awx/main/models/events.py:168
msgid "Host Failure"
msgstr ""
-#: awx/main/models/events.py:156 awx/main/models/events.py:681
+#: awx/main/models/events.py:169 awx/main/models/events.py:714
msgid "Host Skipped"
msgstr ""
-#: awx/main/models/events.py:157 awx/main/models/events.py:676
+#: awx/main/models/events.py:170 awx/main/models/events.py:709
msgid "Host Unreachable"
msgstr ""
-#: awx/main/models/events.py:158 awx/main/models/events.py:172
+#: awx/main/models/events.py:171 awx/main/models/events.py:185
msgid "No Hosts Remaining"
msgstr ""
-#: awx/main/models/events.py:159
+#: awx/main/models/events.py:172
msgid "Host Polling"
msgstr ""
-#: awx/main/models/events.py:160
+#: awx/main/models/events.py:173
msgid "Host Async OK"
msgstr ""
-#: awx/main/models/events.py:161
+#: awx/main/models/events.py:174
msgid "Host Async Failure"
msgstr ""
-#: awx/main/models/events.py:162
+#: awx/main/models/events.py:175
msgid "Item OK"
msgstr ""
-#: awx/main/models/events.py:163
+#: awx/main/models/events.py:176
msgid "Item Failed"
msgstr ""
-#: awx/main/models/events.py:164
+#: awx/main/models/events.py:177
msgid "Item Skipped"
msgstr ""
-#: awx/main/models/events.py:165
+#: awx/main/models/events.py:178
msgid "Host Retry"
msgstr ""
-#: awx/main/models/events.py:167
+#: awx/main/models/events.py:180
msgid "File Difference"
msgstr ""
-#: awx/main/models/events.py:168
+#: awx/main/models/events.py:181
msgid "Playbook Started"
msgstr ""
-#: awx/main/models/events.py:169
+#: awx/main/models/events.py:182
msgid "Running Handlers"
msgstr ""
-#: awx/main/models/events.py:170
+#: awx/main/models/events.py:183
msgid "Including File"
msgstr ""
-#: awx/main/models/events.py:171
+#: awx/main/models/events.py:184
msgid "No Hosts Matched"
msgstr ""
-#: awx/main/models/events.py:173
+#: awx/main/models/events.py:186
msgid "Task Started"
msgstr ""
-#: awx/main/models/events.py:175
+#: awx/main/models/events.py:188
msgid "Variables Prompted"
msgstr ""
-#: awx/main/models/events.py:176
+#: awx/main/models/events.py:189
msgid "Gathering Facts"
msgstr ""
-#: awx/main/models/events.py:177
+#: awx/main/models/events.py:190
msgid "internal: on Import for Host"
msgstr ""
-#: awx/main/models/events.py:178
+#: awx/main/models/events.py:191
msgid "internal: on Not Import for Host"
msgstr ""
-#: awx/main/models/events.py:179
+#: awx/main/models/events.py:192
msgid "Play Started"
msgstr ""
-#: awx/main/models/events.py:180
+#: awx/main/models/events.py:193
msgid "Playbook Complete"
msgstr ""
-#: awx/main/models/events.py:184 awx/main/models/events.py:691
+#: awx/main/models/events.py:197 awx/main/models/events.py:724
msgid "Debug"
msgstr ""
-#: awx/main/models/events.py:185 awx/main/models/events.py:692
+#: awx/main/models/events.py:198 awx/main/models/events.py:725
msgid "Verbose"
msgstr ""
-#: awx/main/models/events.py:186 awx/main/models/events.py:693
+#: awx/main/models/events.py:199 awx/main/models/events.py:726
msgid "Deprecated"
msgstr ""
-#: awx/main/models/events.py:187 awx/main/models/events.py:694
+#: awx/main/models/events.py:200 awx/main/models/events.py:727
msgid "Warning"
msgstr ""
-#: awx/main/models/events.py:188 awx/main/models/events.py:695
+#: awx/main/models/events.py:201 awx/main/models/events.py:728
msgid "System Warning"
msgstr ""
-#: awx/main/models/events.py:189 awx/main/models/events.py:696
+#: awx/main/models/events.py:202 awx/main/models/events.py:729
#: awx/main/models/unified_jobs.py:75
msgid "Error"
msgstr ""
-#: awx/main/models/ha.py:175
+#: awx/main/models/ha.py:184
msgid "Instances that are members of this InstanceGroup"
msgstr ""
-#: awx/main/models/ha.py:180
+#: awx/main/models/ha.py:189
msgid "Instance Group to remotely control this group."
msgstr ""
-#: awx/main/models/ha.py:200
+#: awx/main/models/ha.py:209
msgid "Percentage of Instances to automatically assign to this group"
msgstr ""
-#: awx/main/models/ha.py:204
+#: awx/main/models/ha.py:213
msgid ""
"Static minimum number of Instances to automatically assign to this group"
msgstr ""
-#: awx/main/models/ha.py:209
+#: awx/main/models/ha.py:218
msgid ""
"List of exact-match Instances that will always be automatically assigned to "
"this group"
msgstr ""
-#: awx/main/models/inventory.py:80
+#: awx/main/models/inventory.py:74
msgid "Hosts have a direct link to this inventory."
msgstr ""
-#: awx/main/models/inventory.py:81
+#: awx/main/models/inventory.py:75
msgid "Hosts for inventory generated using the host_filter property."
msgstr ""
-#: awx/main/models/inventory.py:86
+#: awx/main/models/inventory.py:80
msgid "inventories"
msgstr ""
-#: awx/main/models/inventory.py:93
+#: awx/main/models/inventory.py:87
msgid "Organization containing this inventory."
msgstr ""
-#: awx/main/models/inventory.py:100
+#: awx/main/models/inventory.py:94
msgid "Inventory variables in JSON or YAML format."
msgstr ""
-#: awx/main/models/inventory.py:105
+#: awx/main/models/inventory.py:99
msgid ""
"This field is deprecated and will be removed in a future release. Flag "
"indicating whether any hosts in this inventory have failed."
msgstr ""
-#: awx/main/models/inventory.py:111
+#: awx/main/models/inventory.py:105
msgid ""
"This field is deprecated and will be removed in a future release. Total "
"number of hosts in this inventory."
msgstr ""
-#: awx/main/models/inventory.py:117
+#: awx/main/models/inventory.py:111
msgid ""
"This field is deprecated and will be removed in a future release. Number of "
"hosts in this inventory with active failures."
msgstr ""
-#: awx/main/models/inventory.py:123
+#: awx/main/models/inventory.py:117
msgid ""
"This field is deprecated and will be removed in a future release. Total "
"number of groups in this inventory."
msgstr ""
-#: awx/main/models/inventory.py:129
+#: awx/main/models/inventory.py:123
msgid ""
"This field is deprecated and will be removed in a future release. Flag "
"indicating whether this inventory has any external inventory sources."
msgstr ""
-#: awx/main/models/inventory.py:135
+#: awx/main/models/inventory.py:129
msgid ""
"Total number of external inventory sources configured within this inventory."
msgstr ""
-#: awx/main/models/inventory.py:140
+#: awx/main/models/inventory.py:134
msgid "Number of external inventory sources in this inventory with failures."
msgstr ""
-#: awx/main/models/inventory.py:147
+#: awx/main/models/inventory.py:141
msgid "Kind of inventory being represented."
msgstr ""
-#: awx/main/models/inventory.py:153
+#: awx/main/models/inventory.py:147
msgid "Filter that will be applied to the hosts of this inventory."
msgstr ""
-#: awx/main/models/inventory.py:181
+#: awx/main/models/inventory.py:175
msgid ""
"Credentials to be used by hosts belonging to this inventory when accessing "
"Red Hat Insights API."
msgstr ""
-#: awx/main/models/inventory.py:190
+#: awx/main/models/inventory.py:184
msgid "Flag indicating the inventory is being deleted."
msgstr ""
-#: awx/main/models/inventory.py:245
+#: awx/main/models/inventory.py:239
msgid "Could not parse subset as slice specification."
msgstr ""
-#: awx/main/models/inventory.py:249
+#: awx/main/models/inventory.py:243
msgid "Slice number must be less than total number of slices."
msgstr ""
-#: awx/main/models/inventory.py:251
+#: awx/main/models/inventory.py:245
msgid "Slice number must be 1 or higher."
msgstr ""
-#: awx/main/models/inventory.py:388
+#: awx/main/models/inventory.py:382
msgid "Assignment not allowed for Smart Inventory"
msgstr ""
-#: awx/main/models/inventory.py:390 awx/main/models/projects.py:166
+#: awx/main/models/inventory.py:384 awx/main/models/projects.py:167
msgid "Credential kind must be 'insights'."
msgstr ""
-#: awx/main/models/inventory.py:475
+#: awx/main/models/inventory.py:469
msgid "Is this host online and available for running jobs?"
msgstr ""
-#: awx/main/models/inventory.py:481
+#: awx/main/models/inventory.py:475
msgid ""
"The value used by the remote inventory source to uniquely identify the host"
msgstr ""
-#: awx/main/models/inventory.py:486
+#: awx/main/models/inventory.py:480
msgid "Host variables in JSON or YAML format."
msgstr ""
-#: awx/main/models/inventory.py:509
+#: awx/main/models/inventory.py:503
msgid "Inventory source(s) that created or modified this host."
msgstr ""
-#: awx/main/models/inventory.py:514
+#: awx/main/models/inventory.py:508
msgid "Arbitrary JSON structure of most recent ansible_facts, per-host."
msgstr ""
-#: awx/main/models/inventory.py:520
+#: awx/main/models/inventory.py:514
msgid "The date and time ansible_facts was last modified."
msgstr ""
-#: awx/main/models/inventory.py:527
+#: awx/main/models/inventory.py:521
msgid "Red Hat Insights host unique identifier."
msgstr ""
-#: awx/main/models/inventory.py:641
+#: awx/main/models/inventory.py:635
msgid "Group variables in JSON or YAML format."
msgstr ""
-#: awx/main/models/inventory.py:647
+#: awx/main/models/inventory.py:641
msgid "Hosts associated directly with this group."
msgstr ""
-#: awx/main/models/inventory.py:653
+#: awx/main/models/inventory.py:647
msgid "Inventory source(s) that created or modified this group."
msgstr ""
-#: awx/main/models/inventory.py:825
+#: awx/main/models/inventory.py:819
msgid "File, Directory or Script"
msgstr ""
-#: awx/main/models/inventory.py:826
+#: awx/main/models/inventory.py:820
msgid "Sourced from a Project"
msgstr ""
-#: awx/main/models/inventory.py:827
+#: awx/main/models/inventory.py:821
msgid "Amazon EC2"
msgstr ""
-#: awx/main/models/inventory.py:836
+#: awx/main/models/inventory.py:829
msgid "Custom Script"
msgstr ""
-#: awx/main/models/inventory.py:953
+#: awx/main/models/inventory.py:863
msgid "Inventory source variables in YAML or JSON format."
msgstr ""
-#: awx/main/models/inventory.py:964
+#: awx/main/models/inventory.py:868
msgid ""
-"Comma-separated list of filter expressions (EC2 only). Hosts are imported "
-"when ANY of the filters match."
+"Retrieve the enabled state from the given dict of host variables. The "
+"enabled variable may be specified as \"foo.bar\", in which case the lookup "
+"will traverse into nested dicts, equivalent to: from_dict.get(\"foo\", {})."
+"get(\"bar\", default)"
msgstr ""
-#: awx/main/models/inventory.py:970
-msgid "Limit groups automatically created from inventory source (EC2 only)."
+#: awx/main/models/inventory.py:876
+msgid ""
+"Only used when enabled_var is set. Value when the host is considered "
+"enabled. For example if enabled_var=\"status.power_state\"and enabled_value="
+"\"powered_on\" with host variables:{ \"status\": { \"power_state\": "
+"\"powered_on\", \"created\": \"2020-08-04T18:13:04+00:00\", \"healthy"
+"\": true }, \"name\": \"foobar\", \"ip_address\": \"192.168.2.1\"}"
+"The host would be marked enabled. If power_state where any value other than "
+"powered_on then the host would be disabled when imported into Tower. If the "
+"key is not found then the host will be enabled"
msgstr ""
-#: awx/main/models/inventory.py:974
+#: awx/main/models/inventory.py:896
+msgid "Regex where only matching hosts will be imported into Tower."
+msgstr ""
+
+#: awx/main/models/inventory.py:900
msgid "Overwrite local groups and hosts from remote inventory source."
msgstr ""
-#: awx/main/models/inventory.py:978
+#: awx/main/models/inventory.py:904
msgid "Overwrite local variables from remote inventory source."
msgstr ""
-#: awx/main/models/inventory.py:983 awx/main/models/jobs.py:154
-#: awx/main/models/projects.py:135
+#: awx/main/models/inventory.py:909 awx/main/models/jobs.py:154
+#: awx/main/models/projects.py:136
msgid "The amount of time (in seconds) to run before the task is canceled."
msgstr ""
-#: awx/main/models/inventory.py:1016
-msgid "Image ID"
-msgstr ""
-
-#: awx/main/models/inventory.py:1017
-msgid "Availability Zone"
-msgstr ""
-
-#: awx/main/models/inventory.py:1019
-msgid "Instance ID"
-msgstr ""
-
-#: awx/main/models/inventory.py:1020
-msgid "Instance State"
-msgstr ""
-
-#: awx/main/models/inventory.py:1021
-msgid "Platform"
-msgstr ""
-
-#: awx/main/models/inventory.py:1022
-msgid "Instance Type"
-msgstr ""
-
-#: awx/main/models/inventory.py:1024
-msgid "Region"
-msgstr ""
-
-#: awx/main/models/inventory.py:1025
-msgid "Security Group"
-msgstr ""
-
-#: awx/main/models/inventory.py:1026
-msgid "Tags"
-msgstr ""
-
-#: awx/main/models/inventory.py:1027
-msgid "Tag None"
-msgstr ""
-
-#: awx/main/models/inventory.py:1028
-msgid "VPC ID"
-msgstr ""
-
-#: awx/main/models/inventory.py:1096
+#: awx/main/models/inventory.py:926
#, python-format
msgid ""
"Cloud-based inventory sources (such as %s) require credentials for the "
"matching cloud service."
msgstr ""
-#: awx/main/models/inventory.py:1102
+#: awx/main/models/inventory.py:932
msgid "Credential is required for a cloud source."
msgstr ""
-#: awx/main/models/inventory.py:1105
+#: awx/main/models/inventory.py:935
msgid ""
"Credentials of type machine, source control, insights and vault are "
"disallowed for custom inventory sources."
msgstr ""
-#: awx/main/models/inventory.py:1110
+#: awx/main/models/inventory.py:940
msgid ""
"Credentials of type insights and vault are disallowed for scm inventory "
"sources."
msgstr ""
-#: awx/main/models/inventory.py:1170
-#, python-format
-msgid "Invalid %(source)s region: %(region)s"
-msgstr ""
-
-#: awx/main/models/inventory.py:1194
-#, python-format
-msgid "Invalid filter expression: %(filter)s"
-msgstr ""
-
-#: awx/main/models/inventory.py:1215
-#, python-format
-msgid "Invalid group by choice: %(choice)s"
-msgstr ""
-
-#: awx/main/models/inventory.py:1243
+#: awx/main/models/inventory.py:1004
msgid "Project containing inventory file used as source."
msgstr ""
-#: awx/main/models/inventory.py:1416
+#: awx/main/models/inventory.py:1177
msgid ""
"More than one SCM-based inventory source with update on project update per-"
"inventory not allowed."
msgstr ""
-#: awx/main/models/inventory.py:1423
+#: awx/main/models/inventory.py:1184
msgid ""
"Cannot update SCM-based inventory source on launch if set to update on "
"project update. Instead, configure the corresponding source project to "
"update on launch."
msgstr ""
-#: awx/main/models/inventory.py:1429
+#: awx/main/models/inventory.py:1190
msgid "Cannot set source_path if not SCM type."
msgstr ""
-#: awx/main/models/inventory.py:1472
+#: awx/main/models/inventory.py:1233
msgid ""
"Inventory files from this Project Update were used for the inventory update."
msgstr ""
-#: awx/main/models/inventory.py:1583
+#: awx/main/models/inventory.py:1344
msgid "Inventory script contents"
msgstr ""
-#: awx/main/models/inventory.py:1588
+#: awx/main/models/inventory.py:1349
msgid "Organization owning this inventory script"
msgstr ""
@@ -3980,8 +4030,8 @@ msgstr ""
msgid "Job Template {} is missing or undefined."
msgstr ""
-#: awx/main/models/jobs.py:570 awx/main/models/projects.py:278
-#: awx/main/models/projects.py:497
+#: awx/main/models/jobs.py:570 awx/main/models/projects.py:284
+#: awx/main/models/projects.py:508
msgid "SCM Revision"
msgstr ""
@@ -4081,63 +4131,59 @@ msgstr ""
msgid "Unique identifier of the event that triggered this webhook"
msgstr ""
-#: awx/main/models/notifications.py:42
+#: awx/main/models/notifications.py:41
msgid "Email"
msgstr ""
-#: awx/main/models/notifications.py:43
+#: awx/main/models/notifications.py:42
msgid "Slack"
msgstr ""
-#: awx/main/models/notifications.py:44
+#: awx/main/models/notifications.py:43
msgid "Twilio"
msgstr ""
-#: awx/main/models/notifications.py:45
+#: awx/main/models/notifications.py:44
msgid "Pagerduty"
msgstr ""
-#: awx/main/models/notifications.py:46
+#: awx/main/models/notifications.py:45
msgid "Grafana"
msgstr ""
-#: awx/main/models/notifications.py:47
-msgid "HipChat"
-msgstr ""
-
-#: awx/main/models/notifications.py:48 awx/main/models/unified_jobs.py:544
+#: awx/main/models/notifications.py:46 awx/main/models/unified_jobs.py:544
msgid "Webhook"
msgstr ""
-#: awx/main/models/notifications.py:49
+#: awx/main/models/notifications.py:47
msgid "Mattermost"
msgstr ""
-#: awx/main/models/notifications.py:50
+#: awx/main/models/notifications.py:48
msgid "Rocket.Chat"
msgstr ""
-#: awx/main/models/notifications.py:51
+#: awx/main/models/notifications.py:49
msgid "IRC"
msgstr ""
-#: awx/main/models/notifications.py:82
+#: awx/main/models/notifications.py:80
msgid "Optional custom messages for notification template."
msgstr ""
-#: awx/main/models/notifications.py:212 awx/main/models/unified_jobs.py:70
+#: awx/main/models/notifications.py:210 awx/main/models/unified_jobs.py:70
msgid "Pending"
msgstr ""
-#: awx/main/models/notifications.py:213 awx/main/models/unified_jobs.py:73
+#: awx/main/models/notifications.py:211 awx/main/models/unified_jobs.py:73
msgid "Successful"
msgstr ""
-#: awx/main/models/notifications.py:214 awx/main/models/unified_jobs.py:74
+#: awx/main/models/notifications.py:212 awx/main/models/unified_jobs.py:74
msgid "Failed"
msgstr ""
-#: awx/main/models/notifications.py:467
+#: awx/main/models/notifications.py:470
msgid "status must be either running, succeeded or failed"
msgstr ""
@@ -4206,7 +4252,7 @@ msgid ""
"authentication provider ({})"
msgstr ""
-#: awx/main/models/organization.py:51
+#: awx/main/models/organization.py:57
msgid "Maximum number of hosts allowed to be managed by this organization."
msgstr ""
@@ -4230,118 +4276,122 @@ msgstr ""
msgid "Red Hat Insights"
msgstr ""
-#: awx/main/models/projects.py:83
+#: awx/main/models/projects.py:58
+msgid "Remote Archive"
+msgstr ""
+
+#: awx/main/models/projects.py:84
msgid ""
"Local path (relative to PROJECTS_ROOT) containing playbooks and related "
"files for this project."
msgstr ""
-#: awx/main/models/projects.py:92
+#: awx/main/models/projects.py:93
msgid "SCM Type"
msgstr ""
-#: awx/main/models/projects.py:93
+#: awx/main/models/projects.py:94
msgid "Specifies the source control system used to store the project."
msgstr ""
-#: awx/main/models/projects.py:99
+#: awx/main/models/projects.py:100
msgid "SCM URL"
msgstr ""
-#: awx/main/models/projects.py:100
+#: awx/main/models/projects.py:101
msgid "The location where the project is stored."
msgstr ""
-#: awx/main/models/projects.py:106
+#: awx/main/models/projects.py:107
msgid "SCM Branch"
msgstr ""
-#: awx/main/models/projects.py:107
+#: awx/main/models/projects.py:108
msgid "Specific branch, tag or commit to checkout."
msgstr ""
-#: awx/main/models/projects.py:113
+#: awx/main/models/projects.py:114
msgid "SCM refspec"
msgstr ""
-#: awx/main/models/projects.py:114
+#: awx/main/models/projects.py:115
msgid "For git projects, an additional refspec to fetch."
msgstr ""
-#: awx/main/models/projects.py:118
+#: awx/main/models/projects.py:119
msgid "Discard any local changes before syncing the project."
msgstr ""
-#: awx/main/models/projects.py:122
+#: awx/main/models/projects.py:123
msgid "Delete the project before syncing."
msgstr ""
-#: awx/main/models/projects.py:151
+#: awx/main/models/projects.py:152
msgid "Invalid SCM URL."
msgstr ""
-#: awx/main/models/projects.py:154
+#: awx/main/models/projects.py:155
msgid "SCM URL is required."
msgstr ""
-#: awx/main/models/projects.py:162
+#: awx/main/models/projects.py:163
msgid "Insights Credential is required for an Insights Project."
msgstr ""
-#: awx/main/models/projects.py:168
+#: awx/main/models/projects.py:169
msgid "Credential kind must be 'scm'."
msgstr ""
-#: awx/main/models/projects.py:185
+#: awx/main/models/projects.py:186
msgid "Invalid credential."
msgstr ""
-#: awx/main/models/projects.py:259
+#: awx/main/models/projects.py:265
msgid "Update the project when a job is launched that uses the project."
msgstr ""
-#: awx/main/models/projects.py:264
+#: awx/main/models/projects.py:270
msgid ""
"The number of seconds after the last project update ran that a new project "
"update will be launched as a job dependency."
msgstr ""
-#: awx/main/models/projects.py:269
+#: awx/main/models/projects.py:275
msgid ""
"Allow changing the SCM branch or revision in a job template that uses this "
"project."
msgstr ""
-#: awx/main/models/projects.py:279
+#: awx/main/models/projects.py:285
msgid "The last revision fetched by a project update"
msgstr ""
-#: awx/main/models/projects.py:286
+#: awx/main/models/projects.py:292
msgid "Playbook Files"
msgstr ""
-#: awx/main/models/projects.py:287
+#: awx/main/models/projects.py:293
msgid "List of playbooks found in the project"
msgstr ""
-#: awx/main/models/projects.py:294
+#: awx/main/models/projects.py:300
msgid "Inventory Files"
msgstr ""
-#: awx/main/models/projects.py:295
+#: awx/main/models/projects.py:301
msgid ""
"Suggested list of content that could be Ansible inventory in the project"
msgstr ""
-#: awx/main/models/projects.py:332
+#: awx/main/models/projects.py:338
msgid "Organization cannot be changed when in use by job templates."
msgstr ""
-#: awx/main/models/projects.py:490
+#: awx/main/models/projects.py:501
msgid "Parts of the project update playbook that will be run."
msgstr ""
-#: awx/main/models/projects.py:498
+#: awx/main/models/projects.py:509
msgid ""
"The SCM Revision discovered by this update for the given project and branch."
msgstr ""
@@ -4697,41 +4747,33 @@ msgid ""
"Shows when an approval node (with a timeout assigned to it) has timed out."
msgstr ""
-#: awx/main/notifications/grafana_backend.py:86
+#: awx/main/notifications/grafana_backend.py:81
msgid "Error converting time {} or timeEnd {} to int."
msgstr ""
-#: awx/main/notifications/grafana_backend.py:88
+#: awx/main/notifications/grafana_backend.py:83
msgid "Error converting time {} and/or timeEnd {} to int."
msgstr ""
-#: awx/main/notifications/grafana_backend.py:102
-#: awx/main/notifications/grafana_backend.py:104
+#: awx/main/notifications/grafana_backend.py:97
+#: awx/main/notifications/grafana_backend.py:99
msgid "Error sending notification grafana: {}"
msgstr ""
-#: awx/main/notifications/hipchat_backend.py:50
-msgid "Error sending messages: {}"
-msgstr ""
-
-#: awx/main/notifications/hipchat_backend.py:52
-msgid "Error sending message to hipchat: {}"
-msgstr ""
-
#: awx/main/notifications/irc_backend.py:56
msgid "Exception connecting to irc server: {}"
msgstr ""
-#: awx/main/notifications/mattermost_backend.py:50
-#: awx/main/notifications/mattermost_backend.py:52
+#: awx/main/notifications/mattermost_backend.py:49
+#: awx/main/notifications/mattermost_backend.py:51
msgid "Error sending notification mattermost: {}"
msgstr ""
-#: awx/main/notifications/pagerduty_backend.py:64
+#: awx/main/notifications/pagerduty_backend.py:75
msgid "Exception connecting to PagerDuty: {}"
msgstr ""
-#: awx/main/notifications/pagerduty_backend.py:73
+#: awx/main/notifications/pagerduty_backend.py:84
#: awx/main/notifications/slack_backend.py:58
#: awx/main/notifications/twilio_backend.py:48
msgid "Exception sending messages: {}"
@@ -4758,46 +4800,52 @@ msgid ""
"job node(s) missing unified job template and error handling path [{no_ufjt}]."
msgstr ""
-#: awx/main/scheduler/task_manager.py:118
+#: awx/main/scheduler/task_manager.py:127
msgid ""
"Workflow Job spawned from workflow could not start because it would result "
"in recursion (spawn order, most recent first: {})"
msgstr ""
-#: awx/main/scheduler/task_manager.py:126
+#: awx/main/scheduler/task_manager.py:135
msgid ""
"Job spawned from workflow could not start because it was missing a related "
"resource such as project or inventory"
msgstr ""
-#: awx/main/scheduler/task_manager.py:135
+#: awx/main/scheduler/task_manager.py:144
msgid ""
"Job spawned from workflow could not start because it was not in the right "
"state or required manual credentials"
msgstr ""
-#: awx/main/scheduler/task_manager.py:176
+#: awx/main/scheduler/task_manager.py:185
msgid "No error handling paths found, marking workflow as failed"
msgstr ""
-#: awx/main/scheduler/task_manager.py:508
+#: awx/main/scheduler/task_manager.py:523
#, python-brace-format
msgid "The approval node {name} ({pk}) has expired after {timeout} seconds."
msgstr ""
-#: awx/main/tasks.py:1046
+#: awx/main/tasks.py:599
+msgid ""
+"Scheduled job could not start because it was not in the "
+"right state or required manual credentials"
+msgstr ""
+
+#: awx/main/tasks.py:1070
msgid "Invalid virtual environment selected: {}"
msgstr ""
-#: awx/main/tasks.py:1849
+#: awx/main/tasks.py:1857
msgid "Job could not start because it does not have a valid inventory."
msgstr ""
-#: awx/main/tasks.py:1853
+#: awx/main/tasks.py:1861
msgid "Job could not start because it does not have a valid project."
msgstr ""
-#: awx/main/tasks.py:1858
+#: awx/main/tasks.py:1866
msgid ""
"The project revision for this job template is unknown due to a failed update."
msgstr ""
@@ -4822,53 +4870,53 @@ msgstr ""
msgid "Unable to convert \"%s\" to boolean"
msgstr ""
-#: awx/main/utils/common.py:261
+#: awx/main/utils/common.py:248
#, python-format
msgid "Unsupported SCM type \"%s\""
msgstr ""
-#: awx/main/utils/common.py:268 awx/main/utils/common.py:280
-#: awx/main/utils/common.py:299
+#: awx/main/utils/common.py:255 awx/main/utils/common.py:267
+#: awx/main/utils/common.py:286
#, python-format
msgid "Invalid %s URL"
msgstr ""
-#: awx/main/utils/common.py:270 awx/main/utils/common.py:309
+#: awx/main/utils/common.py:257 awx/main/utils/common.py:297
#, python-format
msgid "Unsupported %s URL"
msgstr ""
-#: awx/main/utils/common.py:311
+#: awx/main/utils/common.py:299
#, python-format
msgid "Unsupported host \"%s\" for file:// URL"
msgstr ""
-#: awx/main/utils/common.py:313
+#: awx/main/utils/common.py:301
#, python-format
msgid "Host is required for %s URL"
msgstr ""
-#: awx/main/utils/common.py:331
+#: awx/main/utils/common.py:319
#, python-format
msgid "Username must be \"git\" for SSH access to %s."
msgstr ""
-#: awx/main/utils/common.py:337
+#: awx/main/utils/common.py:325
#, python-format
msgid "Username must be \"hg\" for SSH access to %s."
msgstr ""
-#: awx/main/utils/common.py:668
+#: awx/main/utils/common.py:656
#, python-brace-format
msgid "Input type `{data_type}` is not a dictionary"
msgstr ""
-#: awx/main/utils/common.py:701
+#: awx/main/utils/common.py:689
#, python-brace-format
msgid "Variables not compatible with JSON standard (error: {json_error})"
msgstr ""
-#: awx/main/utils/common.py:707
+#: awx/main/utils/common.py:695
#, python-brace-format
msgid ""
"Cannot parse as JSON (error: {json_error}) or YAML (error: {yaml_error})."
@@ -4980,290 +5028,6 @@ msgstr ""
msgid "A server error has occurred."
msgstr ""
-#: awx/settings/defaults.py:683
-msgid "US East (Northern Virginia)"
-msgstr ""
-
-#: awx/settings/defaults.py:684
-msgid "US East (Ohio)"
-msgstr ""
-
-#: awx/settings/defaults.py:685
-msgid "US West (Oregon)"
-msgstr ""
-
-#: awx/settings/defaults.py:686
-msgid "US West (Northern California)"
-msgstr ""
-
-#: awx/settings/defaults.py:687
-msgid "Canada (Central)"
-msgstr ""
-
-#: awx/settings/defaults.py:688
-msgid "EU (Frankfurt)"
-msgstr ""
-
-#: awx/settings/defaults.py:689
-msgid "EU (Ireland)"
-msgstr ""
-
-#: awx/settings/defaults.py:690
-msgid "EU (London)"
-msgstr ""
-
-#: awx/settings/defaults.py:691
-msgid "Asia Pacific (Singapore)"
-msgstr ""
-
-#: awx/settings/defaults.py:692
-msgid "Asia Pacific (Sydney)"
-msgstr ""
-
-#: awx/settings/defaults.py:693
-msgid "Asia Pacific (Tokyo)"
-msgstr ""
-
-#: awx/settings/defaults.py:694
-msgid "Asia Pacific (Seoul)"
-msgstr ""
-
-#: awx/settings/defaults.py:695
-msgid "Asia Pacific (Mumbai)"
-msgstr ""
-
-#: awx/settings/defaults.py:696
-msgid "South America (Sao Paulo)"
-msgstr ""
-
-#: awx/settings/defaults.py:697
-msgid "US West (GovCloud)"
-msgstr ""
-
-#: awx/settings/defaults.py:698
-msgid "China (Beijing)"
-msgstr ""
-
-#: awx/settings/defaults.py:747
-msgid "US East 1 (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:748
-msgid "US East 1 (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:749
-msgid "US East 1 (D)"
-msgstr ""
-
-#: awx/settings/defaults.py:750
-msgid "US East 4 (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:751
-msgid "US East 4 (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:752
-msgid "US East 4 (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:753
-msgid "US Central (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:754
-msgid "US Central (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:755
-msgid "US Central (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:756
-msgid "US Central (F)"
-msgstr ""
-
-#: awx/settings/defaults.py:757
-msgid "US West (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:758
-msgid "US West (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:759
-msgid "US West (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:760
-msgid "Europe West 1 (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:761
-msgid "Europe West 1 (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:762
-msgid "Europe West 1 (D)"
-msgstr ""
-
-#: awx/settings/defaults.py:763
-msgid "Europe West 2 (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:764
-msgid "Europe West 2 (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:765
-msgid "Europe West 2 (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:766
-msgid "Asia East (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:767
-msgid "Asia East (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:768
-msgid "Asia East (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:769
-msgid "Asia Southeast (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:770
-msgid "Asia Southeast (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:771
-msgid "Asia Northeast (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:772
-msgid "Asia Northeast (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:773
-msgid "Asia Northeast (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:774
-msgid "Australia Southeast (A)"
-msgstr ""
-
-#: awx/settings/defaults.py:775
-msgid "Australia Southeast (B)"
-msgstr ""
-
-#: awx/settings/defaults.py:776
-msgid "Australia Southeast (C)"
-msgstr ""
-
-#: awx/settings/defaults.py:798
-msgid "US East"
-msgstr ""
-
-#: awx/settings/defaults.py:799
-msgid "US East 2"
-msgstr ""
-
-#: awx/settings/defaults.py:800
-msgid "US Central"
-msgstr ""
-
-#: awx/settings/defaults.py:801
-msgid "US North Central"
-msgstr ""
-
-#: awx/settings/defaults.py:802
-msgid "US South Central"
-msgstr ""
-
-#: awx/settings/defaults.py:803
-msgid "US West Central"
-msgstr ""
-
-#: awx/settings/defaults.py:804
-msgid "US West"
-msgstr ""
-
-#: awx/settings/defaults.py:805
-msgid "US West 2"
-msgstr ""
-
-#: awx/settings/defaults.py:806
-msgid "Canada East"
-msgstr ""
-
-#: awx/settings/defaults.py:807
-msgid "Canada Central"
-msgstr ""
-
-#: awx/settings/defaults.py:808
-msgid "Brazil South"
-msgstr ""
-
-#: awx/settings/defaults.py:809
-msgid "Europe North"
-msgstr ""
-
-#: awx/settings/defaults.py:810
-msgid "Europe West"
-msgstr ""
-
-#: awx/settings/defaults.py:811
-msgid "UK West"
-msgstr ""
-
-#: awx/settings/defaults.py:812
-msgid "UK South"
-msgstr ""
-
-#: awx/settings/defaults.py:813
-msgid "Asia East"
-msgstr ""
-
-#: awx/settings/defaults.py:814
-msgid "Asia Southeast"
-msgstr ""
-
-#: awx/settings/defaults.py:815
-msgid "Australia East"
-msgstr ""
-
-#: awx/settings/defaults.py:816
-msgid "Australia Southeast"
-msgstr ""
-
-#: awx/settings/defaults.py:817
-msgid "India West"
-msgstr ""
-
-#: awx/settings/defaults.py:818
-msgid "India South"
-msgstr ""
-
-#: awx/settings/defaults.py:819
-msgid "Japan East"
-msgstr ""
-
-#: awx/settings/defaults.py:820
-msgid "Japan West"
-msgstr ""
-
-#: awx/settings/defaults.py:821
-msgid "Korea Central"
-msgstr ""
-
-#: awx/settings/defaults.py:822
-msgid "Korea South"
-msgstr ""
-
#: awx/sso/apps.py:9
msgid "Single Sign-On"
msgstr ""
@@ -5536,7 +5300,7 @@ msgid "Hostname of TACACS+ server."
msgstr ""
#: awx/sso/conf.py:480 awx/sso/conf.py:492 awx/sso/conf.py:504
-#: awx/sso/conf.py:516 awx/sso/conf.py:527 awx/sso/models.py:15
+#: awx/sso/conf.py:516 awx/sso/conf.py:528 awx/sso/models.py:15
msgid "TACACS+"
msgstr ""
@@ -5564,159 +5328,159 @@ msgstr ""
msgid "TACACS+ session timeout value in seconds, 0 disables timeout."
msgstr ""
-#: awx/sso/conf.py:525
+#: awx/sso/conf.py:526
msgid "TACACS+ Authentication Protocol"
msgstr ""
-#: awx/sso/conf.py:526
+#: awx/sso/conf.py:527
msgid "Choose the authentication protocol used by TACACS+ client."
msgstr ""
-#: awx/sso/conf.py:540
+#: awx/sso/conf.py:541
msgid "Google OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:541 awx/sso/conf.py:634 awx/sso/conf.py:699
+#: awx/sso/conf.py:542 awx/sso/conf.py:635 awx/sso/conf.py:700
msgid ""
"Provide this URL as the callback URL for your application as part of your "
"registration process. Refer to the Ansible Tower documentation for more "
"detail."
msgstr ""
-#: awx/sso/conf.py:544 awx/sso/conf.py:556 awx/sso/conf.py:568
-#: awx/sso/conf.py:581 awx/sso/conf.py:595 awx/sso/conf.py:607
-#: awx/sso/conf.py:619
+#: awx/sso/conf.py:545 awx/sso/conf.py:557 awx/sso/conf.py:569
+#: awx/sso/conf.py:582 awx/sso/conf.py:596 awx/sso/conf.py:608
+#: awx/sso/conf.py:620
msgid "Google OAuth2"
msgstr ""
-#: awx/sso/conf.py:554
+#: awx/sso/conf.py:555
msgid "Google OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:555
+#: awx/sso/conf.py:556
msgid "The OAuth2 key from your web application."
msgstr ""
-#: awx/sso/conf.py:566
+#: awx/sso/conf.py:567
msgid "Google OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:567
+#: awx/sso/conf.py:568
msgid "The OAuth2 secret from your web application."
msgstr ""
-#: awx/sso/conf.py:578
-msgid "Google OAuth2 Whitelisted Domains"
+#: awx/sso/conf.py:579
+msgid "Google OAuth2 Allowed Domains"
msgstr ""
-#: awx/sso/conf.py:579
+#: awx/sso/conf.py:580
msgid ""
"Update this setting to restrict the domains who are allowed to login using "
"Google OAuth2."
msgstr ""
-#: awx/sso/conf.py:590
+#: awx/sso/conf.py:591
msgid "Google OAuth2 Extra Arguments"
msgstr ""
-#: awx/sso/conf.py:591
+#: awx/sso/conf.py:592
msgid ""
"Extra arguments for Google OAuth2 login. You can restrict it to only allow a "
"single domain to authenticate, even if the user is logged in with multple "
"Google accounts. Refer to the Ansible Tower documentation for more detail."
msgstr ""
-#: awx/sso/conf.py:605
+#: awx/sso/conf.py:606
msgid "Google OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:617
+#: awx/sso/conf.py:618
msgid "Google OAuth2 Team Map"
msgstr ""
-#: awx/sso/conf.py:633
+#: awx/sso/conf.py:634
msgid "GitHub OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:637 awx/sso/conf.py:649 awx/sso/conf.py:660
-#: awx/sso/conf.py:672 awx/sso/conf.py:684
+#: awx/sso/conf.py:638 awx/sso/conf.py:650 awx/sso/conf.py:661
+#: awx/sso/conf.py:673 awx/sso/conf.py:685
msgid "GitHub OAuth2"
msgstr ""
-#: awx/sso/conf.py:647
+#: awx/sso/conf.py:648
msgid "GitHub OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:648
+#: awx/sso/conf.py:649
msgid "The OAuth2 key (Client ID) from your GitHub developer application."
msgstr ""
-#: awx/sso/conf.py:658
+#: awx/sso/conf.py:659
msgid "GitHub OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:659
+#: awx/sso/conf.py:660
msgid ""
"The OAuth2 secret (Client Secret) from your GitHub developer application."
msgstr ""
-#: awx/sso/conf.py:670
+#: awx/sso/conf.py:671
msgid "GitHub OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:682
+#: awx/sso/conf.py:683
msgid "GitHub OAuth2 Team Map"
msgstr ""
-#: awx/sso/conf.py:698
+#: awx/sso/conf.py:699
msgid "GitHub Organization OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:702 awx/sso/conf.py:714 awx/sso/conf.py:725
-#: awx/sso/conf.py:738 awx/sso/conf.py:749 awx/sso/conf.py:761
+#: awx/sso/conf.py:703 awx/sso/conf.py:715 awx/sso/conf.py:726
+#: awx/sso/conf.py:739 awx/sso/conf.py:750 awx/sso/conf.py:762
msgid "GitHub Organization OAuth2"
msgstr ""
-#: awx/sso/conf.py:712
+#: awx/sso/conf.py:713
msgid "GitHub Organization OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:713 awx/sso/conf.py:791
+#: awx/sso/conf.py:714 awx/sso/conf.py:792
msgid "The OAuth2 key (Client ID) from your GitHub organization application."
msgstr ""
-#: awx/sso/conf.py:723
+#: awx/sso/conf.py:724
msgid "GitHub Organization OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:724 awx/sso/conf.py:802
+#: awx/sso/conf.py:725 awx/sso/conf.py:803
msgid ""
"The OAuth2 secret (Client Secret) from your GitHub organization application."
msgstr ""
-#: awx/sso/conf.py:735
+#: awx/sso/conf.py:736
msgid "GitHub Organization Name"
msgstr ""
-#: awx/sso/conf.py:736
+#: awx/sso/conf.py:737
msgid ""
"The name of your GitHub organization, as used in your organization's URL: "
"https://github.com//."
msgstr ""
-#: awx/sso/conf.py:747
+#: awx/sso/conf.py:748
msgid "GitHub Organization OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:759
+#: awx/sso/conf.py:760
msgid "GitHub Organization OAuth2 Team Map"
msgstr ""
-#: awx/sso/conf.py:775
+#: awx/sso/conf.py:776
msgid "GitHub Team OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:776
+#: awx/sso/conf.py:777
msgid ""
"Create an organization-owned application at https://github.com/organizations/"
"/settings/applications and obtain an OAuth2 key (Client ID) and "
@@ -5724,172 +5488,182 @@ msgid ""
"application."
msgstr ""
-#: awx/sso/conf.py:780 awx/sso/conf.py:792 awx/sso/conf.py:803
-#: awx/sso/conf.py:816 awx/sso/conf.py:827 awx/sso/conf.py:839
+#: awx/sso/conf.py:781 awx/sso/conf.py:793 awx/sso/conf.py:804
+#: awx/sso/conf.py:817 awx/sso/conf.py:828 awx/sso/conf.py:840
msgid "GitHub Team OAuth2"
msgstr ""
-#: awx/sso/conf.py:790
+#: awx/sso/conf.py:791
msgid "GitHub Team OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:801
+#: awx/sso/conf.py:802
msgid "GitHub Team OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:813
+#: awx/sso/conf.py:814
msgid "GitHub Team ID"
msgstr ""
-#: awx/sso/conf.py:814
+#: awx/sso/conf.py:815
msgid ""
"Find the numeric team ID using the Github API: http://fabian-kostadinov."
"github.io/2015/01/16/how-to-find-a-github-team-id/."
msgstr ""
-#: awx/sso/conf.py:825
+#: awx/sso/conf.py:826
msgid "GitHub Team OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:837
+#: awx/sso/conf.py:838
msgid "GitHub Team OAuth2 Team Map"
msgstr ""
-#: awx/sso/conf.py:853
+#: awx/sso/conf.py:854
msgid "Azure AD OAuth2 Callback URL"
msgstr ""
-#: awx/sso/conf.py:854
+#: awx/sso/conf.py:855
msgid ""
"Provide this URL as the callback URL for your application as part of your "
"registration process. Refer to the Ansible Tower documentation for more "
"detail. "
msgstr ""
-#: awx/sso/conf.py:857 awx/sso/conf.py:869 awx/sso/conf.py:880
-#: awx/sso/conf.py:892 awx/sso/conf.py:904
+#: awx/sso/conf.py:858 awx/sso/conf.py:870 awx/sso/conf.py:881
+#: awx/sso/conf.py:893 awx/sso/conf.py:905
msgid "Azure AD OAuth2"
msgstr ""
-#: awx/sso/conf.py:867
+#: awx/sso/conf.py:868
msgid "Azure AD OAuth2 Key"
msgstr ""
-#: awx/sso/conf.py:868
+#: awx/sso/conf.py:869
msgid "The OAuth2 key (Client ID) from your Azure AD application."
msgstr ""
-#: awx/sso/conf.py:878
+#: awx/sso/conf.py:879
msgid "Azure AD OAuth2 Secret"
msgstr ""
-#: awx/sso/conf.py:879
+#: awx/sso/conf.py:880
msgid "The OAuth2 secret (Client Secret) from your Azure AD application."
msgstr ""
-#: awx/sso/conf.py:890
+#: awx/sso/conf.py:891
msgid "Azure AD OAuth2 Organization Map"
msgstr ""
-#: awx/sso/conf.py:902
+#: awx/sso/conf.py:903
msgid "Azure AD OAuth2 Team Map"
msgstr ""
#: awx/sso/conf.py:927
-msgid "SAML Assertion Consumer Service (ACS) URL"
+msgid "Automatically Create Organizations and Teams on SAML Login"
msgstr ""
#: awx/sso/conf.py:928
msgid ""
+"When enabled (the default), mapped Organizations and Teams will be created "
+"automatically on successful SAML login."
+msgstr ""
+
+#: awx/sso/conf.py:930 awx/sso/conf.py:943 awx/sso/conf.py:956
+#: awx/sso/conf.py:969 awx/sso/conf.py:983 awx/sso/conf.py:996
+#: awx/sso/conf.py:1008 awx/sso/conf.py:1028 awx/sso/conf.py:1045
+#: awx/sso/conf.py:1063 awx/sso/conf.py:1098 awx/sso/conf.py:1129
+#: awx/sso/conf.py:1142 awx/sso/conf.py:1158 awx/sso/conf.py:1170
+#: awx/sso/conf.py:1182 awx/sso/conf.py:1201 awx/sso/models.py:16
+msgid "SAML"
+msgstr ""
+
+#: awx/sso/conf.py:939
+msgid "SAML Assertion Consumer Service (ACS) URL"
+msgstr ""
+
+#: awx/sso/conf.py:940
+msgid ""
"Register Tower as a service provider (SP) with each identity provider (IdP) "
"you have configured. Provide your SP Entity ID and this ACS URL for your "
"application."
msgstr ""
-#: awx/sso/conf.py:931 awx/sso/conf.py:944 awx/sso/conf.py:957
-#: awx/sso/conf.py:971 awx/sso/conf.py:984 awx/sso/conf.py:996
-#: awx/sso/conf.py:1016 awx/sso/conf.py:1033 awx/sso/conf.py:1051
-#: awx/sso/conf.py:1086 awx/sso/conf.py:1117 awx/sso/conf.py:1130
-#: awx/sso/conf.py:1146 awx/sso/conf.py:1158 awx/sso/conf.py:1170
-#: awx/sso/conf.py:1189 awx/sso/models.py:16
-msgid "SAML"
-msgstr ""
-
-#: awx/sso/conf.py:941
+#: awx/sso/conf.py:953
msgid "SAML Service Provider Metadata URL"
msgstr ""
-#: awx/sso/conf.py:942
+#: awx/sso/conf.py:954
msgid ""
"If your identity provider (IdP) allows uploading an XML metadata file, you "
"can download one from this URL."
msgstr ""
-#: awx/sso/conf.py:953
+#: awx/sso/conf.py:965
msgid "SAML Service Provider Entity ID"
msgstr ""
-#: awx/sso/conf.py:954
+#: awx/sso/conf.py:966
msgid ""
"The application-defined unique identifier used as the audience of the SAML "
"service provider (SP) configuration. This is usually the URL for Tower."
msgstr ""
-#: awx/sso/conf.py:968
+#: awx/sso/conf.py:980
msgid "SAML Service Provider Public Certificate"
msgstr ""
-#: awx/sso/conf.py:969
+#: awx/sso/conf.py:981
msgid ""
"Create a keypair for Tower to use as a service provider (SP) and include the "
"certificate content here."
msgstr ""
-#: awx/sso/conf.py:981
+#: awx/sso/conf.py:993
msgid "SAML Service Provider Private Key"
msgstr ""
-#: awx/sso/conf.py:982
+#: awx/sso/conf.py:994
msgid ""
"Create a keypair for Tower to use as a service provider (SP) and include the "
"private key content here."
msgstr ""
-#: awx/sso/conf.py:993
+#: awx/sso/conf.py:1005
msgid "SAML Service Provider Organization Info"
msgstr ""
-#: awx/sso/conf.py:994
+#: awx/sso/conf.py:1006
msgid ""
"Provide the URL, display name, and the name of your app. Refer to the "
"Ansible Tower documentation for example syntax."
msgstr ""
-#: awx/sso/conf.py:1012
+#: awx/sso/conf.py:1024
msgid "SAML Service Provider Technical Contact"
msgstr ""
-#: awx/sso/conf.py:1013
+#: awx/sso/conf.py:1025
msgid ""
"Provide the name and email address of the technical contact for your service "
"provider. Refer to the Ansible Tower documentation for example syntax."
msgstr ""
-#: awx/sso/conf.py:1029
+#: awx/sso/conf.py:1041
msgid "SAML Service Provider Support Contact"
msgstr ""
-#: awx/sso/conf.py:1030
+#: awx/sso/conf.py:1042
msgid ""
"Provide the name and email address of the support contact for your service "
"provider. Refer to the Ansible Tower documentation for example syntax."
msgstr ""
-#: awx/sso/conf.py:1045
+#: awx/sso/conf.py:1057
msgid "SAML Enabled Identity Providers"
msgstr ""
-#: awx/sso/conf.py:1046
+#: awx/sso/conf.py:1058
msgid ""
"Configure the Entity ID, SSO URL and certificate for each identity provider "
"(IdP) in use. Multiple SAML IdPs are supported. Some IdPs may provide user "
@@ -5898,57 +5672,57 @@ msgid ""
"additional details and syntax."
msgstr ""
-#: awx/sso/conf.py:1082
+#: awx/sso/conf.py:1094
msgid "SAML Security Config"
msgstr ""
-#: awx/sso/conf.py:1083
+#: awx/sso/conf.py:1095
msgid ""
"A dict of key value pairs that are passed to the underlying python-saml "
"security setting https://github.com/onelogin/python-saml#settings"
msgstr ""
-#: awx/sso/conf.py:1114
+#: awx/sso/conf.py:1126
msgid "SAML Service Provider extra configuration data"
msgstr ""
-#: awx/sso/conf.py:1115
+#: awx/sso/conf.py:1127
msgid ""
"A dict of key value pairs to be passed to the underlying python-saml Service "
"Provider configuration setting."
msgstr ""
-#: awx/sso/conf.py:1127
+#: awx/sso/conf.py:1139
msgid "SAML IDP to extra_data attribute mapping"
msgstr ""
-#: awx/sso/conf.py:1128
+#: awx/sso/conf.py:1140
msgid ""
"A list of tuples that maps IDP attributes to extra_attributes. Each "
"attribute will be a list of values, even if only 1 value."
msgstr ""
-#: awx/sso/conf.py:1144
+#: awx/sso/conf.py:1156
msgid "SAML Organization Map"
msgstr ""
-#: awx/sso/conf.py:1156
+#: awx/sso/conf.py:1168
msgid "SAML Team Map"
msgstr ""
-#: awx/sso/conf.py:1168
+#: awx/sso/conf.py:1180
msgid "SAML Organization Attribute Mapping"
msgstr ""
-#: awx/sso/conf.py:1169
+#: awx/sso/conf.py:1181
msgid "Used to translate user organization membership into Tower."
msgstr ""
-#: awx/sso/conf.py:1187
+#: awx/sso/conf.py:1199
msgid "SAML Team Attribute Mapping"
msgstr ""
-#: awx/sso/conf.py:1188
+#: awx/sso/conf.py:1200
msgid "Used to translate user team membership into Tower."
msgstr ""
@@ -6015,12 +5789,12 @@ msgstr ""
msgid "Invalid language code(s) for org info: {invalid_lang_codes}."
msgstr ""
-#: awx/sso/pipeline.py:27
+#: awx/sso/pipeline.py:28
#, python-brace-format
msgid "An account cannot be found for {0}"
msgstr ""
-#: awx/sso/pipeline.py:33
+#: awx/sso/pipeline.py:34
msgid "Your account is inactive"
msgstr ""
@@ -6092,8 +5866,8 @@ msgstr ""
msgid ""
"If needed, you can add specific information (such as a legal notice or a "
"disclaimer) to a text box in the login modal using this setting. Any content "
-"added must be in plain text, as custom HTML or other markup languages are "
-"not supported."
+"added must be in plain text or an HTML fragment, as other markup languages "
+"are not supported."
msgstr ""
#: awx/ui/conf.py:45
diff --git a/awx/locale/ja/LC_MESSAGES/django.po b/awx/locale/ja/LC_MESSAGES/django.po
index a878a3d1ad..abc2ad15aa 100644
--- a/awx/locale/ja/LC_MESSAGES/django.po
+++ b/awx/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-05-28 21:45+0000\n"
+"POT-Creation-Date: 2020-09-29 15:20+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -126,27 +126,27 @@ msgstr "クエリー文字列フィールド名は指定されていません。
msgid "Invalid {field_name} id: {field_id}"
msgstr "無効な {field_name} id: {field_id}"
-#: awx/api/filters.py:333
+#: awx/api/filters.py:338
msgid ""
"Cannot apply role_level filter to this list because its model does not use "
"roles for access control."
msgstr "モデルがアクセスコントロールにロールを使用していないので、このリストに role_level フィルターを適用できません。"
-#: awx/api/generics.py:182
+#: awx/api/generics.py:183
msgid ""
"You did not use correct Content-Type in your HTTP request. If you are using "
"our REST API, the Content-Type must be application/json"
msgstr "HTTP 要求で正しい Content-Type (コンテンツタイプ) が使用されていません。REST API を使用している場合、Content-Type (コンテンツタイプ) は「application/json」でなければなりません。"
-#: awx/api/generics.py:623 awx/api/generics.py:685
+#: awx/api/generics.py:647 awx/api/generics.py:709
msgid "\"id\" field must be an integer."
msgstr "「id」フィールドは整数でなければなりません。"
-#: awx/api/generics.py:682
+#: awx/api/generics.py:706
msgid "\"id\" is required to disassociate"
msgstr "関連付けを解除するには 「id」が必要です"
-#: awx/api/generics.py:733
+#: awx/api/generics.py:757
msgid "{} 'id' field is missing."
msgstr "{} 「id」フィールドがありません。"
@@ -219,7 +219,7 @@ msgstr "Playbook 実行"
msgid "Command"
msgstr "コマンド"
-#: awx/api/serializers.py:318 awx/main/models/unified_jobs.py:547
+#: awx/api/serializers.py:318 awx/main/models/unified_jobs.py:546
msgid "SCM Update"
msgstr "SCM 更新"
@@ -249,1139 +249,1161 @@ msgid ""
"saved to the database."
msgstr "この統一されたジョブで生成されるイベントすべてがデータベースに保存されているかどうかを示します。"
-#: awx/api/serializers.py:878
+#: awx/api/serializers.py:880
msgid "Write-only field used to change the password."
msgstr "パスワードを変更するために使用される書き込み専用フィールド。"
-#: awx/api/serializers.py:880
+#: awx/api/serializers.py:882
msgid "Set if the account is managed by an external service"
msgstr "アカウントが外部サービスで管理される場合に設定されます"
-#: awx/api/serializers.py:907
+#: awx/api/serializers.py:909
msgid "Password required for new User."
msgstr "新規ユーザーのパスワードを入力してください。"
-#: awx/api/serializers.py:992
+#: awx/api/serializers.py:994
#, python-format
msgid "Unable to change %s on user managed by LDAP."
msgstr "LDAP で管理されたユーザーの %s を変更できません。"
-#: awx/api/serializers.py:1088
+#: awx/api/serializers.py:1090
msgid "Must be a simple space-separated string with allowed scopes {}."
msgstr "許可されたスコープ {} のある単純なスペースで区切られた文字列でなければなりません。"
-#: awx/api/serializers.py:1186
+#: awx/api/serializers.py:1188
msgid "Authorization Grant Type"
msgstr "認証付与タイプ"
-#: awx/api/serializers.py:1188 awx/main/credential_plugins/azure_kv.py:30
-#: awx/main/models/credential/__init__.py:960
+#: awx/api/serializers.py:1190 awx/main/credential_plugins/azure_kv.py:30
+#: awx/main/models/credential/__init__.py:972
msgid "Client Secret"
msgstr "クライアントシークレット"
-#: awx/api/serializers.py:1191
+#: awx/api/serializers.py:1193
msgid "Client Type"
msgstr "クライアントタイプ"
-#: awx/api/serializers.py:1194
+#: awx/api/serializers.py:1196
msgid "Redirect URIs"
msgstr "リダイレクト URI"
-#: awx/api/serializers.py:1197
+#: awx/api/serializers.py:1199
msgid "Skip Authorization"
msgstr "認証のスキップ"
-#: awx/api/serializers.py:1303
+#: awx/api/serializers.py:1306
msgid "Cannot change max_hosts."
msgstr "max_hosts を変更できません。"
-#: awx/api/serializers.py:1336
+#: awx/api/serializers.py:1339
msgid "This path is already being used by another manual project."
msgstr "このパスは別の手動プロジェクトですでに使用されています。"
-#: awx/api/serializers.py:1338
+#: awx/api/serializers.py:1341
+msgid "SCM branch cannot be used with archive projects."
+msgstr "SCM ブランチはアーカイブプロジェクトでは使用できません。"
+
+#: awx/api/serializers.py:1343
msgid "SCM refspec can only be used with git projects."
msgstr "SCM refspec は、git プロジェクトでのみ使用できます。"
-#: awx/api/serializers.py:1415
+#: awx/api/serializers.py:1420
msgid ""
"One or more job templates depend on branch override behavior for this "
"project (ids: {})."
msgstr "1 つまたは複数のジョブテンプレートは、このプロジェクトのブランチオーバーライドに依存しています (ids: {})。"
-#: awx/api/serializers.py:1422
+#: awx/api/serializers.py:1427
msgid "Update options must be set to false for manual projects."
msgstr "手動プロジェクトについては更新オプションを false に設定する必要があります。"
-#: awx/api/serializers.py:1428
+#: awx/api/serializers.py:1433
msgid "Array of playbooks available within this project."
msgstr "このプロジェクト内で利用可能な一連の Playbook。"
-#: awx/api/serializers.py:1447
+#: awx/api/serializers.py:1452
msgid ""
"Array of inventory files and directories available within this project, not "
"comprehensive."
msgstr "このプロジェクト内で利用可能な一連のインベントリーファイルおよびディレクトリー (包括的な一覧ではありません)。"
-#: awx/api/serializers.py:1495 awx/api/serializers.py:3048
-#: awx/api/serializers.py:3260
+#: awx/api/serializers.py:1500 awx/api/serializers.py:3089
+#: awx/api/serializers.py:3301
msgid "A count of hosts uniquely assigned to each status."
msgstr "各ステータスに一意に割り当てられたホスト数です。"
-#: awx/api/serializers.py:1498 awx/api/serializers.py:3051
+#: awx/api/serializers.py:1503 awx/api/serializers.py:3092
msgid "A count of all plays and tasks for the job run."
msgstr "ジョブ実行用のすべてのプレイおよびタスクの数です。"
-#: awx/api/serializers.py:1625
+#: awx/api/serializers.py:1630
msgid "Smart inventories must specify host_filter"
msgstr "スマートインベントリーは host_filter を指定する必要があります"
-#: awx/api/serializers.py:1713
+#: awx/api/serializers.py:1722
#, python-format
msgid "Invalid port specification: %s"
msgstr "無効なポート指定: %s"
-#: awx/api/serializers.py:1724
+#: awx/api/serializers.py:1733
msgid "Cannot create Host for Smart Inventory"
msgstr "スマートインベントリーのホストを作成できません"
-#: awx/api/serializers.py:1808
+#: awx/api/serializers.py:1751
+msgid "A Group with that name already exists."
+msgstr "その名前のグループはすでに存在します。"
+
+#: awx/api/serializers.py:1822
+msgid "A Host with that name already exists."
+msgstr "その名前のホストはすでに存在します。"
+
+#: awx/api/serializers.py:1827
msgid "Invalid group name."
msgstr "無効なグループ名。"
-#: awx/api/serializers.py:1813
+#: awx/api/serializers.py:1832
msgid "Cannot create Group for Smart Inventory"
msgstr "スマートインベントリーのグループを作成できません"
-#: awx/api/serializers.py:1888
+#: awx/api/serializers.py:1907
msgid ""
"Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python"
msgstr "スクリプトは hashbang シーケンスで開始する必要があります (例: .... #!/usr/bin/env python)"
-#: awx/api/serializers.py:1917
+#: awx/api/serializers.py:1936
msgid "Cloud credential to use for inventory updates."
msgstr "インベントリー更新に使用するクラウド認証情報"
-#: awx/api/serializers.py:1938
+#: awx/api/serializers.py:1957
msgid "`{}` is a prohibited environment variable"
msgstr "`{}` は禁止されている環境変数です"
-#: awx/api/serializers.py:1949
+#: awx/api/serializers.py:1968
msgid "If 'source' is 'custom', 'source_script' must be provided."
msgstr "「source」が「custom」である場合、「source_script」を指定する必要があります。"
-#: awx/api/serializers.py:1955
+#: awx/api/serializers.py:1974
msgid "Must provide an inventory."
msgstr "インベントリーを指定する必要があります。"
-#: awx/api/serializers.py:1959
+#: awx/api/serializers.py:1978
msgid ""
"The 'source_script' does not belong to the same organization as the "
"inventory."
msgstr "「source_script」はインベントリーと同じ組織に属しません。"
-#: awx/api/serializers.py:1961
+#: awx/api/serializers.py:1980
msgid "'source_script' doesn't exist."
msgstr "「source_script」は存在しません。"
-#: awx/api/serializers.py:2063
+#: awx/api/serializers.py:2082
msgid "Cannot use manual project for SCM-based inventory."
msgstr "SCM ベースのインベントリーの手動プロジェクトを使用できません。"
-#: awx/api/serializers.py:2068
+#: awx/api/serializers.py:2087
msgid "Setting not compatible with existing schedules."
msgstr "設定は既存スケジュールとの互換性がありません。"
-#: awx/api/serializers.py:2073
+#: awx/api/serializers.py:2092
msgid "Cannot create Inventory Source for Smart Inventory"
msgstr "スマートインベントリーのインベントリーソースを作成できません"
-#: awx/api/serializers.py:2121
+#: awx/api/serializers.py:2140
msgid "Project required for scm type sources."
msgstr "SCM タイプのソースに必要なプロジェクト。"
-#: awx/api/serializers.py:2130
+#: awx/api/serializers.py:2149
#, python-format
msgid "Cannot set %s if not SCM type."
msgstr "SCM タイプでない場合 %s を設定できません。"
-#: awx/api/serializers.py:2200
+#: awx/api/serializers.py:2219
msgid "The project used for this job."
msgstr "このジョブに使用するプロジェクト"
-#: awx/api/serializers.py:2455
+#: awx/api/serializers.py:2475
msgid "Modifications not allowed for managed credential types"
msgstr "管理されている認証情報タイプで変更は許可されません"
-#: awx/api/serializers.py:2467
+#: awx/api/serializers.py:2487
msgid ""
"Modifications to inputs are not allowed for credential types that are in use"
msgstr "入力への変更は使用中の認証情報タイプで許可されません"
-#: awx/api/serializers.py:2472
+#: awx/api/serializers.py:2492
#, python-format
msgid "Must be 'cloud' or 'net', not %s"
msgstr "「cloud」または「net」にする必要があります (%s ではない)"
-#: awx/api/serializers.py:2478
+#: awx/api/serializers.py:2498
msgid "'ask_at_runtime' is not supported for custom credentials."
msgstr "「ask_at_runtime」はカスタム認証情報ではサポートされません。"
-#: awx/api/serializers.py:2526
+#: awx/api/serializers.py:2547
msgid "Credential Type"
msgstr "認証情報タイプ"
-#: awx/api/serializers.py:2607
+#: awx/api/serializers.py:2611
+msgid "Modifications not allowed for managed credentials"
+msgstr "管理されている認証情報では変更が許可されません"
+
+#: awx/api/serializers.py:2629 awx/api/serializers.py:2703
+msgid "Galaxy credentials must be owned by an Organization."
+msgstr "Galaxy 認証情報は組織が所有している必要があります。"
+
+#: awx/api/serializers.py:2646
msgid ""
"You cannot change the credential type of the credential, as it may break the "
"functionality of the resources using it."
msgstr "認証情報の認証情報タイプを変更することはできません。これにより、認証情報を使用するリソースの機能が中断する可能性があるためです。"
-#: awx/api/serializers.py:2619
+#: awx/api/serializers.py:2658
msgid ""
"Write-only field used to add user to owner role. If provided, do not give "
"either team or organization. Only valid for creation."
msgstr "ユーザーを所有者ロールに追加するために使用される書き込み専用フィールドです。提供されている場合は、チームまたは組織のいずれも指定しないでください。作成時にのみ有効です。"
-#: awx/api/serializers.py:2624
+#: awx/api/serializers.py:2663
msgid ""
"Write-only field used to add team to owner role. If provided, do not give "
"either user or organization. Only valid for creation."
msgstr "チームを所有者ロールに追加するために使用される書き込み専用フィールドです。提供されている場合は、ユーザーまたは組織のいずれも指定しないでください。作成時にのみ有効です。"
-#: awx/api/serializers.py:2629
+#: awx/api/serializers.py:2668
msgid ""
"Inherit permissions from organization roles. If provided on creation, do not "
"give either user or team."
msgstr "組織ロールからパーミッションを継承します。作成時に提供される場合は、ユーザーまたはチームのいずれも指定しないでください。"
-#: awx/api/serializers.py:2645
+#: awx/api/serializers.py:2685
msgid "Missing 'user', 'team', or 'organization'."
msgstr "「user」、「team」、または「organization」がありません。"
-#: awx/api/serializers.py:2662
+#: awx/api/serializers.py:2690
+msgid ""
+"Only one of 'user', 'team', or 'organization' should be provided, received "
+"{} fields."
+msgstr "「user」、「team」、または「organization」のいずれか 1 つのみを指定し、{} フィールドを受け取る必要があります。"
+
+#: awx/api/serializers.py:2718
msgid ""
"Credential organization must be set and match before assigning to a team"
msgstr "認証情報の組織が設定され、一致している状態でチームに割り当てる必要があります。"
-#: awx/api/serializers.py:2793
+#: awx/api/serializers.py:2844
msgid "This field is required."
msgstr "このフィールドは必須です。"
-#: awx/api/serializers.py:2802
+#: awx/api/serializers.py:2853
msgid "Playbook not found for project."
msgstr "プロジェクトの Playbook が見つかりません。"
-#: awx/api/serializers.py:2804
+#: awx/api/serializers.py:2855
msgid "Must select playbook for project."
msgstr "プロジェクトの Playbook を選択してください。"
-#: awx/api/serializers.py:2806 awx/api/serializers.py:2808
+#: awx/api/serializers.py:2857 awx/api/serializers.py:2859
msgid "Project does not allow overriding branch."
msgstr "プロジェクトは、ブランチをオーバーライドできません。"
-#: awx/api/serializers.py:2845
+#: awx/api/serializers.py:2896
msgid "Must be a Personal Access Token."
msgstr "パーソナルアクセストークンである必要があります。"
-#: awx/api/serializers.py:2848
+#: awx/api/serializers.py:2899
msgid "Must match the selected webhook service."
msgstr "選択した Webhook サービスと一致する必要があります。"
-#: awx/api/serializers.py:2919
+#: awx/api/serializers.py:2970
msgid "Cannot enable provisioning callback without an inventory set."
msgstr "インベントリー設定なしにプロビジョニングコールバックを有効にすることはできません。"
-#: awx/api/serializers.py:2922
+#: awx/api/serializers.py:2973
msgid "Must either set a default value or ask to prompt on launch."
msgstr "起動時にプロントを出すには、デフォルト値を設定するか、またはプロンプトを出すよう指定する必要があります。"
-#: awx/api/serializers.py:2924 awx/main/models/jobs.py:299
+#: awx/api/serializers.py:2975 awx/main/models/jobs.py:299
msgid "Job Templates must have a project assigned."
msgstr "ジョブテンプレートにはプロジェクトを割り当てる必要があります。"
-#: awx/api/serializers.py:3092
+#: awx/api/serializers.py:3133
msgid "No change to job limit"
msgstr "ジョブ制限に変更はありません"
-#: awx/api/serializers.py:3093
+#: awx/api/serializers.py:3134
msgid "All failed and unreachable hosts"
msgstr "失敗している、到達できないすべてのホスト"
-#: awx/api/serializers.py:3108
+#: awx/api/serializers.py:3149
msgid "Missing passwords needed to start: {}"
msgstr "起動に必要なパスワードが見つかりません: {}"
-#: awx/api/serializers.py:3127
+#: awx/api/serializers.py:3168
msgid "Relaunch by host status not available until job finishes running."
msgstr "ホストのステータス別の再起動はジョブが実行を終了するまで利用できません。"
-#: awx/api/serializers.py:3141
+#: awx/api/serializers.py:3182
msgid "Job Template Project is missing or undefined."
msgstr "ジョブテンプレートプロジェクトが見つからないか、または定義されていません。"
-#: awx/api/serializers.py:3143
+#: awx/api/serializers.py:3184
msgid "Job Template Inventory is missing or undefined."
msgstr "ジョブテンプレートインベントリーが見つからないか、または定義されていません。"
-#: awx/api/serializers.py:3181
+#: awx/api/serializers.py:3222
msgid "Unknown, job may have been ran before launch configurations were saved."
msgstr "不明です。ジョブは起動設定が保存される前に実行された可能性があります。"
-#: awx/api/serializers.py:3252 awx/main/tasks.py:2800 awx/main/tasks.py:2818
+#: awx/api/serializers.py:3293 awx/main/tasks.py:2838 awx/main/tasks.py:2856
msgid "{} are prohibited from use in ad hoc commands."
msgstr "{} の使用はアドホックコマンドで禁止されています。"
-#: awx/api/serializers.py:3340 awx/api/views/__init__.py:4243
+#: awx/api/serializers.py:3381 awx/api/views/__init__.py:4211
#, python-brace-format
msgid ""
"Standard Output too large to display ({text_size} bytes), only download "
"supported for sizes over {supported_size} bytes."
msgstr "標準出力が大きすぎて表示できません ({text_size} バイト)。サイズが {supported_size} バイトを超える場合はダウンロードのみがサポートされます。"
-#: awx/api/serializers.py:3653
+#: awx/api/serializers.py:3694
msgid "Provided variable {} has no database value to replace with."
msgstr "指定された変数 {} には置き換えるデータベースの値がありません。"
-#: awx/api/serializers.py:3671
+#: awx/api/serializers.py:3712
msgid "\"$encrypted$ is a reserved keyword, may not be used for {}.\""
msgstr "\"$encrypted$ は予約されたキーワードで、{} には使用できません。\""
-#: awx/api/serializers.py:4078
+#: awx/api/serializers.py:4119
msgid "A project is required to run a job."
msgstr "ジョブを実行するにはプロジェクトが必要です。"
-#: awx/api/serializers.py:4080
+#: awx/api/serializers.py:4121
msgid "Missing a revision to run due to failed project update."
msgstr "プロジェクトの更新に失敗したため、実行するリビジョンがありません。"
-#: awx/api/serializers.py:4084
+#: awx/api/serializers.py:4125
msgid "The inventory associated with this Job Template is being deleted."
msgstr "このジョブテンプレートに関連付けられているインベントリーが削除されています。"
-#: awx/api/serializers.py:4086 awx/api/serializers.py:4202
+#: awx/api/serializers.py:4127 awx/api/serializers.py:4244
msgid "The provided inventory is being deleted."
msgstr "指定されたインベントリーが削除されています。"
-#: awx/api/serializers.py:4094
+#: awx/api/serializers.py:4135
msgid "Cannot assign multiple {} credentials."
msgstr "複数の {} 認証情報を割り当てることができません。"
-#: awx/api/serializers.py:4098
+#: awx/api/serializers.py:4140
msgid "Cannot assign a Credential of kind `{}`"
msgstr "`{}`の種類の認証情報を割り当てることができません。"
-#: awx/api/serializers.py:4111
+#: awx/api/serializers.py:4153
msgid ""
"Removing {} credential at launch time without replacement is not supported. "
"Provided list lacked credential(s): {}."
msgstr "置き換えなしで起動時に {} 認証情報を削除することはサポートされていません。指定された一覧には認証情報がありません: {}"
-#: awx/api/serializers.py:4200
+#: awx/api/serializers.py:4242
msgid "The inventory associated with this Workflow is being deleted."
msgstr "このワークフローに関連付けられているインベントリーが削除されています。"
-#: awx/api/serializers.py:4271
+#: awx/api/serializers.py:4313
msgid "Message type '{}' invalid, must be either 'message' or 'body'"
msgstr "メッセージタイプ '{}' が無効です。'メッセージ' または 'ボディー' のいずれかに指定する必要があります。"
-#: awx/api/serializers.py:4277
+#: awx/api/serializers.py:4319
msgid "Expected string for '{}', found {}, "
msgstr "'{}' の文字列が必要ですが、{} が見つかりました。 "
-#: awx/api/serializers.py:4281
+#: awx/api/serializers.py:4323
msgid "Messages cannot contain newlines (found newline in {} event)"
msgstr "メッセージでは改行を追加できません ({} イベントに改行が含まれます)"
-#: awx/api/serializers.py:4287
+#: awx/api/serializers.py:4329
msgid "Expected dict for 'messages' field, found {}"
msgstr "'messages' フィールドには辞書が必要ですが、{} が見つかりました。"
-#: awx/api/serializers.py:4291
+#: awx/api/serializers.py:4333
msgid ""
"Event '{}' invalid, must be one of 'started', 'success', 'error', or "
"'workflow_approval'"
msgstr "イベント '{}' は無効です。'started'、'success'、'error' または 'workflow_approval' のいずれかでなければなりません。"
-#: awx/api/serializers.py:4297
+#: awx/api/serializers.py:4339
msgid "Expected dict for event '{}', found {}"
msgstr "イベント '{}' には辞書が必要ですが、{} が見つかりました。"
-#: awx/api/serializers.py:4302
+#: awx/api/serializers.py:4344
msgid ""
"Workflow Approval event '{}' invalid, must be one of 'running', 'approved', "
"'timed_out', or 'denied'"
msgstr "ワークフロー承認イベント '{}' が無効です。'running'、'approved'、'timed_out' または 'denied' のいずれかでなければなりません。"
-#: awx/api/serializers.py:4309
+#: awx/api/serializers.py:4351
msgid "Expected dict for workflow approval event '{}', found {}"
msgstr "ワークフロー承認イベント '{}' には辞書が必要ですが、{} が見つかりました。"
-#: awx/api/serializers.py:4336
+#: awx/api/serializers.py:4378
msgid "Unable to render message '{}': {}"
msgstr "メッセージ '{}' のレンダリングができません: {}"
-#: awx/api/serializers.py:4338
+#: awx/api/serializers.py:4380
msgid "Field '{}' unavailable"
msgstr "フィールド '{}' が利用できません"
-#: awx/api/serializers.py:4340
+#: awx/api/serializers.py:4382
msgid "Security error due to field '{}'"
msgstr "フィールド '{}' が原因のセキュリティーエラー"
-#: awx/api/serializers.py:4360
+#: awx/api/serializers.py:4402
msgid "Webhook body for '{}' should be a json dictionary. Found type '{}'."
msgstr "'{}' の Webhook のボディーは json 辞書でなければなりません。'{}' のタイプが見つかりました。"
-#: awx/api/serializers.py:4363
+#: awx/api/serializers.py:4405
msgid "Webhook body for '{}' is not a valid json dictionary ({})."
msgstr "'{}' の Webhook ボディーは有効な json 辞書ではありません ({})。"
-#: awx/api/serializers.py:4381
+#: awx/api/serializers.py:4423
msgid ""
"Missing required fields for Notification Configuration: notification_type"
msgstr "通知設定の必須フィールドがありません: notification_type"
-#: awx/api/serializers.py:4408
+#: awx/api/serializers.py:4450
msgid "No values specified for field '{}'"
msgstr "フィールド '{}' に値が指定されていません"
-#: awx/api/serializers.py:4413
+#: awx/api/serializers.py:4455
msgid "HTTP method must be either 'POST' or 'PUT'."
msgstr "HTTP メソッドは 'POST' または 'PUT' のいずれかでなければなりません。"
-#: awx/api/serializers.py:4415
+#: awx/api/serializers.py:4457
msgid "Missing required fields for Notification Configuration: {}."
msgstr "通知設定の必須フィールドがありません: {}。"
-#: awx/api/serializers.py:4418
+#: awx/api/serializers.py:4460
msgid "Configuration field '{}' incorrect type, expected {}."
msgstr "設定フィールド '{}' のタイプが正しくありません。{} が予期されました。"
-#: awx/api/serializers.py:4435
+#: awx/api/serializers.py:4477
msgid "Notification body"
msgstr "通知ボディー"
-#: awx/api/serializers.py:4515
+#: awx/api/serializers.py:4557
msgid ""
"Valid DTSTART required in rrule. Value should start with: DTSTART:"
"YYYYMMDDTHHMMSSZ"
msgstr "有効な DTSTART が rrule で必要です。値は DTSTART:YYYYMMDDTHHMMSSZ で開始する必要があります。"
-#: awx/api/serializers.py:4517
+#: awx/api/serializers.py:4559
msgid ""
"DTSTART cannot be a naive datetime. Specify ;TZINFO= or YYYYMMDDTHHMMSSZZ."
msgstr "DTSTART をネイティブの日時にすることができません。;TZINFO= or YYYYMMDDTHHMMSSZZ を指定します。"
-#: awx/api/serializers.py:4519
+#: awx/api/serializers.py:4561
msgid "Multiple DTSTART is not supported."
msgstr "複数の DTSTART はサポートされません。"
-#: awx/api/serializers.py:4521
+#: awx/api/serializers.py:4563
msgid "RRULE required in rrule."
msgstr "RRULE が rrule で必要です。"
-#: awx/api/serializers.py:4523
+#: awx/api/serializers.py:4565
msgid "Multiple RRULE is not supported."
msgstr "複数の RRULE はサポートされません。"
-#: awx/api/serializers.py:4525
+#: awx/api/serializers.py:4567
msgid "INTERVAL required in rrule."
msgstr "INTERVAL が rrule で必要です。"
-#: awx/api/serializers.py:4527
+#: awx/api/serializers.py:4569
msgid "SECONDLY is not supported."
msgstr "SECONDLY はサポートされません。"
-#: awx/api/serializers.py:4529
+#: awx/api/serializers.py:4571
msgid "Multiple BYMONTHDAYs not supported."
msgstr "複数の BYMONTHDAY はサポートされません。"
-#: awx/api/serializers.py:4531
+#: awx/api/serializers.py:4573
msgid "Multiple BYMONTHs not supported."
msgstr "複数の BYMONTH はサポートされません。"
-#: awx/api/serializers.py:4533
+#: awx/api/serializers.py:4575
msgid "BYDAY with numeric prefix not supported."
msgstr "数字の接頭辞のある BYDAY はサポートされません。"
-#: awx/api/serializers.py:4535
+#: awx/api/serializers.py:4577
msgid "BYYEARDAY not supported."
msgstr "BYYEARDAY はサポートされません。"
-#: awx/api/serializers.py:4537
+#: awx/api/serializers.py:4579
msgid "BYWEEKNO not supported."
msgstr "BYWEEKNO はサポートされません。"
-#: awx/api/serializers.py:4539
+#: awx/api/serializers.py:4581
msgid "RRULE may not contain both COUNT and UNTIL"
msgstr "RRULE には COUNT と UNTIL の両方を含めることができません"
-#: awx/api/serializers.py:4543
+#: awx/api/serializers.py:4585
msgid "COUNT > 999 is unsupported."
msgstr "COUNT > 999 はサポートされません。"
-#: awx/api/serializers.py:4549
+#: awx/api/serializers.py:4591
msgid "rrule parsing failed validation: {}"
msgstr "rrule の構文解析で検証に失敗しました: {}"
-#: awx/api/serializers.py:4611
+#: awx/api/serializers.py:4653
msgid "Inventory Source must be a cloud resource."
msgstr "インベントリーソースはクラウドリソースでなければなりません。"
-#: awx/api/serializers.py:4613
+#: awx/api/serializers.py:4655
msgid "Manual Project cannot have a schedule set."
msgstr "手動プロジェクトにはスケジュールを設定できません。"
-#: awx/api/serializers.py:4616
+#: awx/api/serializers.py:4658
msgid ""
"Inventory sources with `update_on_project_update` cannot be scheduled. "
"Schedule its source project `{}` instead."
msgstr "「update_on_project_update」が設定されたインベントリーソースはスケジュールできません。代わりのそのソースプロジェクト「{}」 をスケジュールします。"
-#: awx/api/serializers.py:4626
+#: awx/api/serializers.py:4668
msgid ""
"Count of jobs in the running or waiting state that are targeted for this "
"instance"
msgstr "このインスタンスにターゲット設定されている実行中または待機状態のジョブの数"
-#: awx/api/serializers.py:4631
+#: awx/api/serializers.py:4673
msgid "Count of all jobs that target this instance"
msgstr "このインスタンスをターゲットに設定するすべてのジョブの数"
-#: awx/api/serializers.py:4664
+#: awx/api/serializers.py:4708
msgid ""
"Count of jobs in the running or waiting state that are targeted for this "
"instance group"
msgstr "このインスタンスグループにターゲット設定されている実行中または待機状態のジョブの数"
-#: awx/api/serializers.py:4669
+#: awx/api/serializers.py:4713
msgid "Count of all jobs that target this instance group"
msgstr "このインスタンスグループをターゲットに設定するすべてのジョブの数"
-#: awx/api/serializers.py:4674
+#: awx/api/serializers.py:4718
msgid "Indicates whether instance group controls any other group"
msgstr "インスタンスグループが他のグループを制御するかどうかを指定します。"
-#: awx/api/serializers.py:4678
+#: awx/api/serializers.py:4722
msgid ""
"Indicates whether instances in this group are isolated.Isolated groups have "
"a designated controller group."
msgstr "このグループ内でインスタンスを分離させるかを指定します。分離されたグループには指定したコントローラーグループがあります。"
-#: awx/api/serializers.py:4683
+#: awx/api/serializers.py:4727
msgid ""
"Indicates whether instances in this group are containerized.Containerized "
"groups have a designated Openshift or Kubernetes cluster."
msgstr "このグループ内でインスタンスをコンテナー化するかを指定します。コンテナー化したグループには、指定の OpenShift または Kubernetes クラスターが含まれます。"
-#: awx/api/serializers.py:4691
+#: awx/api/serializers.py:4735
msgid "Policy Instance Percentage"
msgstr "ポリシーインスタンスの割合"
-#: awx/api/serializers.py:4692
+#: awx/api/serializers.py:4736
msgid ""
"Minimum percentage of all instances that will be automatically assigned to "
"this group when new instances come online."
msgstr "新規インスタンスがオンラインになると、このグループに自動的に最小限割り当てられるインスタンスの割合を選択します。"
-#: awx/api/serializers.py:4697
+#: awx/api/serializers.py:4741
msgid "Policy Instance Minimum"
msgstr "ポリシーインスタンスの最小値"
-#: awx/api/serializers.py:4698
+#: awx/api/serializers.py:4742
msgid ""
"Static minimum number of Instances that will be automatically assign to this "
"group when new instances come online."
msgstr "新規インスタンスがオンラインになると、このグループに自動的に最小限割り当てられるインスタンス数を入力します。"
-#: awx/api/serializers.py:4703
+#: awx/api/serializers.py:4747
msgid "Policy Instance List"
msgstr "ポリシーインスタンスの一覧"
-#: awx/api/serializers.py:4704
+#: awx/api/serializers.py:4748
msgid "List of exact-match Instances that will be assigned to this group"
msgstr "このグループに割り当てられる完全一致のインスタンスの一覧"
-#: awx/api/serializers.py:4730
+#: awx/api/serializers.py:4774
msgid "Duplicate entry {}."
msgstr "重複するエントリー {}。"
-#: awx/api/serializers.py:4732
+#: awx/api/serializers.py:4776
msgid "{} is not a valid hostname of an existing instance."
msgstr "{} は既存インスタンスの有効なホスト名ではありません。"
-#: awx/api/serializers.py:4734 awx/api/views/mixin.py:98
+#: awx/api/serializers.py:4778 awx/api/views/mixin.py:98
msgid ""
"Isolated instances may not be added or removed from instances groups via the "
"API."
msgstr "分離されたインスタンスは、API 経由でインスタンスグループから追加したり、削除したりすることができません。"
-#: awx/api/serializers.py:4736 awx/api/views/mixin.py:102
+#: awx/api/serializers.py:4780 awx/api/views/mixin.py:102
msgid "Isolated instance group membership may not be managed via the API."
msgstr "分離されたインスタンスグループのメンバーシップは API で管理できません。"
-#: awx/api/serializers.py:4738 awx/api/serializers.py:4743
-#: awx/api/serializers.py:4748
+#: awx/api/serializers.py:4782 awx/api/serializers.py:4787
+#: awx/api/serializers.py:4792
msgid "Containerized instances may not be managed via the API"
msgstr "コンテナー化されたインスタンスは API で管理されないことがあります"
-#: awx/api/serializers.py:4753
+#: awx/api/serializers.py:4797
msgid "tower instance group name may not be changed."
msgstr "Tower のインスタンスグループ名は変更できません。"
-#: awx/api/serializers.py:4758
+#: awx/api/serializers.py:4802
msgid "Only Kubernetes credentials can be associated with an Instance Group"
msgstr "インスタンスグループに関連付けることができる Kubernetes 認証情報のみです"
-#: awx/api/serializers.py:4797
+#: awx/api/serializers.py:4841
msgid ""
"When present, shows the field name of the role or relationship that changed."
msgstr "これがある場合には、変更された関係またはロールのフィールド名を表示します。"
-#: awx/api/serializers.py:4799
+#: awx/api/serializers.py:4843
msgid ""
"When present, shows the model on which the role or relationship was defined."
msgstr "これがある場合には、ロールまたは関係が定義されているモデルを表示します。"
-#: awx/api/serializers.py:4832
+#: awx/api/serializers.py:4876
msgid ""
"A summary of the new and changed values when an object is created, updated, "
"or deleted"
msgstr "オブジェクトの作成、更新または削除時の新規値および変更された値の概要"
-#: awx/api/serializers.py:4834
+#: awx/api/serializers.py:4878
msgid ""
"For create, update, and delete events this is the object type that was "
"affected. For associate and disassociate events this is the object type "
"associated or disassociated with object2."
msgstr "作成、更新、および削除イベントの場合、これは影響を受けたオブジェクトタイプになります。関連付けおよび関連付け解除イベントの場合、これは object2 に関連付けられたか、またはその関連付けが解除されたオブジェクトタイプになります。"
-#: awx/api/serializers.py:4837
+#: awx/api/serializers.py:4881
msgid ""
"Unpopulated for create, update, and delete events. For associate and "
"disassociate events this is the object type that object1 is being associated "
"with."
msgstr "作成、更新、および削除イベントの場合は設定されません。関連付けおよび関連付け解除イベントの場合、これは object1 が関連付けられるオブジェクトタイプになります。"
-#: awx/api/serializers.py:4840
+#: awx/api/serializers.py:4884
msgid "The action taken with respect to the given object(s)."
msgstr "指定されたオブジェクトについて実行されたアクション。"
-#: awx/api/views/__init__.py:181
+#: awx/api/views/__init__.py:185
+msgid "Not found."
+msgstr "見つかりません"
+
+#: awx/api/views/__init__.py:193
msgid "Dashboard"
msgstr "ダッシュボード"
-#: awx/api/views/__init__.py:271
+#: awx/api/views/__init__.py:290
msgid "Dashboard Jobs Graphs"
msgstr "ダッシュボードのジョブグラフ"
-#: awx/api/views/__init__.py:307
+#: awx/api/views/__init__.py:326
#, python-format
msgid "Unknown period \"%s\""
msgstr "不明な期間 \"%s\""
-#: awx/api/views/__init__.py:321
+#: awx/api/views/__init__.py:340
msgid "Instances"
msgstr "インスタンス"
-#: awx/api/views/__init__.py:329
+#: awx/api/views/__init__.py:348
msgid "Instance Detail"
msgstr "インスタンスの詳細"
-#: awx/api/views/__init__.py:346
+#: awx/api/views/__init__.py:365
msgid "Instance Jobs"
msgstr "インスタンスジョブ"
-#: awx/api/views/__init__.py:360
+#: awx/api/views/__init__.py:379
msgid "Instance's Instance Groups"
msgstr "インスタンスのインスタンスグループ"
-#: awx/api/views/__init__.py:369
+#: awx/api/views/__init__.py:388
msgid "Instance Groups"
msgstr "インスタンスグループ"
-#: awx/api/views/__init__.py:377
+#: awx/api/views/__init__.py:396
msgid "Instance Group Detail"
msgstr "インスタンスグループの詳細"
-#: awx/api/views/__init__.py:392
+#: awx/api/views/__init__.py:411
msgid "Isolated Groups can not be removed from the API"
msgstr "分離されたグループは API から削除できません"
-#: awx/api/views/__init__.py:394
+#: awx/api/views/__init__.py:413
msgid ""
"Instance Groups acting as a controller for an Isolated Group can not be "
"removed from the API"
msgstr "分離されたグループのコントローラーとして動作するインスタンスグループは API から削除できません"
-#: awx/api/views/__init__.py:400
+#: awx/api/views/__init__.py:419
msgid "Instance Group Running Jobs"
msgstr "ジョブを実行しているインスタンスグループ"
-#: awx/api/views/__init__.py:409
+#: awx/api/views/__init__.py:428
msgid "Instance Group's Instances"
msgstr "インスタンスグループのインスタンス"
-#: awx/api/views/__init__.py:419
+#: awx/api/views/__init__.py:438
msgid "Schedules"
msgstr "スケジュール"
-#: awx/api/views/__init__.py:433
+#: awx/api/views/__init__.py:452
msgid "Schedule Recurrence Rule Preview"
msgstr "繰り返しルールプレビューのスケジュール"
-#: awx/api/views/__init__.py:480
+#: awx/api/views/__init__.py:499
msgid "Cannot assign credential when related template is null."
msgstr "関連するテンプレートが null の場合は認証情報を割り当てることができません。"
-#: awx/api/views/__init__.py:485
+#: awx/api/views/__init__.py:504
msgid "Related template cannot accept {} on launch."
msgstr "関連するテンプレートは起動時に {} を受け入れません。"
-#: awx/api/views/__init__.py:487
+#: awx/api/views/__init__.py:506
msgid ""
"Credential that requires user input on launch cannot be used in saved launch "
"configuration."
msgstr "起動時にユーザー入力を必要とする認証情報は保存された起動設定で使用できません。"
-#: awx/api/views/__init__.py:493
+#: awx/api/views/__init__.py:512
msgid "Related template is not configured to accept credentials on launch."
msgstr "関連するテンプレートは起動時に認証情報を受け入れるよう設定されていません。"
-#: awx/api/views/__init__.py:495
+#: awx/api/views/__init__.py:514
#, python-brace-format
msgid ""
"This launch configuration already provides a {credential_type} credential."
msgstr "この起動設定は {credential_type} 認証情報をすでに指定しています。"
-#: awx/api/views/__init__.py:498
+#: awx/api/views/__init__.py:517
#, python-brace-format
msgid "Related template already uses {credential_type} credential."
msgstr "関連するテンプレートは {credential_type} 認証情報をすでに使用しています。"
-#: awx/api/views/__init__.py:516
+#: awx/api/views/__init__.py:535
msgid "Schedule Jobs List"
msgstr "スケジュールジョブの一覧"
-#: awx/api/views/__init__.py:600 awx/api/views/__init__.py:4452
+#: awx/api/views/__init__.py:619 awx/api/views/__init__.py:4420
msgid ""
"You cannot assign an Organization participation role as a child role for a "
"Team."
msgstr "組織の参加ロールをチームの子ロールとして割り当てることができません。"
-#: awx/api/views/__init__.py:604 awx/api/views/__init__.py:4466
+#: awx/api/views/__init__.py:623 awx/api/views/__init__.py:4434
msgid "You cannot grant system-level permissions to a team."
msgstr "システムレベルのパーミッションをチームに付与できません。"
-#: awx/api/views/__init__.py:611 awx/api/views/__init__.py:4458
+#: awx/api/views/__init__.py:630 awx/api/views/__init__.py:4426
msgid ""
"You cannot grant credential access to a team when the Organization field "
"isn't set, or belongs to a different organization"
msgstr "組織フィールドが設定されていないか、または別の組織に属する場合に認証情報のアクセス権をチームに付与できません"
-#: awx/api/views/__init__.py:713
+#: awx/api/views/__init__.py:732
msgid "Project Schedules"
msgstr "プロジェクトのスケジュール"
-#: awx/api/views/__init__.py:724
+#: awx/api/views/__init__.py:743
msgid "Project SCM Inventory Sources"
msgstr "プロジェクト SCM のインベントリーソース"
-#: awx/api/views/__init__.py:825
+#: awx/api/views/__init__.py:844
msgid "Project Update Events List"
msgstr "プロジェクト更新イベント一覧"
-#: awx/api/views/__init__.py:839
+#: awx/api/views/__init__.py:858
msgid "System Job Events List"
msgstr "システムジョブイベント一覧"
-#: awx/api/views/__init__.py:873
+#: awx/api/views/__init__.py:892
msgid "Project Update SCM Inventory Updates"
msgstr "プロジェクト更新 SCM のインベントリー更新"
-#: awx/api/views/__init__.py:918
+#: awx/api/views/__init__.py:937
msgid "Me"
msgstr "自分"
-#: awx/api/views/__init__.py:927
+#: awx/api/views/__init__.py:946
msgid "OAuth 2 Applications"
msgstr "OAuth 2 アプリケーション"
-#: awx/api/views/__init__.py:936
+#: awx/api/views/__init__.py:955
msgid "OAuth 2 Application Detail"
msgstr "OAuth 2 アプリケーションの詳細"
-#: awx/api/views/__init__.py:949
+#: awx/api/views/__init__.py:968
msgid "OAuth 2 Application Tokens"
msgstr "OAuth 2 アプリケーショントークン"
-#: awx/api/views/__init__.py:971
+#: awx/api/views/__init__.py:990
msgid "OAuth2 Tokens"
msgstr "OAuth2 トークン"
-#: awx/api/views/__init__.py:980
+#: awx/api/views/__init__.py:999
msgid "OAuth2 User Tokens"
msgstr "OAuth2 ユーザートークン"
-#: awx/api/views/__init__.py:992
+#: awx/api/views/__init__.py:1011
msgid "OAuth2 User Authorized Access Tokens"
msgstr "OAuth2 ユーザー認可アクセストークン"
-#: awx/api/views/__init__.py:1007
+#: awx/api/views/__init__.py:1026
msgid "Organization OAuth2 Applications"
msgstr "組織 OAuth2 アプリケーション"
-#: awx/api/views/__init__.py:1019
+#: awx/api/views/__init__.py:1038
msgid "OAuth2 Personal Access Tokens"
msgstr "OAuth2 パーソナルアクセストークン"
-#: awx/api/views/__init__.py:1034
+#: awx/api/views/__init__.py:1053
msgid "OAuth Token Detail"
msgstr "OAuth トークンの詳細"
-#: awx/api/views/__init__.py:1096 awx/api/views/__init__.py:4419
+#: awx/api/views/__init__.py:1115 awx/api/views/__init__.py:4387
msgid ""
"You cannot grant credential access to a user not in the credentials' "
"organization"
msgstr "認証情報の組織に属さないユーザーに認証情報のアクセス権を付与することはできません"
-#: awx/api/views/__init__.py:1100 awx/api/views/__init__.py:4423
+#: awx/api/views/__init__.py:1119 awx/api/views/__init__.py:4391
msgid "You cannot grant private credential access to another user"
msgstr "非公開の認証情報のアクセス権を別のユーザーに付与することはできません"
-#: awx/api/views/__init__.py:1198
+#: awx/api/views/__init__.py:1217
#, python-format
msgid "Cannot change %s."
msgstr "%s を変更できません。"
-#: awx/api/views/__init__.py:1204
+#: awx/api/views/__init__.py:1223
msgid "Cannot delete user."
msgstr "ユーザーを削除できません。"
-#: awx/api/views/__init__.py:1228
+#: awx/api/views/__init__.py:1247
msgid "Deletion not allowed for managed credential types"
msgstr "管理されている認証情報タイプで削除は許可されません"
-#: awx/api/views/__init__.py:1230
+#: awx/api/views/__init__.py:1249
msgid "Credential types that are in use cannot be deleted"
msgstr "使用中の認証情報タイプを削除できません"
-#: awx/api/views/__init__.py:1381
+#: awx/api/views/__init__.py:1362
+msgid "Deletion not allowed for managed credentials"
+msgstr "管理されている認証情報では削除が許可されません"
+
+#: awx/api/views/__init__.py:1407
msgid "External Credential Test"
msgstr "外部認証情報のテスト"
-#: awx/api/views/__init__.py:1408
+#: awx/api/views/__init__.py:1442
msgid "Credential Input Source Detail"
msgstr "認証情報の入力ソース詳細"
-#: awx/api/views/__init__.py:1416 awx/api/views/__init__.py:1424
+#: awx/api/views/__init__.py:1450 awx/api/views/__init__.py:1458
msgid "Credential Input Sources"
msgstr "認証情報の入力ソース"
-#: awx/api/views/__init__.py:1439
+#: awx/api/views/__init__.py:1473
msgid "External Credential Type Test"
msgstr "外部認証情報の種類テスト"
-#: awx/api/views/__init__.py:1497
+#: awx/api/views/__init__.py:1539
msgid "The inventory for this host is already being deleted."
msgstr "このホストのインベントリーはすでに削除されています。"
-#: awx/api/views/__init__.py:1614
+#: awx/api/views/__init__.py:1656
msgid "SSLError while trying to connect to {}"
msgstr "{} への接続試行中に SSL エラーが発生しました"
-#: awx/api/views/__init__.py:1616
+#: awx/api/views/__init__.py:1658
msgid "Request to {} timed out."
msgstr "{} の要求がタイムアウトになりました。"
-#: awx/api/views/__init__.py:1618
+#: awx/api/views/__init__.py:1660
msgid "Unknown exception {} while trying to GET {}"
msgstr "GET {} の試行中に不明の例外 {} が発生しました"
-#: awx/api/views/__init__.py:1622
+#: awx/api/views/__init__.py:1664
msgid ""
"Unauthorized access. Please check your Insights Credential username and "
"password."
msgstr "不正アクセスです。Insights 認証情報のユーザー名およびパスワードを確認してください。"
-#: awx/api/views/__init__.py:1626
+#: awx/api/views/__init__.py:1668
msgid ""
"Failed to access the Insights API at URL {}. Server responded with {} status "
"code and message {}"
msgstr "URL {} で Insights API にアクセスできませんでした。サーバーが {} ステータスコードおよびメッセージ {} を出して応答しました。"
-#: awx/api/views/__init__.py:1635
+#: awx/api/views/__init__.py:1677
msgid "Expected JSON response from Insights at URL {} but instead got {}"
msgstr "Insights からの JSON 応答を想定していましたが、URL {} の代わりに {} を取得しました。"
-#: awx/api/views/__init__.py:1653
+#: awx/api/views/__init__.py:1695
msgid "Could not translate Insights system ID {} into an Insights platform ID."
msgstr "Insights システム ID {} から Insights プラットフォーム ID に変換できませんでした。"
-#: awx/api/views/__init__.py:1695
+#: awx/api/views/__init__.py:1737
msgid "This host is not recognized as an Insights host."
msgstr "このホストは Insights ホストとして認識されていません。"
-#: awx/api/views/__init__.py:1703
+#: awx/api/views/__init__.py:1745
msgid "The Insights Credential for \"{}\" was not found."
msgstr "\"{}\" の Insights 認証情報が見つかりませんでした。"
-#: awx/api/views/__init__.py:1782
+#: awx/api/views/__init__.py:1824
msgid "Cyclical Group association."
msgstr "循環的なグループの関連付け"
-#: awx/api/views/__init__.py:1948
+#: awx/api/views/__init__.py:1990
msgid "Inventory subset argument must be a string."
msgstr "インベントリーサブセットの引数は文字列でなければなりません。"
-#: awx/api/views/__init__.py:1952
+#: awx/api/views/__init__.py:1994
msgid "Subset does not use any supported syntax."
msgstr "サポートされている構文がサブセットで使用されていません。"
-#: awx/api/views/__init__.py:2002
+#: awx/api/views/__init__.py:2044
msgid "Inventory Source List"
msgstr "インベントリーソース一覧"
-#: awx/api/views/__init__.py:2014
+#: awx/api/views/__init__.py:2056
msgid "Inventory Sources Update"
msgstr "インベントリーソースの更新"
-#: awx/api/views/__init__.py:2047
+#: awx/api/views/__init__.py:2089
msgid "Could not start because `can_update` returned False"
msgstr "`can_update` が False を返したので開始できませんでした"
-#: awx/api/views/__init__.py:2055
+#: awx/api/views/__init__.py:2097
msgid "No inventory sources to update."
msgstr "更新するインベントリーソースがありません。"
-#: awx/api/views/__init__.py:2077
+#: awx/api/views/__init__.py:2119
msgid "Inventory Source Schedules"
msgstr "インベントリーソースのスケジュール"
-#: awx/api/views/__init__.py:2104
+#: awx/api/views/__init__.py:2146
msgid "Notification Templates can only be assigned when source is one of {}."
msgstr "ソースが {} のいずれかである場合、通知テンプレートのみを割り当てることができます。"
-#: awx/api/views/__init__.py:2202
+#: awx/api/views/__init__.py:2244
msgid "Source already has credential assigned."
msgstr "ソースには認証情報がすでに割り当てられています。"
-#: awx/api/views/__init__.py:2350
-msgid "'credentials' cannot be used in combination with 'extra_credentials'."
-msgstr "'credentials' は、'extra_credentials' と組み合わせて使用することはできません。"
-
-#: awx/api/views/__init__.py:2368
-msgid "Incorrect type. Expected a list received {}."
-msgstr "タイプが正しくありません。リストが必要でしたが、{} が受信されました。"
-
-#: awx/api/views/__init__.py:2466
+#: awx/api/views/__init__.py:2460
msgid "Job Template Schedules"
msgstr "ジョブテンプレートスケジュール"
-#: awx/api/views/__init__.py:2515
+#: awx/api/views/__init__.py:2509
msgid "Field '{}' is missing from survey spec."
msgstr "Survey の指定にフィールド '{}' がありません。"
-#: awx/api/views/__init__.py:2517
+#: awx/api/views/__init__.py:2511
msgid "Expected {} for field '{}', received {} type."
msgstr "フィールド '{}' の予期される {}。{} タイプを受信しました。"
-#: awx/api/views/__init__.py:2521
+#: awx/api/views/__init__.py:2515
msgid "'spec' doesn't contain any items."
msgstr "「spec」には項目が含まれません。"
-#: awx/api/views/__init__.py:2535
+#: awx/api/views/__init__.py:2529
#, python-format
msgid "Survey question %s is not a json object."
msgstr "Survey の質問 %s は json オブジェクトではありません。"
-#: awx/api/views/__init__.py:2538
+#: awx/api/views/__init__.py:2532
#, python-brace-format
msgid "'{field_name}' missing from survey question {idx}"
msgstr "Survey の質問 {idx} に '{field_name}' がありません。"
-#: awx/api/views/__init__.py:2548
+#: awx/api/views/__init__.py:2542
#, python-brace-format
msgid "'{field_name}' in survey question {idx} expected to be {type_label}."
msgstr "Survey の質問 {idx} の '{field_name}' は {type_label} である必要があります。"
-#: awx/api/views/__init__.py:2552
+#: awx/api/views/__init__.py:2546
#, python-format
msgid "'variable' '%(item)s' duplicated in survey question %(survey)s."
msgstr "Survey の質問 %(survey)s で '変数' '%(item)s' が重複しています。"
-#: awx/api/views/__init__.py:2562
+#: awx/api/views/__init__.py:2556
#, python-brace-format
msgid ""
"'{survey_item[type]}' in survey question {idx} is not one of "
"'{allowed_types}' allowed question types."
msgstr "Survey の質問 {idx} の '{survey_item[type]}' は、'{allowed_types}' で許可されている質問タイプではありません。"
-#: awx/api/views/__init__.py:2572
+#: awx/api/views/__init__.py:2566
#, python-brace-format
msgid ""
"Default value {survey_item[default]} in survey question {idx} expected to be "
"{type_label}."
msgstr "Survey の質問 {idx} のデフォルト値 {survey_item[default]} は、{type_label} である必要があります。"
-#: awx/api/views/__init__.py:2582
+#: awx/api/views/__init__.py:2576
#, python-brace-format
msgid "The {min_or_max} limit in survey question {idx} expected to be integer."
msgstr "Survey の質問 {idx} の {min_or_max} の制限は整数である必要があります。"
-#: awx/api/views/__init__.py:2592
+#: awx/api/views/__init__.py:2586
#, python-brace-format
msgid "Survey question {idx} of type {survey_item[type]} must specify choices."
msgstr "タイプ {survey_item[type]} の Survey の質問 {idx} には選択肢を指定する必要があります。"
-#: awx/api/views/__init__.py:2606
+#: awx/api/views/__init__.py:2600
msgid "Multiple Choice (Single Select) can only have one default value."
msgstr "選択肢方式 (単一の選択) では、デフォルト値を 1 つだけ使用できます。"
-#: awx/api/views/__init__.py:2610
+#: awx/api/views/__init__.py:2604
msgid "Default choice must be answered from the choices listed."
msgstr "デフォルトで指定されている選択項目は、一覧から回答する必要があります。"
-#: awx/api/views/__init__.py:2619
+#: awx/api/views/__init__.py:2613
#, python-brace-format
msgid ""
"$encrypted$ is a reserved keyword for password question defaults, survey "
"question {idx} is type {survey_item[type]}."
msgstr "$encrypted$ は、デフォルト設定されているパスワードの質問に予約されたキーワードで、Survey の質問 {idx} は {survey_item[type]} タイプです。"
-#: awx/api/views/__init__.py:2633
+#: awx/api/views/__init__.py:2627
#, python-brace-format
msgid ""
"$encrypted$ is a reserved keyword, may not be used for new default in "
"position {idx}."
msgstr "$encrypted$ は予約されたキーワードで、位置 {idx} の新規デフォルトに使用できません。"
-#: awx/api/views/__init__.py:2705
+#: awx/api/views/__init__.py:2699
#, python-brace-format
msgid "Cannot assign multiple {credential_type} credentials."
msgstr "複数の {credential_type} 認証情報を割り当てることができません。"
-#: awx/api/views/__init__.py:2709
+#: awx/api/views/__init__.py:2703
msgid "Cannot assign a Credential of kind `{}`."
msgstr "`{}`の種類の認証情報を割り当てることができません。"
#: awx/api/views/__init__.py:2726
-msgid "Extra credentials must be network or cloud."
-msgstr "追加の認証情報はネットワークまたはクラウドにする必要があります。"
-
-#: awx/api/views/__init__.py:2748
msgid "Maximum number of labels for {} reached."
msgstr "{} のラベルの最大数に達しました。"
-#: awx/api/views/__init__.py:2871
+#: awx/api/views/__init__.py:2849
msgid "No matching host could be found!"
msgstr "一致するホストが見つかりませんでした!"
-#: awx/api/views/__init__.py:2874
+#: awx/api/views/__init__.py:2852
msgid "Multiple hosts matched the request!"
msgstr "複数のホストが要求に一致しました!"
-#: awx/api/views/__init__.py:2879
+#: awx/api/views/__init__.py:2857
msgid "Cannot start automatically, user input required!"
msgstr "自動的に開始できません。ユーザー入力が必要です!"
-#: awx/api/views/__init__.py:2887
+#: awx/api/views/__init__.py:2865
msgid "Host callback job already pending."
msgstr "ホストのコールバックジョブがすでに保留中です。"
-#: awx/api/views/__init__.py:2903 awx/api/views/__init__.py:3664
+#: awx/api/views/__init__.py:2881 awx/api/views/__init__.py:3632
msgid "Error starting job!"
msgstr "ジョブの開始時にエラーが発生しました!"
-#: awx/api/views/__init__.py:3027 awx/api/views/__init__.py:3047
+#: awx/api/views/__init__.py:3005 awx/api/views/__init__.py:3025
msgid "Cycle detected."
msgstr "サイクルが検出されました。"
-#: awx/api/views/__init__.py:3039
+#: awx/api/views/__init__.py:3017
msgid "Relationship not allowed."
msgstr "リレーションシップは許可されていません。"
-#: awx/api/views/__init__.py:3268
+#: awx/api/views/__init__.py:3246
msgid "Cannot relaunch slice workflow job orphaned from job template."
msgstr "ジョブテンプレートから孤立しているスライスされたワークフロージョブを再起動することはできません。"
-#: awx/api/views/__init__.py:3270
+#: awx/api/views/__init__.py:3248
msgid "Cannot relaunch sliced workflow job after slice count has changed."
msgstr "スライス数を変更した後は、スライスされたワークフロージョブを再起動することはできません。"
-#: awx/api/views/__init__.py:3303
+#: awx/api/views/__init__.py:3281
msgid "Workflow Job Template Schedules"
msgstr "ワークフロージョブテンプレートのスケジュール"
-#: awx/api/views/__init__.py:3446 awx/api/views/__init__.py:4087
+#: awx/api/views/__init__.py:3424 awx/api/views/__init__.py:4055
msgid "Superuser privileges needed."
msgstr "スーパーユーザー権限が必要です。"
-#: awx/api/views/__init__.py:3479
+#: awx/api/views/__init__.py:3457
msgid "System Job Template Schedules"
msgstr "システムジョブテンプレートのスケジュール"
-#: awx/api/views/__init__.py:3647
+#: awx/api/views/__init__.py:3615
#, python-brace-format
msgid "Wait until job finishes before retrying on {status_value} hosts."
msgstr "ジョブの終了を待機してから {status_value} ホストで再試行します。"
-#: awx/api/views/__init__.py:3652
+#: awx/api/views/__init__.py:3620
#, python-brace-format
msgid "Cannot retry on {status_value} hosts, playbook stats not available."
msgstr "Playbook 統計を利用できないため、{status_value} ホストで再試行できません。"
-#: awx/api/views/__init__.py:3657
+#: awx/api/views/__init__.py:3625
#, python-brace-format
msgid "Cannot relaunch because previous job had 0 {status_value} hosts."
msgstr "直前のジョブにあるのが 0 {status_value} ホストがあるため、再起動できません。"
-#: awx/api/views/__init__.py:3686
+#: awx/api/views/__init__.py:3654
msgid "Cannot create schedule because job requires credential passwords."
msgstr "ジョブには認証情報パスワードが必要なため、スケジュールを削除できません。"
-#: awx/api/views/__init__.py:3691
+#: awx/api/views/__init__.py:3659
msgid "Cannot create schedule because job was launched by legacy method."
msgstr "ジョブがレガシー方式で起動したため、スケジュールを作成できません。"
-#: awx/api/views/__init__.py:3693
+#: awx/api/views/__init__.py:3661
msgid "Cannot create schedule because a related resource is missing."
msgstr "関連するリソースがないため、スケジュールを作成できません。"
-#: awx/api/views/__init__.py:3748
+#: awx/api/views/__init__.py:3716
msgid "Job Host Summaries List"
msgstr "ジョブホスト概要一覧"
-#: awx/api/views/__init__.py:3802
+#: awx/api/views/__init__.py:3770
msgid "Job Event Children List"
msgstr "ジョブイベント子一覧"
-#: awx/api/views/__init__.py:3818
+#: awx/api/views/__init__.py:3786
msgid "Job Event Hosts List"
msgstr "ジョブイベントホスト一覧"
-#: awx/api/views/__init__.py:3833
+#: awx/api/views/__init__.py:3801
msgid "Job Events List"
msgstr "ジョブイベント一覧"
-#: awx/api/views/__init__.py:4044
+#: awx/api/views/__init__.py:4012
msgid "Ad Hoc Command Events List"
msgstr "アドホックコマンドイベント一覧"
-#: awx/api/views/__init__.py:4289
+#: awx/api/views/__init__.py:4257
msgid "Delete not allowed while there are pending notifications"
msgstr "保留中の通知がある場合に削除は許可されません"
-#: awx/api/views/__init__.py:4297
+#: awx/api/views/__init__.py:4265
msgid "Notification Template Test"
msgstr "通知テンプレートテスト"
-#: awx/api/views/__init__.py:4557 awx/api/views/__init__.py:4572
+#: awx/api/views/__init__.py:4525 awx/api/views/__init__.py:4540
msgid "User does not have permission to approve or deny this workflow."
msgstr "このワークフローを承認または拒否するパーミッションはありません。"
-#: awx/api/views/__init__.py:4559 awx/api/views/__init__.py:4574
+#: awx/api/views/__init__.py:4527 awx/api/views/__init__.py:4542
msgid "This workflow step has already been approved or denied."
msgstr "このワークフローの手順はすでに承認または拒否されています。"
@@ -1393,7 +1415,11 @@ msgstr "インベントリー更新イベント一覧"
msgid "Cannot delete inventory script."
msgstr "インベントリースクリプトを削除できません。"
-#: awx/api/views/inventory.py:149
+#: awx/api/views/inventory.py:137
+msgid "You cannot turn a regular inventory into a \"smart\" inventory."
+msgstr "通常の在庫を「スマート」在庫に変えることはできません。"
+
+#: awx/api/views/inventory.py:150
#, python-brace-format
msgid "{0}"
msgstr "{0}"
@@ -1418,71 +1444,76 @@ msgstr "ジョブはイベント処理を終了していません。"
msgid "Related job {} is still processing events."
msgstr "関連するジョブ {} は依然としてイベントを処理しています。"
-#: awx/api/views/root.py:49 awx/templates/rest_framework/api.html:28
+#: awx/api/views/organization.py:230
+#, python-brace-format
+msgid "Credential must be a Galaxy credential, not {sub.credential_type.name}."
+msgstr "認証情報は、{sub.credential_type.name} ではなく、Galaxy 認証情報にする必要があります。"
+
+#: awx/api/views/root.py:50 awx/templates/rest_framework/api.html:28
msgid "REST API"
msgstr "REST API"
-#: awx/api/views/root.py:59 awx/templates/rest_framework/api.html:4
+#: awx/api/views/root.py:60 awx/templates/rest_framework/api.html:4
msgid "AWX REST API"
msgstr "AWX REST API"
-#: awx/api/views/root.py:72
+#: awx/api/views/root.py:73
msgid "API OAuth 2 Authorization Root"
msgstr "API OAuth 2 認証ルート"
-#: awx/api/views/root.py:139
+#: awx/api/views/root.py:140
msgid "Version 2"
msgstr "バージョン 2"
-#: awx/api/views/root.py:148
+#: awx/api/views/root.py:149
msgid "Ping"
msgstr "Ping"
-#: awx/api/views/root.py:180 awx/api/views/root.py:225 awx/conf/apps.py:10
+#: awx/api/views/root.py:181 awx/api/views/root.py:226 awx/conf/apps.py:10
msgid "Configuration"
msgstr "Configuration (構成)"
-#: awx/api/views/root.py:202 awx/api/views/root.py:308
+#: awx/api/views/root.py:203 awx/api/views/root.py:310
msgid "Invalid License"
msgstr "無効なライセンス"
-#: awx/api/views/root.py:207
+#: awx/api/views/root.py:208
msgid "The provided credentials are invalid (HTTP 401)."
msgstr "指定した認証情報は無効 (HTTP 401) です。"
-#: awx/api/views/root.py:209
+#: awx/api/views/root.py:210
msgid "Unable to connect to proxy server."
msgstr "プロキシサーバーに接続できません。"
-#: awx/api/views/root.py:211
+#: awx/api/views/root.py:212
msgid "Could not connect to subscription service."
msgstr "サブスクリプションサービスに接続できませんでした。"
-#: awx/api/views/root.py:284
+#: awx/api/views/root.py:286
msgid "Invalid license data"
msgstr "無効なライセンスデータ"
-#: awx/api/views/root.py:286
+#: awx/api/views/root.py:288
msgid "Missing 'eula_accepted' property"
msgstr "'eula_accepted' プロパティーがありません"
-#: awx/api/views/root.py:290
+#: awx/api/views/root.py:292
msgid "'eula_accepted' value is invalid"
msgstr "'eula_accepted' 値は無効です。"
-#: awx/api/views/root.py:293
+#: awx/api/views/root.py:295
msgid "'eula_accepted' must be True"
msgstr "'eula_accepted' は True でなければなりません"
-#: awx/api/views/root.py:300
+#: awx/api/views/root.py:302
msgid "Invalid JSON"
msgstr "無効な JSON"
-#: awx/api/views/root.py:319
+#: awx/api/views/root.py:321
msgid "Invalid license"
msgstr "無効なライセンス"
-#: awx/api/views/root.py:327
+#: awx/api/views/root.py:329
msgid "Failed to remove license."
msgstr "ライセンスを削除できませんでした。"
@@ -1673,11 +1704,11 @@ msgstr "\"{input}\" は有効な文字列ではありません。"
msgid "Expected a list of tuples of max length 2 but got {input_type} instead."
msgstr "最大の長さが 2 のタプルの一覧が予想されましたが、代わりに {input_type} を取得しました。"
-#: awx/conf/registry.py:73 awx/conf/tests/unit/test_registry.py:155
+#: awx/conf/registry.py:73 awx/conf/tests/unit/test_registry.py:156
msgid "All"
msgstr "すべて"
-#: awx/conf/registry.py:74 awx/conf/tests/unit/test_registry.py:156
+#: awx/conf/registry.py:74 awx/conf/tests/unit/test_registry.py:157
msgid "Changed"
msgstr "変更済み"
@@ -1689,55 +1720,53 @@ msgstr "ユーザー設定"
msgid "This value has been set manually in a settings file."
msgstr "この値は設定ファイルに手動で設定されました。"
-#: awx/conf/tests/unit/test_registry.py:46
-#: awx/conf/tests/unit/test_registry.py:56
-#: awx/conf/tests/unit/test_registry.py:72
-#: awx/conf/tests/unit/test_registry.py:87
-#: awx/conf/tests/unit/test_registry.py:100
-#: awx/conf/tests/unit/test_registry.py:106
-#: awx/conf/tests/unit/test_registry.py:126
-#: awx/conf/tests/unit/test_registry.py:132
-#: awx/conf/tests/unit/test_registry.py:145
-#: awx/conf/tests/unit/test_registry.py:157
-#: awx/conf/tests/unit/test_registry.py:166
-#: awx/conf/tests/unit/test_registry.py:172
-#: awx/conf/tests/unit/test_registry.py:184
-#: awx/conf/tests/unit/test_registry.py:191
-#: awx/conf/tests/unit/test_registry.py:233
-#: awx/conf/tests/unit/test_registry.py:251
-#: awx/conf/tests/unit/test_settings.py:79
-#: awx/conf/tests/unit/test_settings.py:97
-#: awx/conf/tests/unit/test_settings.py:112
-#: awx/conf/tests/unit/test_settings.py:127
-#: awx/conf/tests/unit/test_settings.py:143
-#: awx/conf/tests/unit/test_settings.py:156
-#: awx/conf/tests/unit/test_settings.py:173
-#: awx/conf/tests/unit/test_settings.py:189
-#: awx/conf/tests/unit/test_settings.py:200
-#: awx/conf/tests/unit/test_settings.py:216
-#: awx/conf/tests/unit/test_settings.py:237
-#: awx/conf/tests/unit/test_settings.py:259
-#: awx/conf/tests/unit/test_settings.py:285
-#: awx/conf/tests/unit/test_settings.py:299
-#: awx/conf/tests/unit/test_settings.py:323
+#: awx/conf/tests/unit/test_registry.py:47
+#: awx/conf/tests/unit/test_registry.py:57
+#: awx/conf/tests/unit/test_registry.py:73
+#: awx/conf/tests/unit/test_registry.py:88
+#: awx/conf/tests/unit/test_registry.py:101
+#: awx/conf/tests/unit/test_registry.py:107
+#: awx/conf/tests/unit/test_registry.py:127
+#: awx/conf/tests/unit/test_registry.py:133
+#: awx/conf/tests/unit/test_registry.py:146
+#: awx/conf/tests/unit/test_registry.py:158
+#: awx/conf/tests/unit/test_registry.py:167
+#: awx/conf/tests/unit/test_registry.py:173
+#: awx/conf/tests/unit/test_registry.py:185
+#: awx/conf/tests/unit/test_registry.py:192
+#: awx/conf/tests/unit/test_registry.py:234
+#: awx/conf/tests/unit/test_registry.py:252
+#: awx/conf/tests/unit/test_settings.py:73
+#: awx/conf/tests/unit/test_settings.py:91
+#: awx/conf/tests/unit/test_settings.py:106
+#: awx/conf/tests/unit/test_settings.py:121
+#: awx/conf/tests/unit/test_settings.py:137
+#: awx/conf/tests/unit/test_settings.py:150
+#: awx/conf/tests/unit/test_settings.py:167
+#: awx/conf/tests/unit/test_settings.py:183
+#: awx/conf/tests/unit/test_settings.py:194
+#: awx/conf/tests/unit/test_settings.py:210
+#: awx/conf/tests/unit/test_settings.py:231
+#: awx/conf/tests/unit/test_settings.py:254
+#: awx/conf/tests/unit/test_settings.py:268
+#: awx/conf/tests/unit/test_settings.py:292
+#: awx/conf/tests/unit/test_settings.py:312
+#: awx/conf/tests/unit/test_settings.py:329
#: awx/conf/tests/unit/test_settings.py:343
-#: awx/conf/tests/unit/test_settings.py:360
-#: awx/conf/tests/unit/test_settings.py:374
-#: awx/conf/tests/unit/test_settings.py:398
-#: awx/conf/tests/unit/test_settings.py:411
-#: awx/conf/tests/unit/test_settings.py:430
-#: awx/conf/tests/unit/test_settings.py:466 awx/main/conf.py:24
-#: awx/main/conf.py:33 awx/main/conf.py:43 awx/main/conf.py:53
-#: awx/main/conf.py:65 awx/main/conf.py:78 awx/main/conf.py:91
-#: awx/main/conf.py:116 awx/main/conf.py:129 awx/main/conf.py:142
-#: awx/main/conf.py:154 awx/main/conf.py:162 awx/main/conf.py:173
-#: awx/main/conf.py:405 awx/main/conf.py:830 awx/main/conf.py:840
-#: awx/main/conf.py:852
+#: awx/conf/tests/unit/test_settings.py:367
+#: awx/conf/tests/unit/test_settings.py:380
+#: awx/conf/tests/unit/test_settings.py:399
+#: awx/conf/tests/unit/test_settings.py:435 awx/main/conf.py:23
+#: awx/main/conf.py:32 awx/main/conf.py:42 awx/main/conf.py:52
+#: awx/main/conf.py:64 awx/main/conf.py:77 awx/main/conf.py:90
+#: awx/main/conf.py:115 awx/main/conf.py:128 awx/main/conf.py:141
+#: awx/main/conf.py:153 awx/main/conf.py:161 awx/main/conf.py:172
+#: awx/main/conf.py:392 awx/main/conf.py:742 awx/main/conf.py:754
msgid "System"
msgstr "システム"
-#: awx/conf/tests/unit/test_registry.py:151
-#: awx/conf/tests/unit/test_registry.py:158
+#: awx/conf/tests/unit/test_registry.py:152
+#: awx/conf/tests/unit/test_registry.py:159
msgid "OtherSystem"
msgstr "他のシステム"
@@ -1804,112 +1833,172 @@ msgstr "異なるインベントリーの 2 つの項目を関連付けること
msgid "Unable to change inventory on a group."
msgstr "グループのインベントリーを変更できません。"
-#: awx/main/access.py:1264
+#: awx/main/access.py:1261
msgid "Unable to change organization on a team."
msgstr "チームの組織を変更できません。"
-#: awx/main/access.py:1280
+#: awx/main/access.py:1277
msgid "The {} role cannot be assigned to a team"
msgstr "{} ロールをチームに割り当てることができません"
-#: awx/main/access.py:1474
+#: awx/main/access.py:1471
msgid "Insufficient access to Job Template credentials."
msgstr "ジョブテンプレート認証情報へのアクセス権がありません。"
-#: awx/main/access.py:1639 awx/main/access.py:2063
+#: awx/main/access.py:1635 awx/main/access.py:2059
msgid "Job was launched with secret prompts provided by another user."
msgstr "別のユーザーのシークレットプロンプトで、ジョブが起動しました。"
-#: awx/main/access.py:1648
+#: awx/main/access.py:1644
msgid "Job has been orphaned from its job template and organization."
msgstr "ジョブはジョブテンプレートおよび組織から孤立しています。"
-#: awx/main/access.py:1650
+#: awx/main/access.py:1646
msgid "Job was launched with prompted fields you do not have access to."
msgstr "アクセス権のないプロンプトフィールドでジョブが起動されました。"
-#: awx/main/access.py:1652
+#: awx/main/access.py:1648
msgid ""
"Job was launched with unknown prompted fields. Organization admin "
"permissions required."
msgstr "不明なプロンプトフィールドでジョブが起動されました。組織の管理者権限が必要です。"
-#: awx/main/access.py:2053
+#: awx/main/access.py:2049
msgid "Workflow Job was launched with unknown prompts."
msgstr "ワークフロージョブは不明なプロンプトで起動されています。"
-#: awx/main/access.py:2065
+#: awx/main/access.py:2061
msgid "Job was launched with prompts you lack access to."
msgstr "ジョブはアクセスできないプロンプトで起動されています。"
-#: awx/main/access.py:2067
+#: awx/main/access.py:2063
msgid "Job was launched with prompts no longer accepted."
msgstr "ジョブは受け入れられなくなったプロンプトで起動されています。"
-#: awx/main/access.py:2079
+#: awx/main/access.py:2075
msgid ""
"You do not have permission to the workflow job resources required for "
"relaunch."
msgstr "再起動に必要なワークフロージョブリソースへのパーミッションがありません。"
+#: awx/main/analytics/collectors.py:36
+msgid "General platform configuration."
+msgstr "一般的なプラットフォーム構成。"
+
+#: awx/main/analytics/collectors.py:68
+msgid "Counts of objects such as organizations, inventories, and projects"
+msgstr "組織、在庫、プロジェクトなどのオブジェクトの数"
+
+#: awx/main/analytics/collectors.py:103
+msgid "Counts of users and teams by organization"
+msgstr "組織別のユーザーとチームの数"
+
+#: awx/main/analytics/collectors.py:115
+msgid "Counts of credentials by credential type"
+msgstr "認証情報タイプ別の認証情報の数"
+
+#: awx/main/analytics/collectors.py:127
+msgid "Inventories, their inventory sources, and host counts"
+msgstr "インベントリー、そのインベントリソース、およびホスト数"
+
+#: awx/main/analytics/collectors.py:152
+msgid "Counts of projects by source control type"
+msgstr "ソース管理タイプ別のプロジェクト数"
+
+#: awx/main/analytics/collectors.py:171
+msgid "Cluster topology and capacity"
+msgstr "クラスターのトポロジーと容量"
+
+#: awx/main/analytics/collectors.py:197
+msgid "Counts of jobs by status"
+msgstr "ステータス別のジョブ数"
+
+#: awx/main/analytics/collectors.py:207
+msgid "Counts of jobs by execution node"
+msgstr "実行ノードごとのジョブ数"
+
+#: awx/main/analytics/collectors.py:222
+msgid "Metadata about the analytics collected"
+msgstr "収集された分析に関するメタデータ"
+
+#: awx/main/analytics/collectors.py:285
+msgid "Automation task records"
+msgstr "自動化タスクレコード"
+
+#: awx/main/analytics/collectors.py:314
+msgid "Data on jobs run"
+msgstr "実行されたジョブに関するデータ"
+
+#: awx/main/analytics/collectors.py:351
+msgid "Data on job templates"
+msgstr "ジョブテンプレートに関するデータ"
+
+#: awx/main/analytics/collectors.py:374
+msgid "Data on workflow runs"
+msgstr "ワークフロー実行に関するデータ"
+
+#: awx/main/analytics/collectors.py:410
+msgid "Data on workflows"
+msgstr "ワークフローに関するデータ"
+
#: awx/main/apps.py:8
msgid "Main"
msgstr "メイン"
-#: awx/main/conf.py:22
+#: awx/main/conf.py:21
msgid "Enable Activity Stream"
msgstr "アクティビティーストリームの有効化"
-#: awx/main/conf.py:23
+#: awx/main/conf.py:22
msgid "Enable capturing activity for the activity stream."
msgstr "アクティビティーストリームのアクティビティーのキャプチャーを有効にします。"
-#: awx/main/conf.py:31
+#: awx/main/conf.py:30
msgid "Enable Activity Stream for Inventory Sync"
msgstr "インベントリー同期のアクティビティティーストリームの有効化"
-#: awx/main/conf.py:32
+#: awx/main/conf.py:31
msgid ""
"Enable capturing activity for the activity stream when running inventory "
"sync."
msgstr "インベントリー同期の実行時にアクティビティーストリームのアクティビティーのキャプチャーを有効にします。"
-#: awx/main/conf.py:40
+#: awx/main/conf.py:39
msgid "All Users Visible to Organization Admins"
msgstr "組織管理者に表示されるすべてのユーザー"
-#: awx/main/conf.py:41
+#: awx/main/conf.py:40
msgid ""
"Controls whether any Organization Admin can view all users and teams, even "
"those not associated with their Organization."
msgstr "組織管理者が、それぞれの組織に関連付けられていないすべてのユーザーおよびチームを閲覧できるかどうかを制御します。"
-#: awx/main/conf.py:50
+#: awx/main/conf.py:49
msgid "Organization Admins Can Manage Users and Teams"
msgstr "組織管理者はユーザーおよびチームを管理できる"
-#: awx/main/conf.py:51
+#: awx/main/conf.py:50
msgid ""
"Controls whether any Organization Admin has the privileges to create and "
"manage users and teams. You may want to disable this ability if you are "
"using an LDAP or SAML integration."
msgstr "組織管理者がユーザーおよびチームを作成し、管理する権限を持つようにするかどうかを制御します。LDAP または SAML 統合を使用している場合はこの機能を無効にする必要がある場合があります。"
-#: awx/main/conf.py:62
+#: awx/main/conf.py:61
msgid "Base URL of the Tower host"
msgstr "Tower ホストのベース URL"
-#: awx/main/conf.py:63
+#: awx/main/conf.py:62
msgid ""
"This setting is used by services like notifications to render a valid url to "
"the Tower host."
msgstr "この設定は、有効な URL を Tower ホストにレンダリングする通知などのサービスで使用されます。"
-#: awx/main/conf.py:72
+#: awx/main/conf.py:71
msgid "Remote Host Headers"
msgstr "リモートホストヘッダー"
-#: awx/main/conf.py:73
+#: awx/main/conf.py:72
msgid ""
"HTTP headers and meta keys to search to determine remote host name or IP. "
"Add additional items to this list, such as \"HTTP_X_FORWARDED_FOR\", if "
@@ -1917,114 +2006,112 @@ msgid ""
"Adminstrator guide for more details."
msgstr "リモートホスト名または IP を判別するために検索する HTTP ヘッダーおよびメタキーです。リバースプロキシーの後ろの場合は、\"HTTP_X_FORWARDED_FOR\" のように項目をこの一覧に追加します。詳細は、Administrator Guide の「Proxy Support」セクションを参照してください。"
-#: awx/main/conf.py:85
-msgid "Proxy IP Whitelist"
-msgstr "プロキシー IP ホワイトリスト"
+#: awx/main/conf.py:84
+msgid "Proxy IP Allowed List"
+msgstr "プロキシ IP 許可リスト"
-#: awx/main/conf.py:86
+#: awx/main/conf.py:85
msgid ""
"If Tower is behind a reverse proxy/load balancer, use this setting to "
-"whitelist the proxy IP addresses from which Tower should trust custom "
+"configure the proxy IP addresses from which Tower should trust custom "
"REMOTE_HOST_HEADERS header values. If this setting is an empty list (the "
"default), the headers specified by REMOTE_HOST_HEADERS will be trusted "
"unconditionally')"
-msgstr "Tower がリバースプロキシー/ロードバランサーの背後にある場合、この設定を使用し、Tower がカスタム REMOTE_HOST_HEADERS ヘッダーの値を信頼するのに使用するプロキシー IP アドレスをホワイトリスト化します。この設定が空のリスト (デフォルト) の場合、REMOTE_HOST_HEADERS で指定されるヘッダーは条件なしに信頼されます')"
+msgstr "Tower がリバースプロキシー/ロードバランサーの背後にある場合は、この設定を使用して、Tower がカスタム REMOTE_HOST_HEADERS ヘッダーの値を信頼するのに使用するプロキシー IP アドレスを設定します。この設定が空のリスト (デフォルト) の場合は、REMOTE_HOST_HEADERS で指定されるヘッダーは条件なしに信頼されます')"
-#: awx/main/conf.py:112
+#: awx/main/conf.py:111
msgid "License"
msgstr "ライセンス"
-#: awx/main/conf.py:113
+#: awx/main/conf.py:112
msgid ""
"The license controls which features and functionality are enabled. Use /api/"
"v2/config/ to update or change the license."
msgstr "ライセンスで、どの特徴および機能を有効にするかを管理します。/api/v2/config/ を使用してライセンスを更新または変更してください。"
-#: awx/main/conf.py:127
+#: awx/main/conf.py:126
msgid "Red Hat customer username"
msgstr "Red Hat のお客様ユーザー名"
-#: awx/main/conf.py:128
+#: awx/main/conf.py:127
msgid ""
"This username is used to retrieve license information and to send Automation "
"Analytics"
msgstr "このユーザー名を使用して、ライセンス情報の受信、自動化アナリティクスの送信を行います。"
-#: awx/main/conf.py:140
+#: awx/main/conf.py:139
msgid "Red Hat customer password"
msgstr "Red Hat のお客様パスワード"
-#: awx/main/conf.py:141
+#: awx/main/conf.py:140
msgid ""
"This password is used to retrieve license information and to send Automation "
"Analytics"
msgstr "このパスワードを使用して、ライセンス情報の受信、自動化アナリティクスの送信を行います。"
-#: awx/main/conf.py:152
+#: awx/main/conf.py:151
msgid "Automation Analytics upload URL."
msgstr "自動化アナリティクスのアップロード用 URL"
-#: awx/main/conf.py:153
+#: awx/main/conf.py:152
msgid ""
"This setting is used to to configure data collection for the Automation "
"Analytics dashboard"
msgstr "この設定は、自動化アナリティクスダッシュボードのデータ収集を設定するのに使用します。"
-#: awx/main/conf.py:161
+#: awx/main/conf.py:160
msgid "Unique identifier for an AWX/Tower installation"
msgstr "AWX/Tower インストールの一意識別子"
-#: awx/main/conf.py:170
+#: awx/main/conf.py:169
msgid "Custom virtual environment paths"
msgstr "カスタムの仮想環境パス"
-#: awx/main/conf.py:171
+#: awx/main/conf.py:170
msgid ""
"Paths where Tower will look for custom virtual environments (in addition to /"
"var/lib/awx/venv/). Enter one path per line."
msgstr "Tower が (/var/lib/awx/venv/ 以外に) カスタムの仮想環境を検索するパス。1 行にパスを 1 つ入力してください。"
-#: awx/main/conf.py:181
+#: awx/main/conf.py:180
msgid "Ansible Modules Allowed for Ad Hoc Jobs"
msgstr "アドホックジョブで許可される Ansible モジュール"
-#: awx/main/conf.py:182
+#: awx/main/conf.py:181
msgid "List of modules allowed to be used by ad-hoc jobs."
msgstr "アドホックジョブで使用できるモジュール一覧。"
-#: awx/main/conf.py:183 awx/main/conf.py:205 awx/main/conf.py:214
-#: awx/main/conf.py:225 awx/main/conf.py:235 awx/main/conf.py:245
-#: awx/main/conf.py:256 awx/main/conf.py:267 awx/main/conf.py:278
-#: awx/main/conf.py:290 awx/main/conf.py:299 awx/main/conf.py:312
-#: awx/main/conf.py:325 awx/main/conf.py:337 awx/main/conf.py:348
-#: awx/main/conf.py:359 awx/main/conf.py:371 awx/main/conf.py:383
-#: awx/main/conf.py:394 awx/main/conf.py:414 awx/main/conf.py:424
-#: awx/main/conf.py:434 awx/main/conf.py:450 awx/main/conf.py:463
-#: awx/main/conf.py:477 awx/main/conf.py:491 awx/main/conf.py:503
-#: awx/main/conf.py:513 awx/main/conf.py:524 awx/main/conf.py:534
-#: awx/main/conf.py:545 awx/main/conf.py:555 awx/main/conf.py:565
-#: awx/main/conf.py:577 awx/main/conf.py:589 awx/main/conf.py:601
-#: awx/main/conf.py:615 awx/main/conf.py:627
+#: awx/main/conf.py:182 awx/main/conf.py:204 awx/main/conf.py:213
+#: awx/main/conf.py:224 awx/main/conf.py:234 awx/main/conf.py:244
+#: awx/main/conf.py:254 awx/main/conf.py:265 awx/main/conf.py:277
+#: awx/main/conf.py:286 awx/main/conf.py:299 awx/main/conf.py:312
+#: awx/main/conf.py:324 awx/main/conf.py:335 awx/main/conf.py:346
+#: awx/main/conf.py:358 awx/main/conf.py:370 awx/main/conf.py:381
+#: awx/main/conf.py:401 awx/main/conf.py:411 awx/main/conf.py:421
+#: awx/main/conf.py:434 awx/main/conf.py:445 awx/main/conf.py:455
+#: awx/main/conf.py:466 awx/main/conf.py:476 awx/main/conf.py:486
+#: awx/main/conf.py:498 awx/main/conf.py:510 awx/main/conf.py:522
+#: awx/main/conf.py:536 awx/main/conf.py:548
msgid "Jobs"
msgstr "ジョブ"
-#: awx/main/conf.py:192
+#: awx/main/conf.py:191
msgid "Always"
msgstr "常時"
-#: awx/main/conf.py:193
+#: awx/main/conf.py:192
msgid "Never"
msgstr "なし"
-#: awx/main/conf.py:194
+#: awx/main/conf.py:193
msgid "Only On Job Template Definitions"
msgstr "ジョブテンプレートの定義のみ"
-#: awx/main/conf.py:197
+#: awx/main/conf.py:196
msgid "When can extra variables contain Jinja templates?"
msgstr "いつ追加変数に Jinja テンプレートが含まれるか?"
-#: awx/main/conf.py:199
+#: awx/main/conf.py:198
msgid ""
"Ansible allows variable substitution via the Jinja2 templating language for "
"--extra-vars. This poses a potential security risk where Tower users with "
@@ -2033,358 +2120,294 @@ msgid ""
"to \"template\" or \"never\"."
msgstr "Ansible は Jinja2 テンプレート言語を使用した --extra-vars の変数置き換えを許可します。これにより、ジョブの起動時に追加変数を指定できる Tower ユーザーが Jinja2 テンプレートを使用して任意の Python を実行できるようになるためセキュリティー上のリスクが生じます。この値は「template」または「never」に設定することをお勧めします。"
-#: awx/main/conf.py:212
+#: awx/main/conf.py:211
msgid "Enable job isolation"
msgstr "ジョブの分離の有効化"
-#: awx/main/conf.py:213
+#: awx/main/conf.py:212
msgid ""
"Isolates an Ansible job from protected parts of the system to prevent "
"exposing sensitive information."
msgstr "機密情報の公開を防ぐためにシステムの保護された部分から Ansible ジョブを分離します。"
-#: awx/main/conf.py:221
+#: awx/main/conf.py:220
msgid "Job execution path"
msgstr "ジョブの実行パス"
-#: awx/main/conf.py:222
+#: awx/main/conf.py:221
msgid ""
"The directory in which Tower will create new temporary directories for job "
"execution and isolation (such as credential files and custom inventory "
"scripts)."
msgstr "Tower がジョブの実行および分離用に新規の一時ディレクトリーを作成するディレクトリーです (認証情報ファイルおよびカスタムインベントリースクリプトなど)。"
-#: awx/main/conf.py:233
+#: awx/main/conf.py:232
msgid "Paths to hide from isolated jobs"
msgstr "分離されたジョブから非表示にするパス"
-#: awx/main/conf.py:234
+#: awx/main/conf.py:233
msgid ""
"Additional paths to hide from isolated processes. Enter one path per line."
msgstr "分離されたプロセスには公開しないその他のパスです。1 行に 1 つのパスを入力します。"
-#: awx/main/conf.py:243
+#: awx/main/conf.py:242
msgid "Paths to expose to isolated jobs"
msgstr "分離されたジョブに公開するパス"
-#: awx/main/conf.py:244
+#: awx/main/conf.py:243
msgid ""
-"Whitelist of paths that would otherwise be hidden to expose to isolated "
-"jobs. Enter one path per line."
-msgstr "分離されたジョブに公開するために非表示にされるパスのホワイトリストです。1 行に 1 つのパスを入力します。"
+"List of paths that would otherwise be hidden to expose to isolated jobs. "
+"Enter one path per line."
+msgstr "分離されたジョブに公開するために非表示にされるパスの一覧。1 行に 1 つのパスを入力します。"
-#: awx/main/conf.py:254
-msgid "Verbosity level for isolated node management tasks"
-msgstr "分離ノード管理タスクの詳細レベル"
-
-#: awx/main/conf.py:255
-msgid ""
-"This can be raised to aid in debugging connection issues for isolated task "
-"execution"
-msgstr "このレベルを引き上げると、分離されたタスクの実行に接続の問題をデバッグするのに役立ちます。"
-
-#: awx/main/conf.py:265
+#: awx/main/conf.py:252
msgid "Isolated status check interval"
msgstr "分離されたステータスチェックの間隔"
-#: awx/main/conf.py:266
+#: awx/main/conf.py:253
msgid ""
"The number of seconds to sleep between status checks for jobs running on "
"isolated instances."
msgstr "分離されたインスタンスで実行されるジョブに対するステータスチェック間にスリープ状態になる期間の秒数。"
-#: awx/main/conf.py:275
+#: awx/main/conf.py:262
msgid "Isolated launch timeout"
msgstr "分離された起動のタイムアウト"
-#: awx/main/conf.py:276
+#: awx/main/conf.py:263
msgid ""
"The timeout (in seconds) for launching jobs on isolated instances. This "
"includes the time needed to copy source control files (playbooks) to the "
"isolated instance."
msgstr "分離されたインスタンスでジョブを起動する際のタイムアウト (秒数)。これにはソースコントロールファイル (Playbook) を分離されたインスタンスにコピーするために必要な時間が含まれます。"
-#: awx/main/conf.py:287
+#: awx/main/conf.py:274
msgid "Isolated connection timeout"
msgstr "分離された接続のタイムアウト"
-#: awx/main/conf.py:288
+#: awx/main/conf.py:275
msgid ""
"Ansible SSH connection timeout (in seconds) to use when communicating with "
"isolated instances. Value should be substantially greater than expected "
"network latency."
msgstr "分離されたインスタンスと通信する際に使用される Ansible SSH 接続のタイムアウト (秒数) です。値は予想されるネットワークの待ち時間よりも大幅に大きな値になるはずです。"
-#: awx/main/conf.py:297
+#: awx/main/conf.py:284
msgid "Isolated host key checking"
msgstr "分離されたホストキーチェック"
-#: awx/main/conf.py:298
+#: awx/main/conf.py:285
msgid ""
"When set to True, AWX will enforce strict host key checking for "
"communication with isolated nodes."
msgstr "True に設定すると、AWX は、分離したノードとの通信に対するホストキーの厳密なチェックを有効にします。"
-#: awx/main/conf.py:308
+#: awx/main/conf.py:295
msgid "Generate RSA keys for isolated instances"
msgstr "分離されたインスタンスの RSA 鍵の生成"
-#: awx/main/conf.py:309
+#: awx/main/conf.py:296
msgid ""
"If set, a random RSA key will be generated and distributed to isolated "
"instances. To disable this behavior and manage authentication for isolated "
"instances outside of Tower, disable this setting."
msgstr "設定されている場合、RSA 鍵が生成され、分離されたインスタンスに配布されます。この動作を無効にし、Tower の外部にある分離されたインスタンスの認証を管理するには、この設定を無効にします。"
-#: awx/main/conf.py:323 awx/main/conf.py:324
+#: awx/main/conf.py:310 awx/main/conf.py:311
msgid "The RSA private key for SSH traffic to isolated instances"
msgstr "分離されたインスタンスへの SSH トラフィック用の RSA 秘密鍵"
-#: awx/main/conf.py:335 awx/main/conf.py:336
+#: awx/main/conf.py:322 awx/main/conf.py:323
msgid "The RSA public key for SSH traffic to isolated instances"
msgstr "分離されたインスタンスへの SSH トラフィック用の RSA 公開鍵"
-#: awx/main/conf.py:345
+#: awx/main/conf.py:332
msgid "Enable detailed resource profiling on all playbook runs"
msgstr "全 Playbook の実行に対する詳細なリソースプロファイリングを有効にする"
-#: awx/main/conf.py:346
+#: awx/main/conf.py:333
msgid ""
"If set, detailed resource profiling data will be collected on all jobs. This "
"data can be gathered with `sosreport`."
msgstr "設定されている場合には、すべてのジョブに対するリソースプロファイリングデータが収集されます。このデータは、`sosreport` で収集できます。"
-#: awx/main/conf.py:356
+#: awx/main/conf.py:343
msgid "Interval (in seconds) between polls for cpu usage."
msgstr "CPU 使用率のポーリングの間隔 (秒単位)。"
-#: awx/main/conf.py:357
+#: awx/main/conf.py:344
msgid ""
"Interval (in seconds) between polls for cpu usage. Setting this lower than "
"the default will affect playbook performance."
msgstr "CPU 使用率のポーリングの間隔 (秒単位)。これをデフォルトよりも小さい値に設定すると Playbook のパフォーマンスに影響があります。"
-#: awx/main/conf.py:368
+#: awx/main/conf.py:355
msgid "Interval (in seconds) between polls for memory usage."
msgstr "メモリー使用率のポーリングの間隔 (秒単位)。"
-#: awx/main/conf.py:369
+#: awx/main/conf.py:356
msgid ""
"Interval (in seconds) between polls for memory usage. Setting this lower "
"than the default will affect playbook performance."
msgstr "メモリー使用率のポーリングの間隔 (秒単位)。これをデフォルトよりも小さい値に設定すると Playbook のパフォーマンスに影響があります。"
-#: awx/main/conf.py:380
+#: awx/main/conf.py:367
msgid "Interval (in seconds) between polls for PID count."
msgstr "PID 数のポーリングの間隔 (秒単位)。"
-#: awx/main/conf.py:381
+#: awx/main/conf.py:368
msgid ""
"Interval (in seconds) between polls for PID count. Setting this lower than "
"the default will affect playbook performance."
msgstr "PID 数のポーリングの間隔 (秒単位)。これをデフォルトよりも小さい値に設定すると Playbook のパフォーマンスに影響があります。"
-#: awx/main/conf.py:392
+#: awx/main/conf.py:379
msgid "Extra Environment Variables"
msgstr "追加の環境変数"
-#: awx/main/conf.py:393
+#: awx/main/conf.py:380
msgid ""
"Additional environment variables set for playbook runs, inventory updates, "
"project updates, and notification sending."
msgstr "Playbook 実行、インベントリー更新、プロジェクト更新および通知の送信に設定される追加の環境変数。"
-#: awx/main/conf.py:403
+#: awx/main/conf.py:390
msgid "Gather data for Automation Analytics"
msgstr "自動化アナリティクス向けにデータを収集する"
-#: awx/main/conf.py:404
+#: awx/main/conf.py:391
msgid "Enables Tower to gather data on automation and send it to Red Hat."
msgstr "Tower が自動化のデータを収集して Red Hat に送信できるようにします。"
-#: awx/main/conf.py:412
+#: awx/main/conf.py:399
msgid "Run Project Updates With Higher Verbosity"
msgstr "より詳細なプロジェクト更新を実行する"
-#: awx/main/conf.py:413
+#: awx/main/conf.py:400
msgid ""
"Adds the CLI -vvv flag to ansible-playbook runs of project_update.yml used "
"for project updates."
msgstr "プロジェクトの更新に使用する project_update.yml の ansible-playbook に CLI -vvv フラグを追加します。"
-#: awx/main/conf.py:422
+#: awx/main/conf.py:409
msgid "Enable Role Download"
msgstr "ロールのダウンロードを有効にする"
-#: awx/main/conf.py:423
+#: awx/main/conf.py:410
msgid ""
"Allows roles to be dynamically downloaded from a requirements.yml file for "
"SCM projects."
msgstr "ロールが SCM プロジェクトの requirements.yml ファイルから動的にダウンロードされるのを許可します。"
-#: awx/main/conf.py:432
+#: awx/main/conf.py:419
msgid "Enable Collection(s) Download"
msgstr "コレクションのダウンロードを有効にする"
-#: awx/main/conf.py:433
+#: awx/main/conf.py:420
msgid ""
"Allows collections to be dynamically downloaded from a requirements.yml file "
"for SCM projects."
msgstr "コレクションが SCM プロジェクトの requirements.yml ファイルから動的にダウンロードされるのを許可します。"
-#: awx/main/conf.py:443
-msgid "Primary Galaxy Server URL"
-msgstr "プライマリー Galaxy Server URL"
+#: awx/main/conf.py:429
+msgid "Follow symlinks"
+msgstr "シンボリックリンクをたどる"
-#: awx/main/conf.py:445
+#: awx/main/conf.py:431
msgid ""
-"For organizations that run their own Galaxy service, this gives the option "
-"to specify a host as the primary galaxy server. Requirements will be "
-"downloaded from the primary if the specific role or collection is available "
-"there. If the content is not avilable in the primary, or if this field is "
-"left blank, it will default to galaxy.ansible.com."
-msgstr "Galaxy サービスを実行する組織では、プライマリーの Galaxy Server としてホストを指定するオプションが追加されます。特定のロールやコレクションが利用できる場合には、このプライマリーのサーバーから要件がダウンロードされます。または、フィールドが空白の場合は、galaxy.ansible.com のデフォルト設定を使用します。"
+"Follow symbolic links when scanning for playbooks. Be aware that setting "
+"this to True can lead to infinite recursion if a link points to a parent "
+"directory of itself."
+msgstr "Playbook をスキャンするときは、シンボリックリンクをたどってください。リンクがそれ自体の親ディレクトリーを指している場合は、これを True に設定すると、無限再帰が発生する可能性があることに注意してください。"
-#: awx/main/conf.py:459
-msgid "Primary Galaxy Server Username"
-msgstr "プライマリー Galaxy Server のユーザー名"
-
-#: awx/main/conf.py:460
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The username to use for basic authentication against the Galaxy "
-"instance, this is mutually exclusive with PRIMARY_GALAXY_TOKEN."
-msgstr "パブリックの Ansible Galaxy より優先順位の高い Galaxy Server を使用する場合に、Galaxy インスタンスへの Basic 認証に使用するユーザー名です。これは、PRIMARY_GALAXY_TOKEN と同時に使用できません。"
-
-#: awx/main/conf.py:473
-msgid "Primary Galaxy Server Password"
-msgstr "プライマリー Galaxy Server のパスワード"
-
-#: awx/main/conf.py:474
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The password to use for basic authentication against the Galaxy "
-"instance, this is mutually exclusive with PRIMARY_GALAXY_TOKEN."
-msgstr "パブリックの Ansible Galaxy より優先順位の高い Galaxy Server を使用する場合に、Galaxy インスタンスへの Basic 認証に使用するパスワードです。これは、PRIMARY_GALAXY_TOKEN と同時に使用できません。"
-
-#: awx/main/conf.py:487
-msgid "Primary Galaxy Server Token"
-msgstr "プライマリー Galaxy Server トークン"
-
-#: awx/main/conf.py:488
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The token to use for connecting with the Galaxy instance, this is "
-"mutually exclusive with corresponding username and password settings."
-msgstr "パブリックの Ansible Galaxy より優先順位の高い Galaxy Server を使用する場合に、Galaxy インスタンスへの接続に使用するトークンです。これは、対応のユーザー名およびパスワード設定と同時に使用できません。"
-
-#: awx/main/conf.py:500
-msgid "Primary Galaxy Authentication URL"
-msgstr "プライマリー Galaxy 認証 URL"
-
-#: awx/main/conf.py:501
-msgid ""
-"For using a galaxy server at higher precedence than the public Ansible "
-"Galaxy. The token_endpoint of a Keycloak server."
-msgstr "パブリックの Ansible Galaxy より優先順位の高い Galaxy Server を使用する場合に、使用する Keycloak Server の token_endpoint です。"
-
-#: awx/main/conf.py:511
-msgid "Allow Access to Public Galaxy"
-msgstr "Public Galaxy へのアクセスを許可"
-
-#: awx/main/conf.py:512
-msgid ""
-"Allow or deny access to the public Ansible Galaxy during project updates."
-msgstr "プロジェクト更新中にパブリックの Ansible Galaxy へのアクセスを許可または拒否します。"
-
-#: awx/main/conf.py:521
+#: awx/main/conf.py:442
msgid "Ignore Ansible Galaxy SSL Certificate Verification"
msgstr "Ansible Galaxy SSL 証明書の検証を無視する"
-#: awx/main/conf.py:522
+#: awx/main/conf.py:443
msgid ""
-"If set to true, certificate validation will not be done wheninstalling "
+"If set to true, certificate validation will not be done when installing "
"content from any Galaxy server."
msgstr "True に設定すると、任意の Galaxy サーバーからコンテンツをインストールする時に証明書は検証されません。"
-#: awx/main/conf.py:532
+#: awx/main/conf.py:453
msgid "Standard Output Maximum Display Size"
msgstr "標準出力の最大表示サイズ"
-#: awx/main/conf.py:533
+#: awx/main/conf.py:454
msgid ""
"Maximum Size of Standard Output in bytes to display before requiring the "
"output be downloaded."
msgstr "出力のダウンロードを要求する前に表示される標準出力の最大サイズ (バイト単位)。"
-#: awx/main/conf.py:542
+#: awx/main/conf.py:463
msgid "Job Event Standard Output Maximum Display Size"
msgstr "ジョブイベントの標準出力の最大表示サイズ"
-#: awx/main/conf.py:544
+#: awx/main/conf.py:465
msgid ""
"Maximum Size of Standard Output in bytes to display for a single job or ad "
"hoc command event. `stdout` will end with `…` when truncated."
msgstr "単一ジョブまたはアドホックコマンドイベントについて表示される標準出力の最大サイズ (バイト単位)。`stdout` は切り捨てが実行されると `…` で終了します。"
-#: awx/main/conf.py:553
+#: awx/main/conf.py:474
msgid "Maximum Scheduled Jobs"
msgstr "スケジュール済みジョブの最大数"
-#: awx/main/conf.py:554
+#: awx/main/conf.py:475
msgid ""
"Maximum number of the same job template that can be waiting to run when "
"launching from a schedule before no more are created."
msgstr "スケジュールからの起動時に実行を待機している同じジョブテンプレートの最大数です (これ以上作成されることはありません)。"
-#: awx/main/conf.py:563
+#: awx/main/conf.py:484
msgid "Ansible Callback Plugins"
msgstr "Ansible コールバックプラグイン"
-#: awx/main/conf.py:564
+#: awx/main/conf.py:485
msgid ""
"List of paths to search for extra callback plugins to be used when running "
"jobs. Enter one path per line."
msgstr "ジョブの実行時に使用される追加のコールバックプラグインを検索する際のパスの一覧です。1 行に 1 つのパスを入力します。"
-#: awx/main/conf.py:574
+#: awx/main/conf.py:495
msgid "Default Job Timeout"
msgstr "デフォルトのジョブタイムアウト"
-#: awx/main/conf.py:575
+#: awx/main/conf.py:496
msgid ""
"Maximum time in seconds to allow jobs to run. Use value of 0 to indicate "
"that no timeout should be imposed. A timeout set on an individual job "
"template will override this."
msgstr "ジョブの実行可能な最大時間 (秒数) です。値 0 が使用されている場合はタイムアウトを設定できないことを示します。個別のジョブテンプレートに設定されるタイムアウトはこれを上書きします。"
-#: awx/main/conf.py:586
+#: awx/main/conf.py:507
msgid "Default Inventory Update Timeout"
msgstr "デフォルトのインベントリー更新タイムアウト"
-#: awx/main/conf.py:587
+#: awx/main/conf.py:508
msgid ""
"Maximum time in seconds to allow inventory updates to run. Use value of 0 to "
"indicate that no timeout should be imposed. A timeout set on an individual "
"inventory source will override this."
msgstr "インベントリー更新の実行可能な最大時間 (秒数)。値 0 が設定されている場合はタイムアウトを設定できないことを示します。個別のインベントリーソースに設定されるタイムアウトはこれを上書きします。"
-#: awx/main/conf.py:598
+#: awx/main/conf.py:519
msgid "Default Project Update Timeout"
msgstr "デフォルトのプロジェクト更新タイムアウト"
-#: awx/main/conf.py:599
+#: awx/main/conf.py:520
msgid ""
"Maximum time in seconds to allow project updates to run. Use value of 0 to "
"indicate that no timeout should be imposed. A timeout set on an individual "
"project will override this."
msgstr "プロジェクト更新の実行可能な最大時間 (秒数)。値 0 が設定されている場合はタイムアウトを設定できないことを示します。個別のプロジェクトに設定されるタイムアウトはこれを上書きします。"
-#: awx/main/conf.py:610
+#: awx/main/conf.py:531
msgid "Per-Host Ansible Fact Cache Timeout"
msgstr "ホストあたりの Ansible ファクトキャッシュのタイムアウト"
-#: awx/main/conf.py:611
+#: awx/main/conf.py:532
msgid ""
"Maximum time, in seconds, that stored Ansible facts are considered valid "
"since the last time they were modified. Only valid, non-stale, facts will be "
@@ -2393,74 +2416,74 @@ msgid ""
"timeout should be imposed."
msgstr "保存される Ansible ファクトが最後に変更されてから有効とみなされる最大時間 (秒数) です。有効な新規のファクトのみが Playbook でアクセスできます。ansible_facts のデータベースからの削除はこれによる影響を受けません。タイムアウトが設定されないことを示すには 0 の値を使用します。"
-#: awx/main/conf.py:624
+#: awx/main/conf.py:545
msgid "Maximum number of forks per job."
msgstr "ジョブ別のフォークの最大数。"
-#: awx/main/conf.py:625
+#: awx/main/conf.py:546
msgid ""
"Saving a Job Template with more than this number of forks will result in an "
"error. When set to 0, no limit is applied."
msgstr "この数を超えるフォークを指定してジョブテンプレートを保存すると、エラーが発生します。 0 に設定すると、制限は適用されません。"
-#: awx/main/conf.py:636
+#: awx/main/conf.py:557
msgid "Logging Aggregator"
msgstr "ログアグリゲーター"
-#: awx/main/conf.py:637
+#: awx/main/conf.py:558
msgid "Hostname/IP where external logs will be sent to."
msgstr "外部ログの送信先のホスト名/IP"
-#: awx/main/conf.py:638 awx/main/conf.py:649 awx/main/conf.py:661
-#: awx/main/conf.py:671 awx/main/conf.py:683 awx/main/conf.py:698
-#: awx/main/conf.py:710 awx/main/conf.py:719 awx/main/conf.py:729
-#: awx/main/conf.py:741 awx/main/conf.py:752 awx/main/conf.py:764
-#: awx/main/conf.py:777 awx/main/conf.py:787 awx/main/conf.py:799
-#: awx/main/conf.py:810 awx/main/conf.py:820
+#: awx/main/conf.py:559 awx/main/conf.py:570 awx/main/conf.py:582
+#: awx/main/conf.py:592 awx/main/conf.py:604 awx/main/conf.py:619
+#: awx/main/conf.py:631 awx/main/conf.py:640 awx/main/conf.py:650
+#: awx/main/conf.py:662 awx/main/conf.py:673 awx/main/conf.py:685
+#: awx/main/conf.py:698 awx/main/conf.py:710 awx/main/conf.py:721
+#: awx/main/conf.py:731
msgid "Logging"
msgstr "ロギング"
-#: awx/main/conf.py:646
+#: awx/main/conf.py:567
msgid "Logging Aggregator Port"
msgstr "ログアグリゲーターポート"
-#: awx/main/conf.py:647
+#: awx/main/conf.py:568
msgid ""
"Port on Logging Aggregator to send logs to (if required and not provided in "
"Logging Aggregator)."
msgstr "ログの送信先のログアグリゲーターのポート (必要な場合。ログアグリゲーターでは指定されません)。"
-#: awx/main/conf.py:659
+#: awx/main/conf.py:580
msgid "Logging Aggregator Type"
msgstr "ログアグリゲーターのタイプ"
-#: awx/main/conf.py:660
+#: awx/main/conf.py:581
msgid "Format messages for the chosen log aggregator."
msgstr "選択されたログアグリゲーターのメッセージのフォーマット。"
-#: awx/main/conf.py:669
+#: awx/main/conf.py:590
msgid "Logging Aggregator Username"
msgstr "ログアグリゲーターのユーザー名"
-#: awx/main/conf.py:670
+#: awx/main/conf.py:591
msgid "Username for external log aggregator (if required; HTTP/s only)."
msgstr "外部ログアグリゲーターのユーザー名 (必要な場合、HTTP/s のみ)。"
-#: awx/main/conf.py:681
+#: awx/main/conf.py:602
msgid "Logging Aggregator Password/Token"
msgstr "ログアグリゲーターのパスワード/トークン"
-#: awx/main/conf.py:682
+#: awx/main/conf.py:603
msgid ""
"Password or authentication token for external log aggregator (if required; "
"HTTP/s only)."
msgstr "外部ログアグリゲーターのパスワードまたは認証トークン (必要な場合、HTTP/s のみ)。"
-#: awx/main/conf.py:691
+#: awx/main/conf.py:612
msgid "Loggers Sending Data to Log Aggregator Form"
msgstr "ログアグリゲーターフォームにデータを送信するロガー"
-#: awx/main/conf.py:692
+#: awx/main/conf.py:613
msgid ""
"List of loggers that will send HTTP logs to the collector, these can include "
"any or all of: \n"
@@ -2474,11 +2497,11 @@ msgstr "HTTP ログをコレクターに送信するロガーの一覧です。
"job_events - Ansible ジョブイベントからのコールバックデータ\n"
"system_tracking - スキャンジョブから生成されるファクト"
-#: awx/main/conf.py:705
+#: awx/main/conf.py:626
msgid "Log System Tracking Facts Individually"
msgstr "ログシステムトラッキングの個別ファクト"
-#: awx/main/conf.py:706
+#: awx/main/conf.py:627
msgid ""
"If set, system tracking facts will be sent for each package, service, or "
"other item found in a scan, allowing for greater search query granularity. "
@@ -2486,47 +2509,47 @@ msgid ""
"efficiency in fact processing."
msgstr "設定されている場合、スキャンで見つかる各パッケージ、サービスその他の項目についてのシステムトラッキングのファクトが送信され、検索クエリーの詳細度が上がります。設定されていない場合、ファクトは単一辞書として送信され、ファクトの処理の効率が上がります。"
-#: awx/main/conf.py:717
+#: awx/main/conf.py:638
msgid "Enable External Logging"
msgstr "外部ログの有効化"
-#: awx/main/conf.py:718
+#: awx/main/conf.py:639
msgid "Enable sending logs to external log aggregator."
msgstr "外部ログアグリゲーターへのログ送信の有効化"
-#: awx/main/conf.py:727
+#: awx/main/conf.py:648
msgid "Cluster-wide Tower unique identifier."
msgstr "クラスター全体での Tower 固有識別子。"
-#: awx/main/conf.py:728
+#: awx/main/conf.py:649
msgid "Useful to uniquely identify Tower instances."
msgstr "Tower インスタンスを一意に識別するのに役立ちます。"
-#: awx/main/conf.py:737
+#: awx/main/conf.py:658
msgid "Logging Aggregator Protocol"
msgstr "ログアグリゲーターのプロトコル"
-#: awx/main/conf.py:738
+#: awx/main/conf.py:659
msgid ""
"Protocol used to communicate with log aggregator. HTTPS/HTTP assumes HTTPS "
"unless http:// is explicitly used in the Logging Aggregator hostname."
msgstr "ログアグリゲーターとの通信に使用されるプロトコルです。HTTPS/HTTP については、 http:// がログアグリゲーターのホスト名で明示的に使用されていない限り HTTPS の使用が前提となります。"
-#: awx/main/conf.py:748
+#: awx/main/conf.py:669
msgid "TCP Connection Timeout"
msgstr "TCP 接続のタイムアウト"
-#: awx/main/conf.py:749
+#: awx/main/conf.py:670
msgid ""
"Number of seconds for a TCP connection to external log aggregator to "
"timeout. Applies to HTTPS and TCP log aggregator protocols."
msgstr "外部ログアグリゲーターへの TCP 接続がタイムアウトする秒数です。HTTPS および TCP ログアグリゲータープロトコルに適用されます。"
-#: awx/main/conf.py:759
+#: awx/main/conf.py:680
msgid "Enable/disable HTTPS certificate verification"
msgstr "HTTPS 証明書の検証を有効化/無効化"
-#: awx/main/conf.py:760
+#: awx/main/conf.py:681
msgid ""
"Flag to control enable/disable of certificate verification when "
"LOG_AGGREGATOR_PROTOCOL is \"https\". If enabled, Tower's log handler will "
@@ -2534,11 +2557,11 @@ msgid ""
"connection."
msgstr "LOG_AGGREGATOR_PROTOCOL が「https」の場合の証明書の検証の有効化/無効化を制御するフラグです。有効にされている場合、Tower のログハンドラーは接続を確立する前に外部ログアグリゲーターによって送信される証明書を検証します。"
-#: awx/main/conf.py:772
+#: awx/main/conf.py:693
msgid "Logging Aggregator Level Threshold"
msgstr "ログアグリゲーターレベルのしきい値"
-#: awx/main/conf.py:773
+#: awx/main/conf.py:694
msgid ""
"Level threshold used by log handler. Severities from lowest to highest are "
"DEBUG, INFO, WARNING, ERROR, CRITICAL. Messages less severe than the "
@@ -2546,198 +2569,144 @@ msgid ""
"anlytics ignore this setting)"
msgstr "ログハンドラーによって使用されるレベルのしきい値です。重大度は低い順から高い順に DEBUG、INFO、WARNING、ERROR、CRITICAL になります。しきい値より重大度の低いメッセージはログハンドラーによって無視されます (カテゴリー awx.anlytics の下にあるメッセージはこの設定を無視します)。"
-#: awx/main/conf.py:785
-msgid "Enabled external log aggregation auditing"
-msgstr "有効な外部ログ集計監査"
-
-#: awx/main/conf.py:786
-msgid ""
-"When enabled, all external logs emitted by Tower will also be written to /"
-"var/log/tower/external.log. This is an experimental setting intended to be "
-"used for debugging external log aggregation issues (and may be subject to "
-"change in the future)."
-msgstr "有効な場合には、Tower が出力した外部ログはすべて、/var/log/tower/external.log に書き込まれます。この試用的な設定は、外部ログを累積する問題をデバッグするのに使用します (今後、この設定は変更される可能性があります)。"
-
-#: awx/main/conf.py:795
+#: awx/main/conf.py:706
msgid "Maximum disk persistance for external log aggregation (in GB)"
msgstr "外部ログ集計の最大ディスク永続性 (GB)"
-#: awx/main/conf.py:796
+#: awx/main/conf.py:707
msgid ""
"Amount of data to store (in gigabytes) during an outage of the external log "
"aggregator (defaults to 1). Equivalent to the rsyslogd queue.maxdiskspace "
"setting."
msgstr "外部ログアグリゲーターの停止中に保存するデータ容量 (GB、デフォルトは 1)。rsyslogd queue.maxdiskspace 設定と同じです。"
-#: awx/main/conf.py:806
+#: awx/main/conf.py:717
msgid "File system location for rsyslogd disk persistence"
msgstr "rsyslogd ディスク永続性のファイルシステムの場所"
-#: awx/main/conf.py:807
+#: awx/main/conf.py:718
msgid ""
"Location to persist logs that should be retried after an outage of the "
"external log aggregator (defaults to /var/lib/awx). Equivalent to the "
"rsyslogd queue.spoolDirectory setting."
msgstr "外部ログアグリゲーターが停止した後に再試行する必要のあるログを永続化する場所 (デフォルト: /var/lib/awx)。rsyslogd queue.spoolDirectory の設定と同じです。"
-#: awx/main/conf.py:817
+#: awx/main/conf.py:728
msgid "Enable rsyslogd debugging"
msgstr "rsyslogd デバッグを有効にする"
-#: awx/main/conf.py:818
+#: awx/main/conf.py:729
msgid ""
"Enabled high verbosity debugging for rsyslogd. Useful for debugging "
"connection issues for external log aggregation."
msgstr "rsyslogd の詳細デバッグを有効にしました。外部ログ集計の接続問題のデバッグに役立ちます。"
-#: awx/main/conf.py:828
-msgid "Message Durability"
-msgstr "メッセージの永続性"
-
-#: awx/main/conf.py:829
-msgid ""
-"When set (the default), underlying queues will be persisted to disk. "
-"Disable this to enable higher message bus throughput."
-msgstr "(デフォルト値) が設定されている場合には、下層のキューはディスクに永続化されます。これを無効すると、メッセージバスのスループットを増加できます。"
-
-#: awx/main/conf.py:838
+#: awx/main/conf.py:740
msgid "Last gather date for Automation Analytics."
msgstr "自動化アナリティクス向けにデータを最後に収集した日"
-#: awx/main/conf.py:848
+#: awx/main/conf.py:750
msgid "Automation Analytics Gather Interval"
msgstr "自動化アナリティクスの収集間隔"
-#: awx/main/conf.py:849
+#: awx/main/conf.py:751
msgid "Interval (in seconds) between data gathering."
msgstr "データ収集の間隔 (秒単位)"
-#: awx/main/conf.py:871 awx/sso/conf.py:1239
+#: awx/main/conf.py:773 awx/sso/conf.py:1250
msgid "\n"
msgstr "\n"
-#: awx/main/conf.py:892
-msgid ""
-"A URL for Primary Galaxy must be defined before disabling public Galaxy."
-msgstr "パブリック Galaxy を無効にする前に、Primary Galaxy の URL を定義する必要があります。"
-
-#: awx/main/conf.py:912
-msgid "Cannot provide field if PRIMARY_GALAXY_URL is not set."
-msgstr "PRIMARY_Galaxy_URL が設定されていない場合にはフィールドは指定できません。"
-
-#: awx/main/conf.py:925
-#, python-brace-format
-msgid ""
-"Galaxy server settings are not available until Ansible {min_version}, you "
-"are running {current_version}."
-msgstr "Galaxy Server の設定は Ansible {min_version} するまで利用できません。{current_version} を実行しています。"
-
-#: awx/main/conf.py:934
-msgid ""
-"Setting Galaxy token and authentication URL is mutually exclusive with "
-"username and password."
-msgstr "Galaxy トークンと認証 URL を設定すると、ユーザー名とパスワードの認証は使用できません。"
-
-#: awx/main/conf.py:937
-msgid "If authenticating via username and password, both must be provided."
-msgstr "ユーザー名とパスワードで認証する場合には、ユーザー名とパスワード両方を指定する必要があります。"
-
-#: awx/main/conf.py:943
-msgid ""
-"If authenticating via token, both token and authentication URL must be "
-"provided."
-msgstr "トークンで認証する場合には、トークンと認証 URL の両方を指定する必要があります。"
-
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Sudo"
msgstr "Sudo"
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Su"
msgstr "Su"
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Pbrun"
msgstr "Pbrun"
-#: awx/main/constants.py:17
+#: awx/main/constants.py:16
msgid "Pfexec"
msgstr "Pfexec"
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "DZDO"
msgstr "DZDO"
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "Pmrun"
msgstr "Pmrun"
-#: awx/main/constants.py:18
+#: awx/main/constants.py:17
msgid "Runas"
msgstr "Runas"
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Enable"
msgstr "有効化"
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Doas"
msgstr "Doas"
-#: awx/main/constants.py:19
+#: awx/main/constants.py:18
msgid "Ksu"
msgstr "Ksu"
-#: awx/main/constants.py:20
+#: awx/main/constants.py:19
msgid "Machinectl"
msgstr "Machinectl"
-#: awx/main/constants.py:20
+#: awx/main/constants.py:19
msgid "Sesu"
msgstr "Sesu"
-#: awx/main/constants.py:22
+#: awx/main/constants.py:21
msgid "None"
msgstr "なし"
-#: awx/main/credential_plugins/aim.py:16
+#: awx/main/credential_plugins/aim.py:11
msgid "CyberArk AIM URL"
msgstr "CyberArk AIM URL"
-#: awx/main/credential_plugins/aim.py:21
+#: awx/main/credential_plugins/aim.py:16
msgid "Application ID"
msgstr "アプリケーション ID"
-#: awx/main/credential_plugins/aim.py:26
+#: awx/main/credential_plugins/aim.py:21
msgid "Client Key"
msgstr "クライアントキー"
-#: awx/main/credential_plugins/aim.py:32
+#: awx/main/credential_plugins/aim.py:27
msgid "Client Certificate"
msgstr "クライアント証明書"
-#: awx/main/credential_plugins/aim.py:38
+#: awx/main/credential_plugins/aim.py:33
msgid "Verify SSL Certificates"
msgstr "SSL 証明書の検証"
-#: awx/main/credential_plugins/aim.py:44
+#: awx/main/credential_plugins/aim.py:39
msgid "Object Query"
msgstr "オブジェクトのクエリー"
-#: awx/main/credential_plugins/aim.py:46
+#: awx/main/credential_plugins/aim.py:41
msgid ""
"Lookup query for the object. Ex: Safe=TestSafe;Object=testAccountName123"
msgstr "オブジェクトの検索クエリー。例: Safe=TestSafe;Object=testAccountName123"
-#: awx/main/credential_plugins/aim.py:49
+#: awx/main/credential_plugins/aim.py:44
msgid "Object Query Format"
msgstr "オブジェクトクエリーフォーマット (必須)"
-#: awx/main/credential_plugins/aim.py:55
+#: awx/main/credential_plugins/aim.py:50
msgid "Reason"
msgstr "理由"
-#: awx/main/credential_plugins/aim.py:57
+#: awx/main/credential_plugins/aim.py:52
msgid ""
"Object request reason. This is only needed if it is required by the object's "
"policy."
@@ -2748,12 +2717,12 @@ msgid "Vault URL (DNS Name)"
msgstr "Vault URL (DNS 名)"
#: awx/main/credential_plugins/azure_kv.py:26
-#: awx/main/models/credential/__init__.py:956
+#: awx/main/models/credential/__init__.py:968
msgid "Client ID"
msgstr "クライアント ID"
#: awx/main/credential_plugins/azure_kv.py:35
-#: awx/main/models/credential/__init__.py:965
+#: awx/main/models/credential/__init__.py:977
msgid "Tenant ID"
msgstr "テナント ID"
@@ -2774,142 +2743,177 @@ msgid "The name of the secret to look up."
msgstr "検索するシークレット名"
#: awx/main/credential_plugins/azure_kv.py:51
-#: awx/main/credential_plugins/conjur.py:47
+#: awx/main/credential_plugins/conjur.py:42
msgid "Secret Version"
msgstr "シークレットのバージョン"
#: awx/main/credential_plugins/azure_kv.py:53
-#: awx/main/credential_plugins/conjur.py:49
-#: awx/main/credential_plugins/hashivault.py:67
+#: awx/main/credential_plugins/conjur.py:44
+#: awx/main/credential_plugins/hashivault.py:89
msgid ""
"Used to specify a specific secret version (if left empty, the latest version "
"will be used)."
msgstr "シークレットバージョンの指定に使用します (空白の場合は、最新のバージョンが使用されます)。"
-#: awx/main/credential_plugins/conjur.py:18
+#: awx/main/credential_plugins/conjur.py:13
msgid "Conjur URL"
msgstr "Conjur URL"
-#: awx/main/credential_plugins/conjur.py:23
+#: awx/main/credential_plugins/conjur.py:18
msgid "API Key"
msgstr "API キー"
-#: awx/main/credential_plugins/conjur.py:28 awx/main/models/inventory.py:1018
+#: awx/main/credential_plugins/conjur.py:23
+#: awx/main/migrations/_inventory_source_vars.py:142
msgid "Account"
msgstr "アカウント"
-#: awx/main/credential_plugins/conjur.py:32
-#: awx/main/models/credential/__init__.py:598
-#: awx/main/models/credential/__init__.py:654
-#: awx/main/models/credential/__init__.py:712
-#: awx/main/models/credential/__init__.py:785
-#: awx/main/models/credential/__init__.py:834
-#: awx/main/models/credential/__init__.py:860
-#: awx/main/models/credential/__init__.py:887
-#: awx/main/models/credential/__init__.py:947
-#: awx/main/models/credential/__init__.py:1020
-#: awx/main/models/credential/__init__.py:1051
-#: awx/main/models/credential/__init__.py:1101
+#: awx/main/credential_plugins/conjur.py:27
+#: awx/main/models/credential/__init__.py:606
+#: awx/main/models/credential/__init__.py:662
+#: awx/main/models/credential/__init__.py:720
+#: awx/main/models/credential/__init__.py:793
+#: awx/main/models/credential/__init__.py:846
+#: awx/main/models/credential/__init__.py:872
+#: awx/main/models/credential/__init__.py:899
+#: awx/main/models/credential/__init__.py:959
+#: awx/main/models/credential/__init__.py:1032
+#: awx/main/models/credential/__init__.py:1063
+#: awx/main/models/credential/__init__.py:1113
msgid "Username"
msgstr "ユーザー名"
-#: awx/main/credential_plugins/conjur.py:36
+#: awx/main/credential_plugins/conjur.py:31
msgid "Public Key Certificate"
msgstr "公開鍵の証明書"
-#: awx/main/credential_plugins/conjur.py:42
+#: awx/main/credential_plugins/conjur.py:37
msgid "Secret Identifier"
msgstr "シークレット識別子"
-#: awx/main/credential_plugins/conjur.py:44
+#: awx/main/credential_plugins/conjur.py:39
msgid "The identifier for the secret e.g., /some/identifier"
msgstr "シークレットの識別子。例: /some/identifier"
-#: awx/main/credential_plugins/hashivault.py:19
+#: awx/main/credential_plugins/hashivault.py:14
msgid "Server URL"
msgstr "サーバー URL"
-#: awx/main/credential_plugins/hashivault.py:22
+#: awx/main/credential_plugins/hashivault.py:17
msgid "The URL to the HashiCorp Vault"
msgstr "HashiCorp Vault の URL"
-#: awx/main/credential_plugins/hashivault.py:25
-#: awx/main/models/credential/__init__.py:986
-#: awx/main/models/credential/__init__.py:1003
+#: awx/main/credential_plugins/hashivault.py:20
+#: awx/main/models/credential/__init__.py:998
+#: awx/main/models/credential/__init__.py:1015
msgid "Token"
msgstr "トークン"
-#: awx/main/credential_plugins/hashivault.py:28
+#: awx/main/credential_plugins/hashivault.py:23
msgid "The access token used to authenticate to the Vault server"
msgstr "Vault サーバーへの認証に使用するアクセストークン"
-#: awx/main/credential_plugins/hashivault.py:31
+#: awx/main/credential_plugins/hashivault.py:26
msgid "CA Certificate"
msgstr "CA 証明書"
-#: awx/main/credential_plugins/hashivault.py:34
+#: awx/main/credential_plugins/hashivault.py:29
msgid ""
"The CA certificate used to verify the SSL certificate of the Vault server"
msgstr "Vault サーバーの SSL 証明書の検証に使用する CA 証明書"
+#: awx/main/credential_plugins/hashivault.py:32
+msgid "AppRole role_id"
+msgstr "AppRole role_id"
+
+#: awx/main/credential_plugins/hashivault.py:35
+msgid "The Role ID for AppRole Authentication"
+msgstr "AppRole 認証のロール ID"
+
#: awx/main/credential_plugins/hashivault.py:38
+msgid "AppRole secret_id"
+msgstr "AppRole secret_id"
+
+#: awx/main/credential_plugins/hashivault.py:42
+msgid "The Secret ID for AppRole Authentication"
+msgstr "AppRole 認証のシークレット ID"
+
+#: awx/main/credential_plugins/hashivault.py:45
+msgid "Path to Approle Auth"
+msgstr "ApproleAuth へのパス"
+
+#: awx/main/credential_plugins/hashivault.py:49
+msgid ""
+"The AppRole Authentication path to use if one isn't provided in the metadata "
+"when linking to an input field. Defaults to 'approle'"
+msgstr "入力フィールドにリンクするときにメタデータで指定されていない場合に使用する AppRole 認証パス (デフォルトは「approle」)"
+
+#: awx/main/credential_plugins/hashivault.py:54
msgid "Path to Secret"
msgstr "シークレットへのパス"
-#: awx/main/credential_plugins/hashivault.py:40
+#: awx/main/credential_plugins/hashivault.py:56
msgid "The path to the secret stored in the secret backend e.g, /some/secret/"
-msgstr "シークレットのバックエンドに保存されているシークレットへのパス。例: /some/secret/"
+msgstr "シークレットのバックエンドに保存されているシークレットへのパス。例: /some/secret/"
-#: awx/main/credential_plugins/hashivault.py:48
+#: awx/main/credential_plugins/hashivault.py:59
+msgid "Path to Auth"
+msgstr "認証へのパス"
+
+#: awx/main/credential_plugins/hashivault.py:62
+msgid "The path where the Authentication method is mounted e.g, approle"
+msgstr "認証方法がマウントされるパス (例: approle)"
+
+#: awx/main/credential_plugins/hashivault.py:70
msgid "API Version"
msgstr "API バージョン"
-#: awx/main/credential_plugins/hashivault.py:50
+#: awx/main/credential_plugins/hashivault.py:72
msgid ""
"API v1 is for static key/value lookups. API v2 is for versioned key/value "
"lookups."
msgstr "API v1 は静的なキー/値のルックアップ用で、API v2 はバージョン管理されたキー/値のルックアップ用です。"
-#: awx/main/credential_plugins/hashivault.py:55
+#: awx/main/credential_plugins/hashivault.py:77
msgid "Name of Secret Backend"
msgstr "シークレットバックエンドの名前"
-#: awx/main/credential_plugins/hashivault.py:57
+#: awx/main/credential_plugins/hashivault.py:79
msgid ""
"The name of the kv secret backend (if left empty, the first segment of the "
"secret path will be used)."
msgstr "KV シークレットバックエンド名 (空白の場合は、シークレットパスの最初のセグメントが使用されます)。"
-#: awx/main/credential_plugins/hashivault.py:60
-#: awx/main/models/inventory.py:1023
+#: awx/main/credential_plugins/hashivault.py:82
+#: awx/main/migrations/_inventory_source_vars.py:147
msgid "Key Name"
msgstr "キー名"
-#: awx/main/credential_plugins/hashivault.py:62
+#: awx/main/credential_plugins/hashivault.py:84
msgid "The name of the key to look up in the secret."
msgstr "シークレットで検索するキーの名前"
-#: awx/main/credential_plugins/hashivault.py:65
+#: awx/main/credential_plugins/hashivault.py:87
msgid "Secret Version (v2 only)"
msgstr "シークレットバージョン (v2 のみ)"
-#: awx/main/credential_plugins/hashivault.py:74
+#: awx/main/credential_plugins/hashivault.py:96
msgid "Unsigned Public Key"
msgstr "未署名の公開鍵"
-#: awx/main/credential_plugins/hashivault.py:79
+#: awx/main/credential_plugins/hashivault.py:101
msgid "Role Name"
msgstr "ロール名"
-#: awx/main/credential_plugins/hashivault.py:81
+#: awx/main/credential_plugins/hashivault.py:103
msgid "The name of the role used to sign."
msgstr "署名に使用するロール名"
-#: awx/main/credential_plugins/hashivault.py:84
+#: awx/main/credential_plugins/hashivault.py:106
msgid "Valid Principals"
msgstr "有効なプリンシパル"
-#: awx/main/credential_plugins/hashivault.py:86
+#: awx/main/credential_plugins/hashivault.py:108
msgid ""
"Valid principals (either usernames or hostnames) that the certificate should "
"be signed for."
@@ -2944,70 +2948,74 @@ msgstr "%s に必須です"
msgid "secret values must be of type string, not {}"
msgstr "シークレットの値は文字列型にする必要があります ({}ではない)"
-#: awx/main/fields.py:667
+#: awx/main/fields.py:675
#, python-format
msgid "cannot be set unless \"%s\" is set"
msgstr "\"%s\" が設定されていない場合は設定できません"
-#: awx/main/fields.py:702
+#: awx/main/fields.py:710
msgid "must be set when SSH key is encrypted."
msgstr "SSH キーが暗号化されている場合に設定する必要があります。"
-#: awx/main/fields.py:710
+#: awx/main/fields.py:718
msgid "should not be set when SSH key is not encrypted."
msgstr "SSH キーが暗号化されていない場合は設定できません。"
-#: awx/main/fields.py:769
+#: awx/main/fields.py:777
msgid "'dependencies' is not supported for custom credentials."
msgstr "「dependencies (依存関係)」はカスタム認証情報の場合にはサポートされません。"
-#: awx/main/fields.py:783
+#: awx/main/fields.py:791
msgid "\"tower\" is a reserved field name"
msgstr "「tower」は予約されたフィールド名です"
-#: awx/main/fields.py:790
+#: awx/main/fields.py:798
#, python-format
msgid "field IDs must be unique (%s)"
msgstr "フィールド ID は固有でなければなりません (%s)"
-#: awx/main/fields.py:805
+#: awx/main/fields.py:813
msgid "{} is not a {}"
msgstr "{} は {} ではありません"
-#: awx/main/fields.py:811
+#: awx/main/fields.py:819
#, python-brace-format
msgid "{sub_key} not allowed for {element_type} type ({element_id})"
msgstr "{element_type} タイプには {sub_key} を使用できません ({element_id})"
-#: awx/main/fields.py:869
+#: awx/main/fields.py:877
msgid ""
"Environment variable {} may affect Ansible configuration so its use is not "
"allowed in credentials."
msgstr "環境変数 {} は Ansible の設定に影響を及ぼす可能性があります。したがって認証情報で使用することはできません。"
-#: awx/main/fields.py:875
-msgid "Environment variable {} is blacklisted from use in credentials."
-msgstr "環境変数 {} を認証情報で使用することは禁止されています。"
+#: awx/main/fields.py:883
+msgid "Environment variable {} is not allowed to be used in credentials."
+msgstr "環境変数 {} を認証情報で使用することは許可されていません。"
-#: awx/main/fields.py:903
+#: awx/main/fields.py:911
msgid ""
"Must define unnamed file injector in order to reference `tower.filename`."
msgstr "`tower.filename`を参照するために名前が設定されていないファイルインジェクターを定義する必要があります。"
-#: awx/main/fields.py:910
+#: awx/main/fields.py:918
msgid "Cannot directly reference reserved `tower` namespace container."
msgstr "予約された `tower` 名前空間コンテナーを直接参照することができません。"
-#: awx/main/fields.py:920
+#: awx/main/fields.py:928
msgid "Must use multi-file syntax when injecting multiple files"
msgstr "複数ファイルの挿入時に複数ファイル構文を使用する必要があります。"
-#: awx/main/fields.py:940
+#: awx/main/fields.py:948
#, python-brace-format
msgid "{sub_key} uses an undefined field ({error_msg})"
msgstr "{sub_key} は未定義のフィールドを使用します ({error_msg})"
-#: awx/main/fields.py:947
+#: awx/main/fields.py:955
+msgid "Encountered unsafe code execution: {}"
+msgstr "unsafe コードの実行が発生しました: {}"
+
+#: awx/main/fields.py:959
#, python-brace-format
msgid ""
"Syntax error rendering template for {sub_key} inside of {type} ({error_msg})"
@@ -3037,6 +3045,50 @@ msgid ""
"this list to programmatically generate named URLs for resources"
msgstr "名前付き URL グラフトポロジーを公開するキーと値のペアの読み取り専用一覧です。この一覧を使用してリソースの名前付き URL をプログラムで生成します。"
+#: awx/main/migrations/_inventory_source_vars.py:140
+msgid "Image ID"
+msgstr "イメージ ID"
+
+#: awx/main/migrations/_inventory_source_vars.py:141
+msgid "Availability Zone"
+msgstr "アベイラビリティーゾーン"
+
+#: awx/main/migrations/_inventory_source_vars.py:143
+msgid "Instance ID"
+msgstr "インスタンス ID"
+
+#: awx/main/migrations/_inventory_source_vars.py:144
+msgid "Instance State"
+msgstr "インスタンスの状態"
+
+#: awx/main/migrations/_inventory_source_vars.py:145
+msgid "Platform"
+msgstr "プラットフォーム"
+
+#: awx/main/migrations/_inventory_source_vars.py:146
+msgid "Instance Type"
+msgstr "インスタンスタイプ"
+
+#: awx/main/migrations/_inventory_source_vars.py:148
+msgid "Region"
+msgstr "リージョン"
+
+#: awx/main/migrations/_inventory_source_vars.py:149
+msgid "Security Group"
+msgstr "セキュリティーグループ"
+
+#: awx/main/migrations/_inventory_source_vars.py:150
+msgid "Tags"
+msgstr "タグ"
+
+#: awx/main/migrations/_inventory_source_vars.py:151
+msgid "Tag None"
+msgstr "タグ None"
+
+#: awx/main/migrations/_inventory_source_vars.py:152
+msgid "VPC ID"
+msgstr "VPC ID"
+
#: awx/main/models/activity_stream.py:28
msgid "Entity Created"
msgstr "エンティティーの作成"
@@ -3083,17 +3135,17 @@ msgstr "アドホックコマンドのサポートされていないモジュー
msgid "No argument passed to %s module."
msgstr "%s モジュールに渡される引数はありません。"
-#: awx/main/models/base.py:33 awx/main/models/base.py:39
-#: awx/main/models/base.py:44 awx/main/models/base.py:49
+#: awx/main/models/base.py:34 awx/main/models/base.py:40
+#: awx/main/models/base.py:45 awx/main/models/base.py:50
msgid "Run"
msgstr "実行"
-#: awx/main/models/base.py:34 awx/main/models/base.py:40
-#: awx/main/models/base.py:45 awx/main/models/base.py:50
+#: awx/main/models/base.py:35 awx/main/models/base.py:41
+#: awx/main/models/base.py:46 awx/main/models/base.py:51
msgid "Check"
msgstr "チェック"
-#: awx/main/models/base.py:35
+#: awx/main/models/base.py:36
msgid "Scan"
msgstr "スキャン"
@@ -3103,815 +3155,822 @@ msgid ""
"Tower documentation for details on each type."
msgstr "作成する必要のある証明書のタイプを指定します。それぞれのタイプの詳細については、Ansible Tower ドキュメントを参照してください。"
-#: awx/main/models/credential/__init__.py:110
-#: awx/main/models/credential/__init__.py:353
+#: awx/main/models/credential/__init__.py:114
+#: awx/main/models/credential/__init__.py:358
msgid ""
"Enter inputs using either JSON or YAML syntax. Refer to the Ansible Tower "
"documentation for example syntax."
msgstr "JSON または YAML 構文のいずれかを使用して入力を行います。構文のサンプルについては Ansible Tower ドキュメントを参照してください。"
-#: awx/main/models/credential/__init__.py:325
-#: awx/main/models/credential/__init__.py:594
+#: awx/main/models/credential/__init__.py:329
+#: awx/main/models/credential/__init__.py:602
msgid "Machine"
msgstr "マシン"
-#: awx/main/models/credential/__init__.py:326
-#: awx/main/models/credential/__init__.py:680
+#: awx/main/models/credential/__init__.py:330
+#: awx/main/models/credential/__init__.py:688
msgid "Vault"
msgstr "Vault"
-#: awx/main/models/credential/__init__.py:327
-#: awx/main/models/credential/__init__.py:707
+#: awx/main/models/credential/__init__.py:331
+#: awx/main/models/credential/__init__.py:715
msgid "Network"
msgstr "ネットワーク"
-#: awx/main/models/credential/__init__.py:328
-#: awx/main/models/credential/__init__.py:649
+#: awx/main/models/credential/__init__.py:332
+#: awx/main/models/credential/__init__.py:657
msgid "Source Control"
msgstr "ソースコントロール"
-#: awx/main/models/credential/__init__.py:329
+#: awx/main/models/credential/__init__.py:333
msgid "Cloud"
msgstr "クラウド"
-#: awx/main/models/credential/__init__.py:330
+#: awx/main/models/credential/__init__.py:334
msgid "Personal Access Token"
msgstr "パーソナルアクセストークン"
-#: awx/main/models/credential/__init__.py:331
-#: awx/main/models/credential/__init__.py:1015
+#: awx/main/models/credential/__init__.py:335
+#: awx/main/models/credential/__init__.py:1027
msgid "Insights"
msgstr "Insights"
-#: awx/main/models/credential/__init__.py:332
+#: awx/main/models/credential/__init__.py:336
msgid "External"
msgstr "外部"
-#: awx/main/models/credential/__init__.py:333
+#: awx/main/models/credential/__init__.py:337
msgid "Kubernetes"
msgstr "Kubernetes"
-#: awx/main/models/credential/__init__.py:359
+#: awx/main/models/credential/__init__.py:338
+msgid "Galaxy/Automation Hub"
+msgstr "Galaxy / Automation Hub"
+
+#: awx/main/models/credential/__init__.py:364
msgid ""
"Enter injectors using either JSON or YAML syntax. Refer to the Ansible Tower "
"documentation for example syntax."
msgstr "JSON または YAML 構文のいずれかを使用してインジェクターを入力します。構文のサンプルについては Ansible Tower ドキュメントを参照してください。"
-#: awx/main/models/credential/__init__.py:428
+#: awx/main/models/credential/__init__.py:433
#, python-format
msgid "adding %s credential type"
msgstr "%s 認証情報タイプの追加"
-#: awx/main/models/credential/__init__.py:602
-#: awx/main/models/credential/__init__.py:658
-#: awx/main/models/credential/__init__.py:716
-#: awx/main/models/credential/__init__.py:838
-#: awx/main/models/credential/__init__.py:864
-#: awx/main/models/credential/__init__.py:891
-#: awx/main/models/credential/__init__.py:951
-#: awx/main/models/credential/__init__.py:1024
-#: awx/main/models/credential/__init__.py:1055
-#: awx/main/models/credential/__init__.py:1105
+#: awx/main/models/credential/__init__.py:610
+#: awx/main/models/credential/__init__.py:666
+#: awx/main/models/credential/__init__.py:724
+#: awx/main/models/credential/__init__.py:850
+#: awx/main/models/credential/__init__.py:876
+#: awx/main/models/credential/__init__.py:903
+#: awx/main/models/credential/__init__.py:963
+#: awx/main/models/credential/__init__.py:1036
+#: awx/main/models/credential/__init__.py:1067
+#: awx/main/models/credential/__init__.py:1119
msgid "Password"
msgstr "パスワード"
-#: awx/main/models/credential/__init__.py:608
-#: awx/main/models/credential/__init__.py:721
+#: awx/main/models/credential/__init__.py:616
+#: awx/main/models/credential/__init__.py:729
msgid "SSH Private Key"
msgstr "SSH 秘密鍵"
-#: awx/main/models/credential/__init__.py:615
+#: awx/main/models/credential/__init__.py:623
msgid "Signed SSH Certificate"
msgstr "署名済みの SSH 証明書"
-#: awx/main/models/credential/__init__.py:621
-#: awx/main/models/credential/__init__.py:670
-#: awx/main/models/credential/__init__.py:728
+#: awx/main/models/credential/__init__.py:629
+#: awx/main/models/credential/__init__.py:678
+#: awx/main/models/credential/__init__.py:736
msgid "Private Key Passphrase"
msgstr "秘密鍵のパスフレーズ"
-#: awx/main/models/credential/__init__.py:627
+#: awx/main/models/credential/__init__.py:635
msgid "Privilege Escalation Method"
msgstr "権限昇格方法"
-#: awx/main/models/credential/__init__.py:629
+#: awx/main/models/credential/__init__.py:637
msgid ""
"Specify a method for \"become\" operations. This is equivalent to specifying "
"the --become-method Ansible parameter."
msgstr "「become」操作の方式を指定します。これは --become-method Ansible パラメーターを指定することに相当します。"
-#: awx/main/models/credential/__init__.py:634
+#: awx/main/models/credential/__init__.py:642
msgid "Privilege Escalation Username"
msgstr "権限昇格のユーザー名"
-#: awx/main/models/credential/__init__.py:638
+#: awx/main/models/credential/__init__.py:646
msgid "Privilege Escalation Password"
msgstr "権限昇格のパスワード"
-#: awx/main/models/credential/__init__.py:663
+#: awx/main/models/credential/__init__.py:671
msgid "SCM Private Key"
msgstr "SCM 秘密鍵"
-#: awx/main/models/credential/__init__.py:685
+#: awx/main/models/credential/__init__.py:693
msgid "Vault Password"
msgstr "Vault パスワード"
-#: awx/main/models/credential/__init__.py:691
+#: awx/main/models/credential/__init__.py:699
msgid "Vault Identifier"
msgstr "Vault ID"
-#: awx/main/models/credential/__init__.py:694
+#: awx/main/models/credential/__init__.py:702
msgid ""
"Specify an (optional) Vault ID. This is equivalent to specifying the --vault-"
"id Ansible parameter for providing multiple Vault passwords. Note: this "
"feature only works in Ansible 2.4+."
msgstr "(オプションの) Vault ID を指定します。これは、複数の Vault パスワードを指定するために --vault-id Ansible パラメーターを指定することに相当します。注: この機能は Ansible 2.4+ でのみ機能します。"
-#: awx/main/models/credential/__init__.py:733
+#: awx/main/models/credential/__init__.py:741
msgid "Authorize"
msgstr "承認"
-#: awx/main/models/credential/__init__.py:737
+#: awx/main/models/credential/__init__.py:745
msgid "Authorize Password"
msgstr "パスワードの承認"
-#: awx/main/models/credential/__init__.py:751
+#: awx/main/models/credential/__init__.py:759
msgid "Amazon Web Services"
msgstr "Amazon Web Services"
-#: awx/main/models/credential/__init__.py:756
+#: awx/main/models/credential/__init__.py:764
msgid "Access Key"
msgstr "アクセスキー"
-#: awx/main/models/credential/__init__.py:760
+#: awx/main/models/credential/__init__.py:768
msgid "Secret Key"
msgstr "シークレットキー"
-#: awx/main/models/credential/__init__.py:765
+#: awx/main/models/credential/__init__.py:773
msgid "STS Token"
msgstr "STS トークン"
-#: awx/main/models/credential/__init__.py:768
+#: awx/main/models/credential/__init__.py:776
msgid ""
"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."
msgstr "セキュリティートークンサービス (STS) は、AWS Identity and Access Management (IAM) ユーザーの一時的な、権限の制限された認証情報を要求できる web サービスです。"
-#: awx/main/models/credential/__init__.py:780 awx/main/models/inventory.py:833
+#: awx/main/models/credential/__init__.py:788 awx/main/models/inventory.py:826
msgid "OpenStack"
msgstr "OpenStack"
-#: awx/main/models/credential/__init__.py:789
+#: awx/main/models/credential/__init__.py:797
msgid "Password (API Key)"
msgstr "パスワード (API キー)"
-#: awx/main/models/credential/__init__.py:794
-#: awx/main/models/credential/__init__.py:1046
+#: awx/main/models/credential/__init__.py:802
+#: awx/main/models/credential/__init__.py:1058
msgid "Host (Authentication URL)"
msgstr "ホスト (認証 URL)"
-#: awx/main/models/credential/__init__.py:796
+#: awx/main/models/credential/__init__.py:804
msgid ""
"The host to authenticate with. For example, https://openstack.business.com/"
"v2.0/"
msgstr "認証に使用するホスト。例: https://openstack.business.com/v2.0/"
-#: awx/main/models/credential/__init__.py:800
+#: awx/main/models/credential/__init__.py:808
msgid "Project (Tenant Name)"
msgstr "プロジェクト (テナント名)"
-#: awx/main/models/credential/__init__.py:804
+#: awx/main/models/credential/__init__.py:812
+msgid "Project (Domain Name)"
+msgstr "プロジェクト (ドメイン名)"
+
+#: awx/main/models/credential/__init__.py:816
msgid "Domain Name"
msgstr "ドメイン名"
-#: awx/main/models/credential/__init__.py:806
+#: awx/main/models/credential/__init__.py:818
msgid ""
"OpenStack domains define administrative boundaries. It is only needed for "
"Keystone v3 authentication URLs. Refer to Ansible Tower documentation for "
"common scenarios."
msgstr "OpenStack ドメインは管理上の境界を定義します。これは Keystone v3 認証 URL にのみ必要です。共通するシナリオについては Ansible Tower ドキュメントを参照してください。"
-#: awx/main/models/credential/__init__.py:812
-#: awx/main/models/credential/__init__.py:1110
-#: awx/main/models/credential/__init__.py:1144
+#: awx/main/models/credential/__init__.py:824
+#: awx/main/models/credential/__init__.py:1131
+#: awx/main/models/credential/__init__.py:1166
msgid "Verify SSL"
msgstr "SSL の検証"
-#: awx/main/models/credential/__init__.py:823 awx/main/models/inventory.py:830
+#: awx/main/models/credential/__init__.py:835 awx/main/models/inventory.py:824
msgid "VMware vCenter"
msgstr "VMware vCenter"
-#: awx/main/models/credential/__init__.py:828
+#: awx/main/models/credential/__init__.py:840
msgid "VCenter Host"
msgstr "vCenter ホスト"
-#: awx/main/models/credential/__init__.py:830
+#: awx/main/models/credential/__init__.py:842
msgid ""
"Enter the hostname or IP address that corresponds to your VMware vCenter."
msgstr "VMware vCenter に対応するホスト名または IP アドレスを入力します。"
-#: awx/main/models/credential/__init__.py:849 awx/main/models/inventory.py:831
+#: awx/main/models/credential/__init__.py:861 awx/main/models/inventory.py:825
msgid "Red Hat Satellite 6"
msgstr "Red Hat Satellite 6"
-#: awx/main/models/credential/__init__.py:854
+#: awx/main/models/credential/__init__.py:866
msgid "Satellite 6 URL"
msgstr "Satellite 6 URL"
-#: awx/main/models/credential/__init__.py:856
+#: awx/main/models/credential/__init__.py:868
msgid ""
"Enter the URL that corresponds to your Red Hat Satellite 6 server. For "
"example, https://satellite.example.org"
msgstr "Red Hat Satellite 6 Server に対応する URL を入力します (例: https://satellite.example.org)。"
-#: awx/main/models/credential/__init__.py:875 awx/main/models/inventory.py:832
+#: awx/main/models/credential/__init__.py:887
msgid "Red Hat CloudForms"
msgstr "Red Hat CloudForms"
-#: awx/main/models/credential/__init__.py:880
+#: awx/main/models/credential/__init__.py:892
msgid "CloudForms URL"
msgstr "CloudForms URL"
-#: awx/main/models/credential/__init__.py:882
+#: awx/main/models/credential/__init__.py:894
msgid ""
"Enter the URL for the virtual machine that corresponds to your CloudForms "
"instance. For example, https://cloudforms.example.org"
msgstr "CloudForms インスタンスに対応する仮想マシンの URL を入力します (例: https://cloudforms.example.org)。"
-#: awx/main/models/credential/__init__.py:902 awx/main/models/inventory.py:828
+#: awx/main/models/credential/__init__.py:914 awx/main/models/inventory.py:822
msgid "Google Compute Engine"
msgstr "Google Compute Engine"
-#: awx/main/models/credential/__init__.py:907
+#: awx/main/models/credential/__init__.py:919
msgid "Service Account Email Address"
msgstr "サービスアカウントのメールアドレス"
-#: awx/main/models/credential/__init__.py:909
+#: awx/main/models/credential/__init__.py:921
msgid ""
"The email address assigned to the Google Compute Engine service account."
msgstr "Google Compute Engine サービスアカウントに割り当てられたメールアドレス。"
-#: awx/main/models/credential/__init__.py:915
+#: awx/main/models/credential/__init__.py:927
msgid ""
"The Project ID is the GCE assigned identification. It is often constructed "
"as three words or two words followed by a three-digit number. Examples: "
"project-id-000 and another-project-id"
msgstr "プロジェクト ID は GCE によって割り当てられる識別情報です。これは 3 語か、または 2 語とそれに続く 3 桁の数字のいずれかで構成されます。例: project-id-000、another-project-id"
-#: awx/main/models/credential/__init__.py:921
+#: awx/main/models/credential/__init__.py:933
msgid "RSA Private Key"
msgstr "RSA 秘密鍵"
-#: awx/main/models/credential/__init__.py:926
+#: awx/main/models/credential/__init__.py:938
msgid ""
"Paste the contents of the PEM file associated with the service account email."
msgstr "サービスアカウントメールに関連付けられた PEM ファイルの内容を貼り付けます。"
-#: awx/main/models/credential/__init__.py:936 awx/main/models/inventory.py:829
+#: awx/main/models/credential/__init__.py:948 awx/main/models/inventory.py:823
msgid "Microsoft Azure Resource Manager"
msgstr "Microsoft Azure Resource Manager"
-#: awx/main/models/credential/__init__.py:941
+#: awx/main/models/credential/__init__.py:953
msgid "Subscription ID"
msgstr "サブスクリプション ID"
-#: awx/main/models/credential/__init__.py:943
+#: awx/main/models/credential/__init__.py:955
msgid "Subscription ID is an Azure construct, which is mapped to a username."
msgstr "サブスクリプション ID は、ユーザー名にマップされる Azure コンストラクトです。"
-#: awx/main/models/credential/__init__.py:969
+#: awx/main/models/credential/__init__.py:981
msgid "Azure Cloud Environment"
msgstr "Azure クラウド環境"
-#: awx/main/models/credential/__init__.py:971
+#: awx/main/models/credential/__init__.py:983
msgid ""
"Environment variable AZURE_CLOUD_ENVIRONMENT when using Azure GovCloud or "
"Azure stack."
msgstr "Azure GovCloud または Azure スタック使用時の環境変数 AZURE_CLOUD_ENVIRONMENT。"
-#: awx/main/models/credential/__init__.py:981
+#: awx/main/models/credential/__init__.py:993
msgid "GitHub Personal Access Token"
msgstr "GitHub パーソナルアクセストークン"
-#: awx/main/models/credential/__init__.py:989
+#: awx/main/models/credential/__init__.py:1001
msgid "This token needs to come from your profile settings in GitHub"
msgstr "このトークンは GitHub のプロファイル設定から取得する必要があります。"
-#: awx/main/models/credential/__init__.py:998
+#: awx/main/models/credential/__init__.py:1010
msgid "GitLab Personal Access Token"
msgstr "GitLab パーソナルアクセストークン"
-#: awx/main/models/credential/__init__.py:1006
+#: awx/main/models/credential/__init__.py:1018
msgid "This token needs to come from your profile settings in GitLab"
msgstr "このトークンは GitLab のプロファイル設定から取得する必要があります。"
-#: awx/main/models/credential/__init__.py:1041 awx/main/models/inventory.py:834
+#: awx/main/models/credential/__init__.py:1053 awx/main/models/inventory.py:827
msgid "Red Hat Virtualization"
msgstr "Red Hat Virtualization"
-#: awx/main/models/credential/__init__.py:1048
+#: awx/main/models/credential/__init__.py:1060
msgid "The host to authenticate with."
msgstr "認証するホスト。"
-#: awx/main/models/credential/__init__.py:1060
+#: awx/main/models/credential/__init__.py:1072
msgid "CA File"
msgstr "CA ファイル"
-#: awx/main/models/credential/__init__.py:1062
+#: awx/main/models/credential/__init__.py:1074
msgid "Absolute file path to the CA file to use (optional)"
msgstr "使用する CA ファイルへの絶対ファイルパス (オプション)"
-#: awx/main/models/credential/__init__.py:1091 awx/main/models/inventory.py:835
+#: awx/main/models/credential/__init__.py:1103 awx/main/models/inventory.py:828
msgid "Ansible Tower"
msgstr "Ansible Tower"
-#: awx/main/models/credential/__init__.py:1096
+#: awx/main/models/credential/__init__.py:1108
msgid "Ansible Tower Hostname"
msgstr "Ansible Tower ホスト名"
-#: awx/main/models/credential/__init__.py:1098
+#: awx/main/models/credential/__init__.py:1110
msgid "The Ansible Tower base URL to authenticate with."
msgstr "認証で使用する Ansible Tower ベース URL。"
-#: awx/main/models/credential/__init__.py:1130
+#: awx/main/models/credential/__init__.py:1115
+msgid ""
+"The Ansible Tower user to authenticate as.This should not be set if an OAuth "
+"token is being used."
+msgstr "認証する AnsibleTower ユーザー。OAuth トークンが使用されている場合は、これを設定しないでください。"
+
+#: awx/main/models/credential/__init__.py:1124
+msgid "OAuth Token"
+msgstr "OAuth トークン"
+
+#: awx/main/models/credential/__init__.py:1127
+msgid ""
+"An OAuth token to use to authenticate to Tower with.This should not be set "
+"if username/password are being used."
+msgstr "Tower への認証に使用する OAuth トークン。ユーザー名/パスワードが使用されている場合は設定しないでください。"
+
+#: awx/main/models/credential/__init__.py:1152
msgid "OpenShift or Kubernetes API Bearer Token"
msgstr "OpenShift または Kubernetes API Bearer トークン"
-#: awx/main/models/credential/__init__.py:1134
+#: awx/main/models/credential/__init__.py:1156
msgid "OpenShift or Kubernetes API Endpoint"
msgstr "OpenShift または Kubernetes API エンドポイント"
-#: awx/main/models/credential/__init__.py:1136
+#: awx/main/models/credential/__init__.py:1158
msgid "The OpenShift or Kubernetes API Endpoint to authenticate with."
msgstr "認証する OpenShift または Kubernetes API エンドポイント。"
-#: awx/main/models/credential/__init__.py:1139
+#: awx/main/models/credential/__init__.py:1161
msgid "API authentication bearer token"
msgstr "API 認証ベアラートークン"
-#: awx/main/models/credential/__init__.py:1149
+#: awx/main/models/credential/__init__.py:1171
msgid "Certificate Authority data"
msgstr "認証局データ"
+#: awx/main/models/credential/__init__.py:1184
+msgid "Ansible Galaxy/Automation Hub API Token"
+msgstr "Ansible Galaxy/Automation Hub API トークン"
+
+#: awx/main/models/credential/__init__.py:1188
+msgid "Galaxy Server URL"
+msgstr "Galaxy Server URL"
+
#: awx/main/models/credential/__init__.py:1190
+msgid "The URL of the Galaxy instance to connect to."
+msgstr "接続する Galaxy インスタンスの URL。"
+
+#: awx/main/models/credential/__init__.py:1193
+msgid "Auth Server URL"
+msgstr "認証サーバー URL"
+
+#: awx/main/models/credential/__init__.py:1196
+msgid "The URL of a Keycloak server token_endpoint, if using SSO auth."
+msgstr "SSO 認証を使用している場合は、Keycloak サーバー token_endpoint の URL。"
+
+#: awx/main/models/credential/__init__.py:1201
+msgid "API Token"
+msgstr "API トークン"
+
+#: awx/main/models/credential/__init__.py:1205
+msgid "A token to use for authentication against the Galaxy instance."
+msgstr "Galaxy インスタンスに対する認証に使用するトークン。"
+
+#: awx/main/models/credential/__init__.py:1244
msgid "Target must be a non-external credential"
msgstr "ターゲットには、外部の認証情報以外を使用してください。"
-#: awx/main/models/credential/__init__.py:1195
+#: awx/main/models/credential/__init__.py:1249
msgid "Source must be an external credential"
msgstr "ソースは、外部の認証情報でなければなりません。"
-#: awx/main/models/credential/__init__.py:1202
+#: awx/main/models/credential/__init__.py:1256
msgid "Input field must be defined on target credential (options are {})."
msgstr "入力フィールドは、ターゲットの認証情報 (オプションは {}) で定義する必要があります。"
-#: awx/main/models/events.py:152 awx/main/models/events.py:674
+#: awx/main/models/events.py:165 awx/main/models/events.py:707
msgid "Host Failed"
msgstr "ホストの失敗"
-#: awx/main/models/events.py:153
+#: awx/main/models/events.py:166
msgid "Host Started"
msgstr "ホストの開始"
-#: awx/main/models/events.py:154 awx/main/models/events.py:675
+#: awx/main/models/events.py:167 awx/main/models/events.py:708
msgid "Host OK"
msgstr "ホスト OK"
-#: awx/main/models/events.py:155
+#: awx/main/models/events.py:168
msgid "Host Failure"
msgstr "ホストの失敗"
-#: awx/main/models/events.py:156 awx/main/models/events.py:681
+#: awx/main/models/events.py:169 awx/main/models/events.py:714
msgid "Host Skipped"
msgstr "ホストがスキップされました"
-#: awx/main/models/events.py:157 awx/main/models/events.py:676
+#: awx/main/models/events.py:170 awx/main/models/events.py:709
msgid "Host Unreachable"
msgstr "ホストに到達できません"
-#: awx/main/models/events.py:158 awx/main/models/events.py:172
+#: awx/main/models/events.py:171 awx/main/models/events.py:185
msgid "No Hosts Remaining"
msgstr "残りのホストがありません"
-#: awx/main/models/events.py:159
+#: awx/main/models/events.py:172
msgid "Host Polling"
msgstr "ホストのポーリング"
-#: awx/main/models/events.py:160
+#: awx/main/models/events.py:173
msgid "Host Async OK"
msgstr "ホストの非同期 OK"
-#: awx/main/models/events.py:161
+#: awx/main/models/events.py:174
msgid "Host Async Failure"
msgstr "ホストの非同期失敗"
-#: awx/main/models/events.py:162
+#: awx/main/models/events.py:175
msgid "Item OK"
msgstr "項目 OK"
-#: awx/main/models/events.py:163
+#: awx/main/models/events.py:176
msgid "Item Failed"
msgstr "項目の失敗"
-#: awx/main/models/events.py:164
+#: awx/main/models/events.py:177
msgid "Item Skipped"
msgstr "項目のスキップ"
-#: awx/main/models/events.py:165
+#: awx/main/models/events.py:178
msgid "Host Retry"
msgstr "ホストの再試行"
-#: awx/main/models/events.py:167
+#: awx/main/models/events.py:180
msgid "File Difference"
msgstr "ファイルの相違点"
-#: awx/main/models/events.py:168
+#: awx/main/models/events.py:181
msgid "Playbook Started"
msgstr "Playbook の開始"
-#: awx/main/models/events.py:169
+#: awx/main/models/events.py:182
msgid "Running Handlers"
msgstr "実行中のハンドラー"
-#: awx/main/models/events.py:170
+#: awx/main/models/events.py:183
msgid "Including File"
msgstr "組み込みファイル"
-#: awx/main/models/events.py:171
+#: awx/main/models/events.py:184
msgid "No Hosts Matched"
msgstr "一致するホストがありません"
-#: awx/main/models/events.py:173
+#: awx/main/models/events.py:186
msgid "Task Started"
msgstr "タスクの開始"
-#: awx/main/models/events.py:175
+#: awx/main/models/events.py:188
msgid "Variables Prompted"
msgstr "変数のプロモート"
-#: awx/main/models/events.py:176
+#: awx/main/models/events.py:189
msgid "Gathering Facts"
msgstr "ファクトの収集"
-#: awx/main/models/events.py:177
+#: awx/main/models/events.py:190
msgid "internal: on Import for Host"
msgstr "内部: ホストのインポート時"
-#: awx/main/models/events.py:178
+#: awx/main/models/events.py:191
msgid "internal: on Not Import for Host"
msgstr "内部: ホストの非インポート時"
-#: awx/main/models/events.py:179
+#: awx/main/models/events.py:192
msgid "Play Started"
msgstr "プレイの開始"
-#: awx/main/models/events.py:180
+#: awx/main/models/events.py:193
msgid "Playbook Complete"
msgstr "Playbook の完了"
-#: awx/main/models/events.py:184 awx/main/models/events.py:691
+#: awx/main/models/events.py:197 awx/main/models/events.py:724
msgid "Debug"
msgstr "デバッグ"
-#: awx/main/models/events.py:185 awx/main/models/events.py:692
+#: awx/main/models/events.py:198 awx/main/models/events.py:725
msgid "Verbose"
msgstr "詳細"
-#: awx/main/models/events.py:186 awx/main/models/events.py:693
+#: awx/main/models/events.py:199 awx/main/models/events.py:726
msgid "Deprecated"
msgstr "非推奨"
-#: awx/main/models/events.py:187 awx/main/models/events.py:694
+#: awx/main/models/events.py:200 awx/main/models/events.py:727
msgid "Warning"
msgstr "警告"
-#: awx/main/models/events.py:188 awx/main/models/events.py:695
+#: awx/main/models/events.py:201 awx/main/models/events.py:728
msgid "System Warning"
msgstr "システム警告"
-#: awx/main/models/events.py:189 awx/main/models/events.py:696
+#: awx/main/models/events.py:202 awx/main/models/events.py:729
#: awx/main/models/unified_jobs.py:75
msgid "Error"
msgstr "エラー"
-#: awx/main/models/ha.py:175
+#: awx/main/models/ha.py:184
msgid "Instances that are members of this InstanceGroup"
msgstr "このインスタンスグループのメンバーであるインスタンス"
-#: awx/main/models/ha.py:180
+#: awx/main/models/ha.py:189
msgid "Instance Group to remotely control this group."
msgstr "このグループをリモートで制御するためのインスタンスグループ"
-#: awx/main/models/ha.py:200
+#: awx/main/models/ha.py:209
msgid "Percentage of Instances to automatically assign to this group"
msgstr "このグループに自動的に割り当てるインスタンスの割合"
-#: awx/main/models/ha.py:204
+#: awx/main/models/ha.py:213
msgid ""
"Static minimum number of Instances to automatically assign to this group"
msgstr "このグループに自動的に割り当てるインスタンスの静的な最小数。"
-#: awx/main/models/ha.py:209
+#: awx/main/models/ha.py:218
msgid ""
"List of exact-match Instances that will always be automatically assigned to "
"this group"
msgstr "このグループに常に自動的に割り当てられる完全一致のインスタンスの一覧"
-#: awx/main/models/inventory.py:80
+#: awx/main/models/inventory.py:74
msgid "Hosts have a direct link to this inventory."
msgstr "ホストにはこのインベントリーへの直接のリンクがあります。"
-#: awx/main/models/inventory.py:81
+#: awx/main/models/inventory.py:75
msgid "Hosts for inventory generated using the host_filter property."
msgstr "host_filter プロパティーを使用して生成されたインベントリーのホスト。"
-#: awx/main/models/inventory.py:86
+#: awx/main/models/inventory.py:80
msgid "inventories"
msgstr "インベントリー"
-#: awx/main/models/inventory.py:93
+#: awx/main/models/inventory.py:87
msgid "Organization containing this inventory."
msgstr "このインベントリーを含む組織。"
-#: awx/main/models/inventory.py:100
+#: awx/main/models/inventory.py:94
msgid "Inventory variables in JSON or YAML format."
msgstr "JSON または YAML 形式のインベントリー変数。"
-#: awx/main/models/inventory.py:105
+#: awx/main/models/inventory.py:99
msgid ""
"This field is deprecated and will be removed in a future release. Flag "
"indicating whether any hosts in this inventory have failed."
msgstr "このフィールドは非推奨で、今後のリリースで削除予定です。このインベントリーのホストが失敗したかどうかを示すフラグ。"
-#: awx/main/models/inventory.py:111
+#: awx/main/models/inventory.py:105
msgid ""
"This field is deprecated and will be removed in a future release. Total "
"number of hosts in this inventory."
msgstr "このフィールドは非推奨で、今後のリリースで削除予定です。このインベントリーでの合計ホスト数。"
-#: awx/main/models/inventory.py:117
+#: awx/main/models/inventory.py:111
msgid ""
"This field is deprecated and will be removed in a future release. Number of "
"hosts in this inventory with active failures."
msgstr "このフィールドは非推奨で、今後のリリースで削除予定です。このインベントリーで障害が発生中のホスト数。"
-#: awx/main/models/inventory.py:123
+#: awx/main/models/inventory.py:117
msgid ""
"This field is deprecated and will be removed in a future release. Total "
"number of groups in this inventory."
msgstr "このフィールドは非推奨で、今後のリリースで削除予定です。このインベントリーでの合計グループ数。"
-#: awx/main/models/inventory.py:129
+#: awx/main/models/inventory.py:123
msgid ""
"This field is deprecated and will be removed in a future release. Flag "
"indicating whether this inventory has any external inventory sources."
msgstr "このフィールドは非推奨で、今後のリリースで削除予定です。このインベントリーに外部のインベントリーソースがあるかどうかを示すフラグ。"
-#: awx/main/models/inventory.py:135
+#: awx/main/models/inventory.py:129
msgid ""
"Total number of external inventory sources configured within this inventory."
msgstr "このインベントリー内で設定される外部インベントリーソースの合計数。"
-#: awx/main/models/inventory.py:140
+#: awx/main/models/inventory.py:134
msgid "Number of external inventory sources in this inventory with failures."
msgstr "エラーのあるこのインベントリー内の外部インベントリーソースの数。"
-#: awx/main/models/inventory.py:147
+#: awx/main/models/inventory.py:141
msgid "Kind of inventory being represented."
msgstr "表示されているインベントリーの種類。"
-#: awx/main/models/inventory.py:153
+#: awx/main/models/inventory.py:147
msgid "Filter that will be applied to the hosts of this inventory."
msgstr "このインべントリーのホストに適用されるフィルター。"
-#: awx/main/models/inventory.py:181
+#: awx/main/models/inventory.py:175
msgid ""
"Credentials to be used by hosts belonging to this inventory when accessing "
"Red Hat Insights API."
msgstr "Red Hat Insights API へのアクセス時にこのインベントリーに属するホストによって使用される認証情報。"
-#: awx/main/models/inventory.py:190
+#: awx/main/models/inventory.py:184
msgid "Flag indicating the inventory is being deleted."
msgstr "このインベントリーが削除されていることを示すフラグ。"
-#: awx/main/models/inventory.py:245
+#: awx/main/models/inventory.py:239
msgid "Could not parse subset as slice specification."
msgstr "サブセットをスライスの詳細として解析できませんでした。"
-#: awx/main/models/inventory.py:249
+#: awx/main/models/inventory.py:243
msgid "Slice number must be less than total number of slices."
msgstr "スライス番号はスライスの合計数より小さくなければなりません。"
-#: awx/main/models/inventory.py:251
+#: awx/main/models/inventory.py:245
msgid "Slice number must be 1 or higher."
msgstr "スライス番号は 1 以上でなければなりません。"
-#: awx/main/models/inventory.py:388
+#: awx/main/models/inventory.py:382
msgid "Assignment not allowed for Smart Inventory"
msgstr "割り当てはスマートインベントリーでは許可されません"
-#: awx/main/models/inventory.py:390 awx/main/models/projects.py:166
+#: awx/main/models/inventory.py:384 awx/main/models/projects.py:167
msgid "Credential kind must be 'insights'."
msgstr "認証情報の種類は「insights」である必要があります。"
-#: awx/main/models/inventory.py:475
+#: awx/main/models/inventory.py:469
msgid "Is this host online and available for running jobs?"
msgstr "このホストはオンラインで、ジョブを実行するために利用できますか?"
-#: awx/main/models/inventory.py:481
+#: awx/main/models/inventory.py:475
msgid ""
"The value used by the remote inventory source to uniquely identify the host"
msgstr "ホストを一意に識別するためにリモートインベントリーソースで使用される値"
-#: awx/main/models/inventory.py:486
+#: awx/main/models/inventory.py:480
msgid "Host variables in JSON or YAML format."
msgstr "JSON または YAML 形式のホスト変数。"
-#: awx/main/models/inventory.py:509
+#: awx/main/models/inventory.py:503
msgid "Inventory source(s) that created or modified this host."
msgstr "このホストを作成または変更したインベントリーソース。"
-#: awx/main/models/inventory.py:514
+#: awx/main/models/inventory.py:508
msgid "Arbitrary JSON structure of most recent ansible_facts, per-host."
msgstr "ホスト別の最新 ansible_facts の任意の JSON 構造。"
-#: awx/main/models/inventory.py:520
+#: awx/main/models/inventory.py:514
msgid "The date and time ansible_facts was last modified."
msgstr "ansible_facts の最終変更日時。"
-#: awx/main/models/inventory.py:527
+#: awx/main/models/inventory.py:521
msgid "Red Hat Insights host unique identifier."
msgstr "Red Hat Insights ホスト固有 ID。"
-#: awx/main/models/inventory.py:641
+#: awx/main/models/inventory.py:635
msgid "Group variables in JSON or YAML format."
msgstr "JSON または YAML 形式のグループ変数。"
-#: awx/main/models/inventory.py:647
+#: awx/main/models/inventory.py:641
msgid "Hosts associated directly with this group."
msgstr "このグループに直接関連付けられたホスト。"
-#: awx/main/models/inventory.py:653
+#: awx/main/models/inventory.py:647
msgid "Inventory source(s) that created or modified this group."
msgstr "このグループを作成または変更したインベントリーソース。"
-#: awx/main/models/inventory.py:825
+#: awx/main/models/inventory.py:819
msgid "File, Directory or Script"
msgstr "ファイル、ディレクトリーまたはスクリプト"
-#: awx/main/models/inventory.py:826
+#: awx/main/models/inventory.py:820
msgid "Sourced from a Project"
msgstr "ソース: プロジェクト"
-#: awx/main/models/inventory.py:827
+#: awx/main/models/inventory.py:821
msgid "Amazon EC2"
msgstr "Amazon EC2"
-#: awx/main/models/inventory.py:836
+#: awx/main/models/inventory.py:829
msgid "Custom Script"
msgstr "カスタムスクリプト"
-#: awx/main/models/inventory.py:953
+#: awx/main/models/inventory.py:863
msgid "Inventory source variables in YAML or JSON format."
msgstr "YAML または JSON 形式のインベントリーソース変数。"
-#: awx/main/models/inventory.py:964
+#: awx/main/models/inventory.py:868
msgid ""
-"Comma-separated list of filter expressions (EC2 only). Hosts are imported "
-"when ANY of the filters match."
-msgstr "カンマ区切りのフィルター式の一覧 (EC2 のみ) です。ホストは、フィルターのいずれかが一致する場合にインポートされます。"
+"Retrieve the enabled state from the given dict of host variables. The "
+"enabled variable may be specified as \"foo.bar\", in which case the lookup "
+"will traverse into nested dicts, equivalent to: from_dict.get(\"foo\", {})."
+"get(\"bar\", default)"
+msgstr "ホスト変数の指定された辞書から有効な状態を取得します。有効な変数は「foo.bar」として指定できます。その場合、ルックアップはネストされた辞書に移動します。これは、from_dict.get(\"foo\", {}).get(\"bar\", default) と同等です。"
-#: awx/main/models/inventory.py:970
-msgid "Limit groups automatically created from inventory source (EC2 only)."
-msgstr "インベントリーソースから自動的に作成されるグループを制限します (EC2 のみ)。"
+#: awx/main/models/inventory.py:876
+msgid ""
+"Only used when enabled_var is set. Value when the host is considered "
+"enabled. For example if enabled_var=\"status.power_state\"and enabled_value="
+"\"powered_on\" with host variables:{ \"status\": { \"power_state\": "
+"\"powered_on\", \"created\": \"2020-08-04T18:13:04+00:00\", \"healthy"
+"\": true }, \"name\": \"foobar\", \"ip_address\": \"192.168.2.1\"}"
+"The host would be marked enabled. If power_state where any value other than "
+"powered_on then the host would be disabled when imported into Tower. If the "
+"key is not found then the host will be enabled"
+msgstr "enabled_var が設定されている場合にのみ使用されます。ホストが有効と見なされる場合の値です。たとえば、ホスト変数 { \"status\": { \"power_state\": \"powered_on\", \"created\": \"2020-08-04T18:13:04+00:00\", \"healthy\": true }, \"name\": \"foobar\", \"ip_address\": \"192.168.2.1\"} を使用した enabled_var=\"status.power_state\" および enabled_value=\"powered_on\" の場合は、ホストは有効とマークされます。powered_on 以外の値が power_state の場合は、Tower にインポートするとホストは無効になります。キーが見つからない場合は、ホストが有効になります"
-#: awx/main/models/inventory.py:974
+#: awx/main/models/inventory.py:896
+msgid "Regex where only matching hosts will be imported into Tower."
+msgstr "一致するホストのみが Tower にインポートされる正規表現。"
+
+#: awx/main/models/inventory.py:900
msgid "Overwrite local groups and hosts from remote inventory source."
msgstr "リモートインベントリーソースからのローカルグループおよびホストを上書きします。"
-#: awx/main/models/inventory.py:978
+#: awx/main/models/inventory.py:904
msgid "Overwrite local variables from remote inventory source."
msgstr "リモートインベントリーソースからのローカル変数を上書きします。"
-#: awx/main/models/inventory.py:983 awx/main/models/jobs.py:154
-#: awx/main/models/projects.py:135
+#: awx/main/models/inventory.py:909 awx/main/models/jobs.py:154
+#: awx/main/models/projects.py:136
msgid "The amount of time (in seconds) to run before the task is canceled."
msgstr "タスクが取り消される前の実行時間 (秒数)。"
-#: awx/main/models/inventory.py:1016
-msgid "Image ID"
-msgstr "イメージ ID"
-
-#: awx/main/models/inventory.py:1017
-msgid "Availability Zone"
-msgstr "アベイラビリティーゾーン"
-
-#: awx/main/models/inventory.py:1019
-msgid "Instance ID"
-msgstr "インスタンス ID"
-
-#: awx/main/models/inventory.py:1020
-msgid "Instance State"
-msgstr "インスタンスの状態"
-
-#: awx/main/models/inventory.py:1021
-msgid "Platform"
-msgstr "プラットフォーム"
-
-#: awx/main/models/inventory.py:1022
-msgid "Instance Type"
-msgstr "インスタンスタイプ"
-
-#: awx/main/models/inventory.py:1024
-msgid "Region"
-msgstr "リージョン"
-
-#: awx/main/models/inventory.py:1025
-msgid "Security Group"
-msgstr "セキュリティーグループ"
-
-#: awx/main/models/inventory.py:1026
-msgid "Tags"
-msgstr "タグ"
-
-#: awx/main/models/inventory.py:1027
-msgid "Tag None"
-msgstr "タグ None"
-
-#: awx/main/models/inventory.py:1028
-msgid "VPC ID"
-msgstr "VPC ID"
-
-#: awx/main/models/inventory.py:1096
+#: awx/main/models/inventory.py:926
#, python-format
msgid ""
"Cloud-based inventory sources (such as %s) require credentials for the "
"matching cloud service."
msgstr "クラウドベースのインベントリーソース (%s など) には一致するクラウドサービスの認証情報が必要です。"
-#: awx/main/models/inventory.py:1102
+#: awx/main/models/inventory.py:932
msgid "Credential is required for a cloud source."
msgstr "認証情報がクラウドソースに必要です。"
-#: awx/main/models/inventory.py:1105
+#: awx/main/models/inventory.py:935
msgid ""
"Credentials of type machine, source control, insights and vault are "
"disallowed for custom inventory sources."
msgstr "タイプがマシン、ソースコントロール、Insights および Vault の認証情報はカスタムインベントリーソースには許可されません。"
-#: awx/main/models/inventory.py:1110
+#: awx/main/models/inventory.py:940
msgid ""
"Credentials of type insights and vault are disallowed for scm inventory "
"sources."
msgstr "タイプが Insights および Vault の認証情報は SCM のインベントリーソースには許可されません。"
-#: awx/main/models/inventory.py:1170
-#, python-format
-msgid "Invalid %(source)s region: %(region)s"
-msgstr "無効な %(source)s リージョン: %(region)s"
-
-#: awx/main/models/inventory.py:1194
-#, python-format
-msgid "Invalid filter expression: %(filter)s"
-msgstr "無効なフィルター式: %(filter)s"
-
-#: awx/main/models/inventory.py:1215
-#, python-format
-msgid "Invalid group by choice: %(choice)s"
-msgstr "無効なグループ (選択による): %(choice)s"
-
-#: awx/main/models/inventory.py:1243
+#: awx/main/models/inventory.py:1004
msgid "Project containing inventory file used as source."
msgstr "ソースとして使用されるインベントリーファイルが含まれるプロジェクト。"
-#: awx/main/models/inventory.py:1416
+#: awx/main/models/inventory.py:1177
msgid ""
"More than one SCM-based inventory source with update on project update per-"
"inventory not allowed."
msgstr "複数の SCM ベースのインベントリーソースについて、インベントリー別のプロジェクト更新時の更新は許可されません。"
-#: awx/main/models/inventory.py:1423
+#: awx/main/models/inventory.py:1184
msgid ""
"Cannot update SCM-based inventory source on launch if set to update on "
"project update. Instead, configure the corresponding source project to "
"update on launch."
msgstr "プロジェクト更新時の更新に設定している場合、SCM ベースのインベントリーソースを更新できません。その代わりに起動時に更新するように対応するソースプロジェクトを設定します。"
-#: awx/main/models/inventory.py:1429
+#: awx/main/models/inventory.py:1190
msgid "Cannot set source_path if not SCM type."
msgstr "SCM タイプでない場合 source_path を設定できません。"
-#: awx/main/models/inventory.py:1472
+#: awx/main/models/inventory.py:1233
msgid ""
"Inventory files from this Project Update were used for the inventory update."
msgstr "このプロジェクト更新のインベントリーファイルがインベントリー更新に使用されました。"
-#: awx/main/models/inventory.py:1583
+#: awx/main/models/inventory.py:1344
msgid "Inventory script contents"
msgstr "インベントリースクリプトの内容"
-#: awx/main/models/inventory.py:1588
+#: awx/main/models/inventory.py:1349
msgid "Organization owning this inventory script"
msgstr "このインベントリースクリプトを所有する組織"
@@ -3949,89 +4008,89 @@ msgstr "ジョブテンプレートは「inventory」を指定するか、この
msgid "Maximum number of forks ({settings.MAX_FORKS}) exceeded."
msgstr "フォームの最大数 ({settings.MAX_FORKS}) を超えました。"
-#: awx/main/models/jobs.py:463
+#: awx/main/models/jobs.py:459
msgid "Project is missing."
msgstr "プロジェクトがありません。"
-#: awx/main/models/jobs.py:467
+#: awx/main/models/jobs.py:463
msgid "Project does not allow override of branch."
msgstr "プロジェクトではブランチの上書きはできません。"
-#: awx/main/models/jobs.py:477 awx/main/models/workflow.py:545
+#: awx/main/models/jobs.py:473 awx/main/models/workflow.py:545
msgid "Field is not configured to prompt on launch."
msgstr "フィールドは起動時にプロンプトを出すよう設定されていません。"
-#: awx/main/models/jobs.py:483
+#: awx/main/models/jobs.py:479
msgid "Saved launch configurations cannot provide passwords needed to start."
msgstr "保存された起動設定は、開始に必要なパスワードを提供しません。"
-#: awx/main/models/jobs.py:491
+#: awx/main/models/jobs.py:487
msgid "Job Template {} is missing or undefined."
msgstr "ジョブテンプレート {} が見つからないか、または定義されていません。"
-#: awx/main/models/jobs.py:574 awx/main/models/projects.py:278
-#: awx/main/models/projects.py:497
+#: awx/main/models/jobs.py:570 awx/main/models/projects.py:284
+#: awx/main/models/projects.py:508
msgid "SCM Revision"
msgstr "SCM リビジョン"
-#: awx/main/models/jobs.py:575
+#: awx/main/models/jobs.py:571
msgid "The SCM Revision from the Project used for this job, if available"
msgstr "このジョブに使用されるプロジェクトからの SCM リビジョン (ある場合)"
-#: awx/main/models/jobs.py:583
+#: awx/main/models/jobs.py:579
msgid ""
"The SCM Refresh task used to make sure the playbooks were available for the "
"job run"
msgstr "SCM 更新タスクは、Playbook がジョブの実行で利用可能であったことを確認するために使用されます"
-#: awx/main/models/jobs.py:588
+#: awx/main/models/jobs.py:584
msgid ""
"If part of a sliced job, the ID of the inventory slice operated on. If not "
"part of sliced job, parameter is not used."
msgstr "スライスされたジョブの一部の場合には、スライス処理が行われたインベントリーの ID です。スライスされたジョブの一部でなければ、パラメーターは使用されません。"
-#: awx/main/models/jobs.py:594
+#: awx/main/models/jobs.py:590
msgid ""
"If ran as part of sliced jobs, the total number of slices. If 1, job is not "
"part of a sliced job."
msgstr "スライスされたジョブの一部として実行された場合には、スライスの合計数です。1 であればジョブはスライスされたジョブの一部ではありません。"
-#: awx/main/models/jobs.py:676
+#: awx/main/models/jobs.py:672
#, python-brace-format
msgid "{status_value} is not a valid status option."
msgstr "{status_value} は、有効なステータスオプションではありません。"
-#: awx/main/models/jobs.py:926
+#: awx/main/models/jobs.py:922
msgid ""
"Inventory applied as a prompt, assuming job template prompts for inventory"
msgstr "インベントリーがプロンプトとして適用されると、ジョブテンプレートでインベントリーをプロンプトで要求することが前提となります。"
-#: awx/main/models/jobs.py:1085
+#: awx/main/models/jobs.py:1081
msgid "job host summaries"
msgstr "ジョブホストの概要"
-#: awx/main/models/jobs.py:1144
+#: awx/main/models/jobs.py:1140
msgid "Remove jobs older than a certain number of days"
msgstr "特定の日数より前のジョブを削除"
-#: awx/main/models/jobs.py:1145
+#: awx/main/models/jobs.py:1141
msgid "Remove activity stream entries older than a certain number of days"
msgstr "特定の日数より前のアクティビティーストリームのエントリーを削除"
-#: awx/main/models/jobs.py:1146
+#: awx/main/models/jobs.py:1142
msgid "Removes expired browser sessions from the database"
msgstr "期限切れブラウザーセッションをデータベースから削除"
-#: awx/main/models/jobs.py:1147
+#: awx/main/models/jobs.py:1143
msgid "Removes expired OAuth 2 access tokens and refresh tokens"
msgstr "期限切れの OAuth 2 アクセストークンを削除し、トークンを更新"
-#: awx/main/models/jobs.py:1217
+#: awx/main/models/jobs.py:1213
#, python-brace-format
msgid "Variables {list_of_keys} are not allowed for system jobs."
msgstr "システムジョブでは変数 {list_of_keys} を使用できません。"
-#: awx/main/models/jobs.py:1233
+#: awx/main/models/jobs.py:1229
msgid "days must be a positive integer."
msgstr "日数は正の整数である必要があります。"
@@ -4070,63 +4129,59 @@ msgstr "サービス API のステータスに戻すためのパーソナルア
msgid "Unique identifier of the event that triggered this webhook"
msgstr "この Webhook をトリガーしたイベントの一意識別子"
-#: awx/main/models/notifications.py:42
+#: awx/main/models/notifications.py:41
msgid "Email"
msgstr "メール"
-#: awx/main/models/notifications.py:43
+#: awx/main/models/notifications.py:42
msgid "Slack"
msgstr "Slack"
-#: awx/main/models/notifications.py:44
+#: awx/main/models/notifications.py:43
msgid "Twilio"
msgstr "Twilio"
-#: awx/main/models/notifications.py:45
+#: awx/main/models/notifications.py:44
msgid "Pagerduty"
msgstr "Pagerduty"
-#: awx/main/models/notifications.py:46
+#: awx/main/models/notifications.py:45
msgid "Grafana"
msgstr "Grafana"
-#: awx/main/models/notifications.py:47
-msgid "HipChat"
-msgstr "HipChat"
-
-#: awx/main/models/notifications.py:48 awx/main/models/unified_jobs.py:545
+#: awx/main/models/notifications.py:46 awx/main/models/unified_jobs.py:544
msgid "Webhook"
msgstr "Webhook"
-#: awx/main/models/notifications.py:49
+#: awx/main/models/notifications.py:47
msgid "Mattermost"
msgstr "Mattermost"
-#: awx/main/models/notifications.py:50
+#: awx/main/models/notifications.py:48
msgid "Rocket.Chat"
msgstr "Rocket.Chat"
-#: awx/main/models/notifications.py:51
+#: awx/main/models/notifications.py:49
msgid "IRC"
msgstr "IRC"
-#: awx/main/models/notifications.py:82
+#: awx/main/models/notifications.py:80
msgid "Optional custom messages for notification template."
msgstr "通知テンプレートのオプションのカスタムメッセージ"
-#: awx/main/models/notifications.py:212 awx/main/models/unified_jobs.py:70
+#: awx/main/models/notifications.py:210 awx/main/models/unified_jobs.py:70
msgid "Pending"
msgstr "保留中"
-#: awx/main/models/notifications.py:213 awx/main/models/unified_jobs.py:73
+#: awx/main/models/notifications.py:211 awx/main/models/unified_jobs.py:73
msgid "Successful"
msgstr "成功"
-#: awx/main/models/notifications.py:214 awx/main/models/unified_jobs.py:74
+#: awx/main/models/notifications.py:212 awx/main/models/unified_jobs.py:74
msgid "Failed"
msgstr "失敗"
-#: awx/main/models/notifications.py:467
+#: awx/main/models/notifications.py:466
msgid "status must be either running, succeeded or failed"
msgstr "ステータスは、実行中、成功、失敗のいずれかでなければなりません。"
@@ -4195,11 +4250,11 @@ msgid ""
"authentication provider ({})"
msgstr "OAuth2 トークンは、外部の認証プロバイダー ({}) に関連付けられたユーザーが作成することはできません。"
-#: awx/main/models/organization.py:51
+#: awx/main/models/organization.py:57
msgid "Maximum number of hosts allowed to be managed by this organization."
msgstr "この組織が管理可能な最大ホスト数"
-#: awx/main/models/projects.py:53 awx/main/models/unified_jobs.py:539
+#: awx/main/models/projects.py:53 awx/main/models/unified_jobs.py:538
msgid "Manual"
msgstr "手動"
@@ -4219,118 +4274,122 @@ msgstr "Subversion"
msgid "Red Hat Insights"
msgstr "Red Hat Insights"
-#: awx/main/models/projects.py:83
+#: awx/main/models/projects.py:58
+msgid "Remote Archive"
+msgstr "リモートアーカイブ"
+
+#: awx/main/models/projects.py:84
msgid ""
"Local path (relative to PROJECTS_ROOT) containing playbooks and related "
"files for this project."
msgstr "このプロジェクトの Playbook および関連するファイルを含むローカルパス (PROJECTS_ROOT との相対)。"
-#: awx/main/models/projects.py:92
+#: awx/main/models/projects.py:93
msgid "SCM Type"
msgstr "SCM タイプ"
-#: awx/main/models/projects.py:93
+#: awx/main/models/projects.py:94
msgid "Specifies the source control system used to store the project."
msgstr "プロジェクトを保存するために使用されるソースコントロールシステムを指定します。"
-#: awx/main/models/projects.py:99
+#: awx/main/models/projects.py:100
msgid "SCM URL"
msgstr "SCM URL"
-#: awx/main/models/projects.py:100
+#: awx/main/models/projects.py:101
msgid "The location where the project is stored."
msgstr "プロジェクトが保存される場所。"
-#: awx/main/models/projects.py:106
+#: awx/main/models/projects.py:107
msgid "SCM Branch"
msgstr "SCM ブランチ"
-#: awx/main/models/projects.py:107
+#: awx/main/models/projects.py:108
msgid "Specific branch, tag or commit to checkout."
msgstr "チェックアウトする特定のブランチ、タグまたはコミット。"
-#: awx/main/models/projects.py:113
+#: awx/main/models/projects.py:114
msgid "SCM refspec"
msgstr "SCM refspec"
-#: awx/main/models/projects.py:114
+#: awx/main/models/projects.py:115
msgid "For git projects, an additional refspec to fetch."
msgstr "git プロジェクトについては、追加の refspec を使用して取得します。"
-#: awx/main/models/projects.py:118
+#: awx/main/models/projects.py:119
msgid "Discard any local changes before syncing the project."
msgstr "ローカル変更を破棄してからプロジェクトを同期します。"
-#: awx/main/models/projects.py:122
+#: awx/main/models/projects.py:123
msgid "Delete the project before syncing."
msgstr "プロジェクトを削除してから同期します。"
-#: awx/main/models/projects.py:151
+#: awx/main/models/projects.py:152
msgid "Invalid SCM URL."
msgstr "無効な SCM URL。"
-#: awx/main/models/projects.py:154
+#: awx/main/models/projects.py:155
msgid "SCM URL is required."
msgstr "SCM URL が必要です。"
-#: awx/main/models/projects.py:162
+#: awx/main/models/projects.py:163
msgid "Insights Credential is required for an Insights Project."
msgstr "Insights 認証情報が Insights プロジェクトに必要です。"
-#: awx/main/models/projects.py:168
+#: awx/main/models/projects.py:169
msgid "Credential kind must be 'scm'."
msgstr "認証情報の種類は 'scm' にする必要があります。"
-#: awx/main/models/projects.py:185
+#: awx/main/models/projects.py:186
msgid "Invalid credential."
msgstr "無効な認証情報。"
-#: awx/main/models/projects.py:259
+#: awx/main/models/projects.py:265
msgid "Update the project when a job is launched that uses the project."
msgstr "プロジェクトを使用するジョブの起動時にプロジェクトを更新します。"
-#: awx/main/models/projects.py:264
+#: awx/main/models/projects.py:270
msgid ""
"The number of seconds after the last project update ran that a new project "
"update will be launched as a job dependency."
msgstr "最終プロジェクト更新を実行して新規プロジェクトの更新をジョブの依存関係として起動した後の秒数。"
-#: awx/main/models/projects.py:269
+#: awx/main/models/projects.py:275
msgid ""
"Allow changing the SCM branch or revision in a job template that uses this "
"project."
msgstr "このプロジェクトを使用するジョブテンプレートで SCM ブランチまたはリビジョンを変更できるようにします。"
-#: awx/main/models/projects.py:279
+#: awx/main/models/projects.py:285
msgid "The last revision fetched by a project update"
msgstr "プロジェクト更新で取得される最新リビジョン"
-#: awx/main/models/projects.py:286
+#: awx/main/models/projects.py:292
msgid "Playbook Files"
msgstr "Playbook ファイル"
-#: awx/main/models/projects.py:287
+#: awx/main/models/projects.py:293
msgid "List of playbooks found in the project"
msgstr "プロジェクトにある Playbook の一覧"
-#: awx/main/models/projects.py:294
+#: awx/main/models/projects.py:300
msgid "Inventory Files"
msgstr "インベントリーファイル"
-#: awx/main/models/projects.py:295
+#: awx/main/models/projects.py:301
msgid ""
"Suggested list of content that could be Ansible inventory in the project"
msgstr "プロジェクト内の Ansible インベントリーの可能性のあるコンテンツの一覧"
-#: awx/main/models/projects.py:332
+#: awx/main/models/projects.py:338
msgid "Organization cannot be changed when in use by job templates."
msgstr "組織は、ジョブテンプレートで使用中の場合には変更できません。"
-#: awx/main/models/projects.py:490
+#: awx/main/models/projects.py:501
msgid "Parts of the project update playbook that will be run."
msgstr "実行予定のプロジェクト更新 Playbook の一部。"
-#: awx/main/models/projects.py:498
+#: awx/main/models/projects.py:509
msgid ""
"The SCM Revision discovered by this update for the given project and branch."
msgstr "指定のプロジェクトおよびブランチ用にこの更新が検出した SCM リビジョン"
@@ -4559,81 +4618,81 @@ msgstr "更新中"
msgid "The organization used to determine access to this template."
msgstr "このテンプレートにアクセスできるかを決定する時に使用する組織"
-#: awx/main/models/unified_jobs.py:466
+#: awx/main/models/unified_jobs.py:465
msgid "Field is not allowed on launch."
msgstr "フィールドは起動時に許可されません。"
-#: awx/main/models/unified_jobs.py:494
+#: awx/main/models/unified_jobs.py:493
#, python-brace-format
msgid ""
"Variables {list_of_keys} provided, but this template cannot accept variables."
msgstr "変数 {list_of_keys} が指定されましたが、このテンプレートは変数に対応していません。"
-#: awx/main/models/unified_jobs.py:540
+#: awx/main/models/unified_jobs.py:539
msgid "Relaunch"
msgstr "再起動"
-#: awx/main/models/unified_jobs.py:541
+#: awx/main/models/unified_jobs.py:540
msgid "Callback"
msgstr "コールバック"
-#: awx/main/models/unified_jobs.py:542
+#: awx/main/models/unified_jobs.py:541
msgid "Scheduled"
msgstr "スケジュール済み"
-#: awx/main/models/unified_jobs.py:543
+#: awx/main/models/unified_jobs.py:542
msgid "Dependency"
msgstr "依存関係"
-#: awx/main/models/unified_jobs.py:544
+#: awx/main/models/unified_jobs.py:543
msgid "Workflow"
msgstr "ワークフロー"
-#: awx/main/models/unified_jobs.py:546
+#: awx/main/models/unified_jobs.py:545
msgid "Sync"
msgstr "同期"
-#: awx/main/models/unified_jobs.py:601
+#: awx/main/models/unified_jobs.py:600
msgid "The node the job executed on."
msgstr "ジョブが実行されるノード。"
-#: awx/main/models/unified_jobs.py:607
+#: awx/main/models/unified_jobs.py:606
msgid "The instance that managed the isolated execution environment."
msgstr "分離された実行環境を管理したインスタンス。"
-#: awx/main/models/unified_jobs.py:634
+#: awx/main/models/unified_jobs.py:633
msgid "The date and time the job was queued for starting."
msgstr "ジョブが開始のために待機した日時。"
-#: awx/main/models/unified_jobs.py:639
+#: awx/main/models/unified_jobs.py:638
msgid ""
"If True, the task manager has already processed potential dependencies for "
"this job."
msgstr "True の場合には、タスクマネージャーは、このジョブの潜在的な依存関係を処理済みです。"
-#: awx/main/models/unified_jobs.py:645
+#: awx/main/models/unified_jobs.py:644
msgid "The date and time the job finished execution."
msgstr "ジョブが実行を完了した日時。"
-#: awx/main/models/unified_jobs.py:652
+#: awx/main/models/unified_jobs.py:651
msgid "The date and time when the cancel request was sent."
msgstr "取り消しリクエストが送信された日時。"
-#: awx/main/models/unified_jobs.py:659
+#: awx/main/models/unified_jobs.py:658
msgid "Elapsed time in seconds that the job ran."
msgstr "ジョブ実行の経過時間 (秒単位)"
-#: awx/main/models/unified_jobs.py:681
+#: awx/main/models/unified_jobs.py:680
msgid ""
"A status field to indicate the state of the job if it wasn't able to run and "
"capture stdout"
msgstr "stdout の実行およびキャプチャーを実行できない場合のジョブの状態を示すための状態フィールド"
-#: awx/main/models/unified_jobs.py:710
+#: awx/main/models/unified_jobs.py:709
msgid "The Instance group the job was run under"
msgstr "ジョブが実行されたインスタンスグループ"
-#: awx/main/models/unified_jobs.py:718
+#: awx/main/models/unified_jobs.py:717
msgid "The organization used to determine access to this unified job."
msgstr "この統一されたジョブにアクセスできるかを決定する時に使用する組織"
@@ -4687,41 +4746,33 @@ msgid ""
"Shows when an approval node (with a timeout assigned to it) has timed out."
msgstr "承認ノード (タイムアウトが割り当てられている場合) がタイムアウトになると表示されます。"
-#: awx/main/notifications/grafana_backend.py:86
+#: awx/main/notifications/grafana_backend.py:81
msgid "Error converting time {} or timeEnd {} to int."
msgstr "time {} または timeEnd {} を int に変換中のエラー"
-#: awx/main/notifications/grafana_backend.py:88
+#: awx/main/notifications/grafana_backend.py:83
msgid "Error converting time {} and/or timeEnd {} to int."
msgstr "time {} および/または timeEnd {} を int に変換中のエラー"
-#: awx/main/notifications/grafana_backend.py:102
-#: awx/main/notifications/grafana_backend.py:104
+#: awx/main/notifications/grafana_backend.py:97
+#: awx/main/notifications/grafana_backend.py:99
msgid "Error sending notification grafana: {}"
msgstr "通知 grafana の送信時のエラー: {}"
-#: awx/main/notifications/hipchat_backend.py:50
-msgid "Error sending messages: {}"
-msgstr "メッセージの送信時のエラー: {}"
-
-#: awx/main/notifications/hipchat_backend.py:52
-msgid "Error sending message to hipchat: {}"
-msgstr "メッセージの hipchat への送信時のエラー: {}"
-
#: awx/main/notifications/irc_backend.py:56
msgid "Exception connecting to irc server: {}"
msgstr "irc サーバーへの接続時の例外: {}"
-#: awx/main/notifications/mattermost_backend.py:50
-#: awx/main/notifications/mattermost_backend.py:52
+#: awx/main/notifications/mattermost_backend.py:49
+#: awx/main/notifications/mattermost_backend.py:51
msgid "Error sending notification mattermost: {}"
msgstr "通知 mattermost の送信時のエラー: {}"
-#: awx/main/notifications/pagerduty_backend.py:64
+#: awx/main/notifications/pagerduty_backend.py:75
msgid "Exception connecting to PagerDuty: {}"
msgstr "PagerDuty への接続時の例外: {}"
-#: awx/main/notifications/pagerduty_backend.py:73
+#: awx/main/notifications/pagerduty_backend.py:84
#: awx/main/notifications/slack_backend.py:58
#: awx/main/notifications/twilio_backend.py:48
msgid "Exception sending messages: {}"
@@ -4748,46 +4799,52 @@ msgid ""
"job node(s) missing unified job template and error handling path [{no_ufjt}]."
msgstr "ワークフロージョブのノードにエラー処理パスがありません [{node_status}] ワークフロージョブのノードに統一されたジョブテンプレートおよびエラー処理パスがありません [{no_ufjt}]。"
-#: awx/main/scheduler/task_manager.py:118
+#: awx/main/scheduler/task_manager.py:127
msgid ""
"Workflow Job spawned from workflow could not start because it would result "
"in recursion (spawn order, most recent first: {})"
msgstr "ワークフローから起動されるワークフロージョブは、再帰が生じるために開始できませんでした (起動順、もっとも新しいものから: {})"
-#: awx/main/scheduler/task_manager.py:126
+#: awx/main/scheduler/task_manager.py:135
msgid ""
"Job spawned from workflow could not start because it was missing a related "
"resource such as project or inventory"
msgstr "ワークフローから起動されるジョブは、プロジェクトまたはインベントリーなどの関連するリソースがないために開始できませんでした"
-#: awx/main/scheduler/task_manager.py:135
+#: awx/main/scheduler/task_manager.py:144
msgid ""
"Job spawned from workflow could not start because it was not in the right "
"state or required manual credentials"
msgstr "ワークフローから起動されるジョブは、正常な状態にないか、または手動の認証が必要であるために開始できませんでした"
-#: awx/main/scheduler/task_manager.py:176
+#: awx/main/scheduler/task_manager.py:185
msgid "No error handling paths found, marking workflow as failed"
msgstr "エラーの処理パスが見つかりません。ワークフローを失敗としてマークしました"
-#: awx/main/scheduler/task_manager.py:508
+#: awx/main/scheduler/task_manager.py:523
#, python-brace-format
msgid "The approval node {name} ({pk}) has expired after {timeout} seconds."
msgstr "承認ノード {name} ({pk}) は {timeout} 秒後に失効しました。"
-#: awx/main/tasks.py:1049
+#: awx/main/tasks.py:599
+msgid ""
+"Scheduled job could not start because it was not in the "
+"right state or required manual credentials"
+msgstr "スケジュール済みのジョブは、正常な状態にないか、手動の認証が必要であるために開始できませんでした"
+
+#: awx/main/tasks.py:1070
msgid "Invalid virtual environment selected: {}"
msgstr "無効な仮想環境が選択されました: {}"
-#: awx/main/tasks.py:1853
+#: awx/main/tasks.py:1857
msgid "Job could not start because it does not have a valid inventory."
msgstr "ジョブは有効なインベントリーがないために開始できませんでした。"
-#: awx/main/tasks.py:1857
+#: awx/main/tasks.py:1861
msgid "Job could not start because it does not have a valid project."
msgstr "ジョブは有効なプロジェクトがないために開始できませんでした。"
-#: awx/main/tasks.py:1862
+#: awx/main/tasks.py:1866
msgid ""
"The project revision for this job template is unknown due to a failed update."
msgstr "更新に失敗したため、このジョブテンプレートのプロジェクトリビジョンは不明です。"
@@ -4812,53 +4869,53 @@ msgstr "ワークフロージョブのノードにエラーハンドルパスが
msgid "Unable to convert \"%s\" to boolean"
msgstr "\"%s\" をブール値に変換できません"
-#: awx/main/utils/common.py:261
+#: awx/main/utils/common.py:248
#, python-format
msgid "Unsupported SCM type \"%s\""
msgstr "サポートされない SCM タイプ \"%s\""
-#: awx/main/utils/common.py:268 awx/main/utils/common.py:280
-#: awx/main/utils/common.py:299
+#: awx/main/utils/common.py:255 awx/main/utils/common.py:267
+#: awx/main/utils/common.py:286
#, python-format
msgid "Invalid %s URL"
msgstr "無効な %s URL"
-#: awx/main/utils/common.py:270 awx/main/utils/common.py:309
+#: awx/main/utils/common.py:257 awx/main/utils/common.py:297
#, python-format
msgid "Unsupported %s URL"
msgstr "サポートされない %s URL"
-#: awx/main/utils/common.py:311
+#: awx/main/utils/common.py:299
#, python-format
msgid "Unsupported host \"%s\" for file:// URL"
msgstr "file:// URL でサポートされないホスト \"%s\""
-#: awx/main/utils/common.py:313
+#: awx/main/utils/common.py:301
#, python-format
msgid "Host is required for %s URL"
msgstr "%s URL にはホストが必要です"
-#: awx/main/utils/common.py:331
+#: awx/main/utils/common.py:319
#, python-format
msgid "Username must be \"git\" for SSH access to %s."
msgstr "%s への SSH アクセスではユーザー名を \"git\" にする必要があります。"
-#: awx/main/utils/common.py:337
+#: awx/main/utils/common.py:325
#, python-format
msgid "Username must be \"hg\" for SSH access to %s."
msgstr "%s への SSH アクセスではユーザー名を \"hg\" にする必要があります。"
-#: awx/main/utils/common.py:668
+#: awx/main/utils/common.py:656
#, python-brace-format
msgid "Input type `{data_type}` is not a dictionary"
msgstr "入力タイプ `{data_type}` は辞書ではありません"
-#: awx/main/utils/common.py:701
+#: awx/main/utils/common.py:689
#, python-brace-format
msgid "Variables not compatible with JSON standard (error: {json_error})"
msgstr "変数には JSON 標準との互換性がありません (エラー: {json_error})"
-#: awx/main/utils/common.py:707
+#: awx/main/utils/common.py:695
#, python-brace-format
msgid ""
"Cannot parse as JSON (error: {json_error}) or YAML (error: {yaml_error})."
@@ -4970,290 +5027,6 @@ msgstr "サーバーエラー"
msgid "A server error has occurred."
msgstr "サーバーエラーが発生しました。"
-#: awx/settings/defaults.py:683
-msgid "US East (Northern Virginia)"
-msgstr "米国東部 (バージニア北部)"
-
-#: awx/settings/defaults.py:684
-msgid "US East (Ohio)"
-msgstr "米国東部 (オハイオ)"
-
-#: awx/settings/defaults.py:685
-msgid "US West (Oregon)"
-msgstr "米国西部 (オレゴン)"
-
-#: awx/settings/defaults.py:686
-msgid "US West (Northern California)"
-msgstr "米国西部 (北カリフォルニア)"
-
-#: awx/settings/defaults.py:687
-msgid "Canada (Central)"
-msgstr "カナダ (中部)"
-
-#: awx/settings/defaults.py:688
-msgid "EU (Frankfurt)"
-msgstr "EU (フランクフルト)"
-
-#: awx/settings/defaults.py:689
-msgid "EU (Ireland)"
-msgstr "EU (アイルランド)"
-
-#: awx/settings/defaults.py:690
-msgid "EU (London)"
-msgstr "EU (ロンドン)"
-
-#: awx/settings/defaults.py:691
-msgid "Asia Pacific (Singapore)"
-msgstr "アジア太平洋 (シンガポール)"
-
-#: awx/settings/defaults.py:692
-msgid "Asia Pacific (Sydney)"
-msgstr "アジア太平洋 (シドニー)"
-
-#: awx/settings/defaults.py:693
-msgid "Asia Pacific (Tokyo)"
-msgstr "アジア太平洋 (東京)"
-
-#: awx/settings/defaults.py:694
-msgid "Asia Pacific (Seoul)"
-msgstr "アジア太平洋 (ソウル)"
-
-#: awx/settings/defaults.py:695
-msgid "Asia Pacific (Mumbai)"
-msgstr "アジア太平洋 (ムンバイ)"
-
-#: awx/settings/defaults.py:696
-msgid "South America (Sao Paulo)"
-msgstr "南アメリカ (サンパウロ)"
-
-#: awx/settings/defaults.py:697
-msgid "US West (GovCloud)"
-msgstr "米国西部 (GovCloud)"
-
-#: awx/settings/defaults.py:698
-msgid "China (Beijing)"
-msgstr "中国 (北京)"
-
-#: awx/settings/defaults.py:747
-msgid "US East 1 (B)"
-msgstr "米国東部 1 (B)"
-
-#: awx/settings/defaults.py:748
-msgid "US East 1 (C)"
-msgstr "米国東部 1 (C)"
-
-#: awx/settings/defaults.py:749
-msgid "US East 1 (D)"
-msgstr "米国東部 1 (D)"
-
-#: awx/settings/defaults.py:750
-msgid "US East 4 (A)"
-msgstr "米国東部 4 (A)"
-
-#: awx/settings/defaults.py:751
-msgid "US East 4 (B)"
-msgstr "米国東部 4 (B)"
-
-#: awx/settings/defaults.py:752
-msgid "US East 4 (C)"
-msgstr "米国東部 4 (C)"
-
-#: awx/settings/defaults.py:753
-msgid "US Central (A)"
-msgstr "米国中部 (A)"
-
-#: awx/settings/defaults.py:754
-msgid "US Central (B)"
-msgstr "米国中部 (B)"
-
-#: awx/settings/defaults.py:755
-msgid "US Central (C)"
-msgstr "米国中部 (C)"
-
-#: awx/settings/defaults.py:756
-msgid "US Central (F)"
-msgstr "米国中部 (F)"
-
-#: awx/settings/defaults.py:757
-msgid "US West (A)"
-msgstr "米国西部 (A)"
-
-#: awx/settings/defaults.py:758
-msgid "US West (B)"
-msgstr "米国西部 (B)"
-
-#: awx/settings/defaults.py:759
-msgid "US West (C)"
-msgstr "米国西部 (C)"
-
-#: awx/settings/defaults.py:760
-msgid "Europe West 1 (B)"
-msgstr "欧州西部 1 (B)"
-
-#: awx/settings/defaults.py:761
-msgid "Europe West 1 (C)"
-msgstr "欧州西部 1 (C)"
-
-#: awx/settings/defaults.py:762
-msgid "Europe West 1 (D)"
-msgstr "欧州西部 1 (D)"
-
-#: awx/settings/defaults.py:763
-msgid "Europe West 2 (A)"
-msgstr "欧州西部 2 (A)"
-
-#: awx/settings/defaults.py:764
-msgid "Europe West 2 (B)"
-msgstr "欧州西部 2 (B)"
-
-#: awx/settings/defaults.py:765
-msgid "Europe West 2 (C)"
-msgstr "欧州西部 2 (C)"
-
-#: awx/settings/defaults.py:766
-msgid "Asia East (A)"
-msgstr "アジア東部 (A)"
-
-#: awx/settings/defaults.py:767
-msgid "Asia East (B)"
-msgstr "アジア東部 (B)"
-
-#: awx/settings/defaults.py:768
-msgid "Asia East (C)"
-msgstr "アジア東部 (C)"
-
-#: awx/settings/defaults.py:769
-msgid "Asia Southeast (A)"
-msgstr "アジア南東部 (A)"
-
-#: awx/settings/defaults.py:770
-msgid "Asia Southeast (B)"
-msgstr "アジア南東部 (B)"
-
-#: awx/settings/defaults.py:771
-msgid "Asia Northeast (A)"
-msgstr "アジア北東部 (A)"
-
-#: awx/settings/defaults.py:772
-msgid "Asia Northeast (B)"
-msgstr "アジア北東部 (B)"
-
-#: awx/settings/defaults.py:773
-msgid "Asia Northeast (C)"
-msgstr "アジア北東部 (C)"
-
-#: awx/settings/defaults.py:774
-msgid "Australia Southeast (A)"
-msgstr "オーストラリア南東部 (A)"
-
-#: awx/settings/defaults.py:775
-msgid "Australia Southeast (B)"
-msgstr "オーストラリア南東部 (B)"
-
-#: awx/settings/defaults.py:776
-msgid "Australia Southeast (C)"
-msgstr "オーストラリア南東部 (C)"
-
-#: awx/settings/defaults.py:798
-msgid "US East"
-msgstr "米国東部"
-
-#: awx/settings/defaults.py:799
-msgid "US East 2"
-msgstr "米国東部 2"
-
-#: awx/settings/defaults.py:800
-msgid "US Central"
-msgstr "米国中部"
-
-#: awx/settings/defaults.py:801
-msgid "US North Central"
-msgstr "米国中北部"
-
-#: awx/settings/defaults.py:802
-msgid "US South Central"
-msgstr "米国中南部"
-
-#: awx/settings/defaults.py:803
-msgid "US West Central"
-msgstr "米国中西部"
-
-#: awx/settings/defaults.py:804
-msgid "US West"
-msgstr "米国西部"
-
-#: awx/settings/defaults.py:805
-msgid "US West 2"
-msgstr "米国西部 2"
-
-#: awx/settings/defaults.py:806
-msgid "Canada East"
-msgstr "カナダ東部"
-
-#: awx/settings/defaults.py:807
-msgid "Canada Central"
-msgstr "カナダ中部"
-
-#: awx/settings/defaults.py:808
-msgid "Brazil South"
-msgstr "ブラジル南部"
-
-#: awx/settings/defaults.py:809
-msgid "Europe North"
-msgstr "欧州北部"
-
-#: awx/settings/defaults.py:810
-msgid "Europe West"
-msgstr "欧州西部"
-
-#: awx/settings/defaults.py:811
-msgid "UK West"
-msgstr "英国西部"
-
-#: awx/settings/defaults.py:812
-msgid "UK South"
-msgstr "英国南部"
-
-#: awx/settings/defaults.py:813
-msgid "Asia East"
-msgstr "アジア東部"
-
-#: awx/settings/defaults.py:814
-msgid "Asia Southeast"
-msgstr "アジア南東部"
-
-#: awx/settings/defaults.py:815
-msgid "Australia East"
-msgstr "オーストラリア東部"
-
-#: awx/settings/defaults.py:816
-msgid "Australia Southeast"
-msgstr "オーストラリア南東部 "
-
-#: awx/settings/defaults.py:817
-msgid "India West"
-msgstr "インド西部"
-
-#: awx/settings/defaults.py:818
-msgid "India South"
-msgstr "インド南部"
-
-#: awx/settings/defaults.py:819
-msgid "Japan East"
-msgstr "日本東部"
-
-#: awx/settings/defaults.py:820
-msgid "Japan West"
-msgstr "日本西部"
-
-#: awx/settings/defaults.py:821
-msgid "Korea Central"
-msgstr "韓国中部"
-
-#: awx/settings/defaults.py:822
-msgid "Korea South"
-msgstr "韓国南部"
-
#: awx/sso/apps.py:9
msgid "Single Sign-On"
msgstr "シングルサインオン"
@@ -5596,8 +5369,8 @@ msgid "The OAuth2 secret from your web application."
msgstr "web アプリケーションの OAuth2 シークレット"
#: awx/sso/conf.py:578
-msgid "Google OAuth2 Whitelisted Domains"
-msgstr "Google OAuth2 ホワイトリストドメイン"
+msgid "Google OAuth2 Allowed Domains"
+msgstr "GoogleOAuth2 で許可されているドメイン"
#: awx/sso/conf.py:579
msgid ""
@@ -5785,101 +5558,111 @@ msgstr "Azure AD OAuth2 組織マップ"
msgid "Azure AD OAuth2 Team Map"
msgstr "Azure AD OAuth2 チームマップ"
+#: awx/sso/conf.py:926
+msgid "Automatically Create Organizations and Teams on SAML Login"
+msgstr "SAML ログインで組織とチームを自動的に作成"
+
#: awx/sso/conf.py:927
+msgid ""
+"When enabled (the default), mapped Organizations and Teams will be created "
+"automatically on successful SAML login."
+msgstr "有効にすると (デフォルト)、マップされた組織とチームは、SAML ログインが成功すると自動的に作成されます。"
+
+#: awx/sso/conf.py:929 awx/sso/conf.py:942 awx/sso/conf.py:955
+#: awx/sso/conf.py:968 awx/sso/conf.py:982 awx/sso/conf.py:995
+#: awx/sso/conf.py:1007 awx/sso/conf.py:1027 awx/sso/conf.py:1044
+#: awx/sso/conf.py:1062 awx/sso/conf.py:1097 awx/sso/conf.py:1128
+#: awx/sso/conf.py:1141 awx/sso/conf.py:1157 awx/sso/conf.py:1169
+#: awx/sso/conf.py:1181 awx/sso/conf.py:1200 awx/sso/models.py:16
+msgid "SAML"
+msgstr "SAML"
+
+#: awx/sso/conf.py:938
msgid "SAML Assertion Consumer Service (ACS) URL"
msgstr "SAML アサーションコンシューマー サービス (ACS) URL"
-#: awx/sso/conf.py:928
+#: awx/sso/conf.py:939
msgid ""
"Register Tower as a service provider (SP) with each identity provider (IdP) "
"you have configured. Provide your SP Entity ID and this ACS URL for your "
"application."
msgstr "設定済みの各アイデンティティープロバイダー (IdP) で Tower をサービスプロバイダー (SP) として登録します。SP エンティティー ID およびアプリケーションのこの ACS URL を指定します。"
-#: awx/sso/conf.py:931 awx/sso/conf.py:944 awx/sso/conf.py:957
-#: awx/sso/conf.py:971 awx/sso/conf.py:984 awx/sso/conf.py:996
-#: awx/sso/conf.py:1016 awx/sso/conf.py:1033 awx/sso/conf.py:1051
-#: awx/sso/conf.py:1086 awx/sso/conf.py:1117 awx/sso/conf.py:1130
-#: awx/sso/conf.py:1146 awx/sso/conf.py:1158 awx/sso/conf.py:1170
-#: awx/sso/conf.py:1189 awx/sso/models.py:16
-msgid "SAML"
-msgstr "SAML"
-
-#: awx/sso/conf.py:941
+#: awx/sso/conf.py:952
msgid "SAML Service Provider Metadata URL"
msgstr "SAML サービスプロバイダーメタデータ URL"
-#: awx/sso/conf.py:942
+#: awx/sso/conf.py:953
msgid ""
"If your identity provider (IdP) allows uploading an XML metadata file, you "
"can download one from this URL."
msgstr "アイデンティティープロバイダー (IdP) が XML メタデータファイルのアップロードを許可する場合、この URL からダウンロードできます。"
-#: awx/sso/conf.py:953
+#: awx/sso/conf.py:964
msgid "SAML Service Provider Entity ID"
msgstr "SAML サービスプロバイダーエンティティー ID"
-#: awx/sso/conf.py:954
+#: awx/sso/conf.py:965
msgid ""
"The application-defined unique identifier used as the audience of the SAML "
"service provider (SP) configuration. This is usually the URL for Tower."
msgstr "SAML サービスプロバイダー (SP) 設定の対象として使用されるアプリケーションで定義される固有識別子です。通常これは Tower の URL になります。"
-#: awx/sso/conf.py:968
+#: awx/sso/conf.py:979
msgid "SAML Service Provider Public Certificate"
msgstr "SAML サービスプロバイダーの公開証明書"
-#: awx/sso/conf.py:969
+#: awx/sso/conf.py:980
msgid ""
"Create a keypair for Tower to use as a service provider (SP) and include the "
"certificate content here."
msgstr "サービスプロバイダー (SP) として使用するための Tower のキーペアを作成し、ここに証明書の内容を組み込みます。"
-#: awx/sso/conf.py:981
+#: awx/sso/conf.py:992
msgid "SAML Service Provider Private Key"
msgstr "SAML サービスプロバイダーの秘密鍵|"
-#: awx/sso/conf.py:982
+#: awx/sso/conf.py:993
msgid ""
"Create a keypair for Tower to use as a service provider (SP) and include the "
"private key content here."
msgstr "サービスプロバイダー (SP) として使用するための Tower のキーペアを作成し、ここに秘密鍵の内容を組み込みます。"
-#: awx/sso/conf.py:993
+#: awx/sso/conf.py:1004
msgid "SAML Service Provider Organization Info"
msgstr "SAML サービスプロバイダーの組織情報"
-#: awx/sso/conf.py:994
+#: awx/sso/conf.py:1005
msgid ""
"Provide the URL, display name, and the name of your app. Refer to the "
"Ansible Tower documentation for example syntax."
msgstr "アプリケーションの URL、表示名、および名前を指定します。構文のサンプルについては Ansible Tower ドキュメントを参照してください。"
-#: awx/sso/conf.py:1012
+#: awx/sso/conf.py:1023
msgid "SAML Service Provider Technical Contact"
msgstr "SAML サービスプロバイダーテクニカルサポートの問い合わせ先"
-#: awx/sso/conf.py:1013
+#: awx/sso/conf.py:1024
msgid ""
"Provide the name and email address of the technical contact for your service "
"provider. Refer to the Ansible Tower documentation for example syntax."
msgstr "サービスプロバイダーのテクニカルサポート担当の名前およびメールアドレスを指定します。構文のサンプルについては Ansible Tower ドキュメントを参照してください。"
-#: awx/sso/conf.py:1029
+#: awx/sso/conf.py:1040
msgid "SAML Service Provider Support Contact"
msgstr "SAML サービスプロバイダーサポートの問い合わせ先"
-#: awx/sso/conf.py:1030
+#: awx/sso/conf.py:1041
msgid ""
"Provide the name and email address of the support contact for your service "
"provider. Refer to the Ansible Tower documentation for example syntax."
msgstr "サービスプロバイダーのサポート担当の名前およびメールアドレスを指定します。構文のサンプルについては Ansible Tower ドキュメントを参照してください。"
-#: awx/sso/conf.py:1045
+#: awx/sso/conf.py:1056
msgid "SAML Enabled Identity Providers"
msgstr "SAML で有効にされたアイデンティティープロバイダー"
-#: awx/sso/conf.py:1046
+#: awx/sso/conf.py:1057
msgid ""
"Configure the Entity ID, SSO URL and certificate for each identity provider "
"(IdP) in use. Multiple SAML IdPs are supported. Some IdPs may provide user "
@@ -5888,57 +5671,57 @@ msgid ""
"additional details and syntax."
msgstr "使用中のそれぞれのアイデンティティープロバイダー (IdP) についてのエンティティー ID、SSO URL および証明書を設定します。複数の SAML IdP がサポートされます。一部の IdP はデフォルト OID とは異なる属性名を使用してユーザーデータを提供することがあります。それぞれの IdP について属性名が上書きされる可能性があります。追加の詳細および構文については、Ansible ドキュメントを参照してください。"
-#: awx/sso/conf.py:1082
+#: awx/sso/conf.py:1093
msgid "SAML Security Config"
msgstr "SAML セキュリティー設定"
-#: awx/sso/conf.py:1083
+#: awx/sso/conf.py:1094
msgid ""
"A dict of key value pairs that are passed to the underlying python-saml "
"security setting https://github.com/onelogin/python-saml#settings"
msgstr "基礎となる python-saml セキュリティー設定に渡されるキー値ペアの辞書: https://github.com/onelogin/python-saml#settings"
-#: awx/sso/conf.py:1114
+#: awx/sso/conf.py:1125
msgid "SAML Service Provider extra configuration data"
msgstr "SAML サービスプロバイダーの追加設定データ"
-#: awx/sso/conf.py:1115
+#: awx/sso/conf.py:1126
msgid ""
"A dict of key value pairs to be passed to the underlying python-saml Service "
"Provider configuration setting."
msgstr "基礎となる python-saml サービスプロバイダー設定に渡されるキー値ペアの辞書。"
-#: awx/sso/conf.py:1127
+#: awx/sso/conf.py:1138
msgid "SAML IDP to extra_data attribute mapping"
msgstr "SAML IDP の extra_data 属性へのマッピング"
-#: awx/sso/conf.py:1128
+#: awx/sso/conf.py:1139
msgid ""
"A list of tuples that maps IDP attributes to extra_attributes. Each "
"attribute will be a list of values, even if only 1 value."
msgstr "IDP 属性を extra_attributes にマップするタプルの一覧です。各属性は 1 つの値のみの場合も値の一覧となります。"
-#: awx/sso/conf.py:1144
+#: awx/sso/conf.py:1155
msgid "SAML Organization Map"
msgstr "SAML 組織マップ"
-#: awx/sso/conf.py:1156
+#: awx/sso/conf.py:1167
msgid "SAML Team Map"
msgstr "SAML チームマップ"
-#: awx/sso/conf.py:1168
+#: awx/sso/conf.py:1179
msgid "SAML Organization Attribute Mapping"
msgstr "SAML 組織属性マッピング"
-#: awx/sso/conf.py:1169
+#: awx/sso/conf.py:1180
msgid "Used to translate user organization membership into Tower."
msgstr "ユーザー組織メンバーシップを Tower に変換するために使用されます。"
-#: awx/sso/conf.py:1187
+#: awx/sso/conf.py:1198
msgid "SAML Team Attribute Mapping"
msgstr "SAML チーム属性マッピング"
-#: awx/sso/conf.py:1188
+#: awx/sso/conf.py:1199
msgid "Used to translate user team membership into Tower."
msgstr "ユーザーチームメンバーシップを Tower に変換するために使用されます。"
@@ -6005,12 +5788,12 @@ msgstr "無効なユーザーフラグ: \"{invalid_flag}\""
msgid "Invalid language code(s) for org info: {invalid_lang_codes}."
msgstr "組織情報の無効な言語コード: {invalid_lang_codes}"
-#: awx/sso/pipeline.py:27
+#: awx/sso/pipeline.py:28
#, python-brace-format
msgid "An account cannot be found for {0}"
msgstr "{0} のアカウントが見つかりません"
-#: awx/sso/pipeline.py:33
+#: awx/sso/pipeline.py:34
msgid "Your account is inactive"
msgstr "アカウントが非アクティブです"
@@ -6082,9 +5865,9 @@ msgstr "カスタムログイン情報"
msgid ""
"If needed, you can add specific information (such as a legal notice or a "
"disclaimer) to a text box in the login modal using this setting. Any content "
-"added must be in plain text, as custom HTML or other markup languages are "
-"not supported."
-msgstr "必要な場合は、この設定を使ってログインモーダルのテキストボックスに特定の情報 (法律上の通知または免責事項など) を追加できます。追加されるすべてのコンテンツは、カスタム HTML や他のマークアップ言語がサポートされないため、プレーンテキストでなければなりません。"
+"added must be in plain text or an HTML fragment, as other markup languages "
+"are not supported."
+msgstr "必要に応じて、この設定を使用して、ログインモーダルのテキストボックスに特定の情報 (法律上の通知または免責事項など) を追加できます。他のマークアップ言語はサポートされていないため、追加するコンテンツはすべてプレーンテキストまたは HTML フラグメントでなければなりません。"
#: awx/ui/conf.py:45
msgid "Custom Logo"
diff --git a/awx/main/access.py b/awx/main/access.py
index 4f54be6e12..0ecb025d92 100644
--- a/awx/main/access.py
+++ b/awx/main/access.py
@@ -1103,11 +1103,6 @@ class CredentialTypeAccess(BaseAccess):
def can_use(self, obj):
return True
- def get_method_capability(self, method, obj, parent_obj):
- if obj.managed_by_tower:
- return False
- return super(CredentialTypeAccess, self).get_method_capability(method, obj, parent_obj)
-
def filtered_queryset(self):
return self.model.objects.all()
@@ -1182,6 +1177,8 @@ class CredentialAccess(BaseAccess):
def get_user_capabilities(self, obj, **kwargs):
user_capabilities = super(CredentialAccess, self).get_user_capabilities(obj, **kwargs)
user_capabilities['use'] = self.can_use(obj)
+ if getattr(obj, 'managed_by_tower', False) is True:
+ user_capabilities['edit'] = user_capabilities['delete'] = False
return user_capabilities
@@ -2753,6 +2750,9 @@ class WorkflowApprovalTemplateAccess(BaseAccess):
else:
return (self.check_related('workflow_approval_template', UnifiedJobTemplate, role_field='admin_role'))
+ def can_change(self, obj, data):
+ return self.user.can_access(WorkflowJobTemplate, 'change', obj.workflow_job_template, data={})
+
def can_start(self, obj, validate_license=False):
# for copying WFJTs that contain approval nodes
if self.user.is_superuser:
diff --git a/awx/main/analytics/__init__.py b/awx/main/analytics/__init__.py
index 9ab526f29b..6aee1cef91 100644
--- a/awx/main/analytics/__init__.py
+++ b/awx/main/analytics/__init__.py
@@ -1 +1 @@
-from .core import register, gather, ship, table_version # noqa
+from .core import all_collectors, expensive_collectors, register, gather, ship # noqa
diff --git a/awx/main/analytics/broadcast_websocket.py b/awx/main/analytics/broadcast_websocket.py
index 5cfda529eb..d8abcb4745 100644
--- a/awx/main/analytics/broadcast_websocket.py
+++ b/awx/main/analytics/broadcast_websocket.py
@@ -20,7 +20,7 @@ from django.conf import settings
BROADCAST_WEBSOCKET_REDIS_KEY_NAME = 'broadcast_websocket_stats'
-logger = logging.getLogger('awx.main.analytics.broadcast_websocket')
+logger = logging.getLogger('awx.analytics.broadcast_websocket')
def dt_to_seconds(dt):
diff --git a/awx/main/analytics/collectors.py b/awx/main/analytics/collectors.py
index 45cc247bf4..e1dc468d51 100644
--- a/awx/main/analytics/collectors.py
+++ b/awx/main/analytics/collectors.py
@@ -1,3 +1,4 @@
+import io
import os
import os.path
import platform
@@ -6,13 +7,14 @@ from django.db import connection
from django.db.models import Count
from django.conf import settings
from django.utils.timezone import now
+from django.utils.translation import ugettext_lazy as _
from awx.conf.license import get_license
from awx.main.utils import (get_awx_version, get_ansible_version,
get_custom_venv_choices, camelcase_to_underscore)
from awx.main import models
from django.contrib.sessions.models import Session
-from awx.main.analytics import register, table_version
+from awx.main.analytics import register
'''
This module is used to define metrics collected by awx.main.analytics.gather()
@@ -31,8 +33,8 @@ data _since_ the last report date - i.e., new data in the last 24 hours)
'''
-@register('config', '1.1')
-def config(since):
+@register('config', '1.1', description=_('General platform configuration.'))
+def config(since, **kwargs):
license_info = get_license(show_key=False)
install_type = 'traditional'
if os.environ.get('container') == 'oci':
@@ -63,8 +65,8 @@ def config(since):
}
-@register('counts', '1.0')
-def counts(since):
+@register('counts', '1.0', description=_('Counts of objects such as organizations, inventories, and projects'))
+def counts(since, **kwargs):
counts = {}
for cls in (models.Organization, models.Team, models.User,
models.Inventory, models.Credential, models.Project,
@@ -98,8 +100,8 @@ def counts(since):
return counts
-@register('org_counts', '1.0')
-def org_counts(since):
+@register('org_counts', '1.0', description=_('Counts of users and teams by organization'))
+def org_counts(since, **kwargs):
counts = {}
for org in models.Organization.objects.annotate(num_users=Count('member_role__members', distinct=True),
num_teams=Count('teams', distinct=True)).values('name', 'id', 'num_users', 'num_teams'):
@@ -110,8 +112,8 @@ def org_counts(since):
return counts
-@register('cred_type_counts', '1.0')
-def cred_type_counts(since):
+@register('cred_type_counts', '1.0', description=_('Counts of credentials by credential type'))
+def cred_type_counts(since, **kwargs):
counts = {}
for cred_type in models.CredentialType.objects.annotate(num_credentials=Count(
'credentials', distinct=True)).values('name', 'id', 'managed_by_tower', 'num_credentials'):
@@ -122,8 +124,8 @@ def cred_type_counts(since):
return counts
-@register('inventory_counts', '1.2')
-def inventory_counts(since):
+@register('inventory_counts', '1.2', description=_('Inventories, their inventory sources, and host counts'))
+def inventory_counts(since, **kwargs):
counts = {}
for inv in models.Inventory.objects.filter(kind='').annotate(num_sources=Count('inventory_sources', distinct=True),
num_hosts=Count('hosts', distinct=True)).only('id', 'name', 'kind'):
@@ -147,8 +149,8 @@ def inventory_counts(since):
return counts
-@register('projects_by_scm_type', '1.0')
-def projects_by_scm_type(since):
+@register('projects_by_scm_type', '1.0', description=_('Counts of projects by source control type'))
+def projects_by_scm_type(since, **kwargs):
counts = dict(
(t[0] or 'manual', 0)
for t in models.Project.SCM_TYPE_CHOICES
@@ -166,8 +168,8 @@ def _get_isolated_datetime(last_check):
return last_check
-@register('instance_info', '1.0')
-def instance_info(since, include_hostnames=False):
+@register('instance_info', '1.0', description=_('Cluster topology and capacity'))
+def instance_info(since, include_hostnames=False, **kwargs):
info = {}
instances = models.Instance.objects.values_list('hostname').values(
'uuid', 'version', 'capacity', 'cpu', 'memory', 'managed_by_policy', 'hostname', 'last_isolated_check', 'enabled')
@@ -192,8 +194,8 @@ def instance_info(since, include_hostnames=False):
return info
-@register('job_counts', '1.0')
-def job_counts(since):
+@register('job_counts', '1.0', description=_('Counts of jobs by status'))
+def job_counts(since, **kwargs):
counts = {}
counts['total_jobs'] = models.UnifiedJob.objects.exclude(launch_type='sync').count()
counts['status'] = dict(models.UnifiedJob.objects.exclude(launch_type='sync').values_list('status').annotate(Count('status')).order_by())
@@ -202,8 +204,8 @@ def job_counts(since):
return counts
-@register('job_instance_counts', '1.0')
-def job_instance_counts(since):
+@register('job_instance_counts', '1.0', description=_('Counts of jobs by execution node'))
+def job_instance_counts(since, **kwargs):
counts = {}
job_types = models.UnifiedJob.objects.exclude(launch_type='sync').values_list(
'execution_node', 'launch_type').annotate(job_launch_type=Count('launch_type')).order_by()
@@ -217,30 +219,71 @@ def job_instance_counts(since):
return counts
-@register('query_info', '1.0')
-def query_info(since, collection_type):
+@register('query_info', '1.0', description=_('Metadata about the analytics collected'))
+def query_info(since, collection_type, until, **kwargs):
query_info = {}
query_info['last_run'] = str(since)
- query_info['current_time'] = str(now())
+ query_info['current_time'] = str(until)
query_info['collection_type'] = collection_type
return query_info
-# Copies Job Events from db to a .csv to be shipped
-@table_version('events_table.csv', '1.1')
-@table_version('unified_jobs_table.csv', '1.1')
-@table_version('unified_job_template_table.csv', '1.0')
-@table_version('workflow_job_node_table.csv', '1.0')
-@table_version('workflow_job_template_node_table.csv', '1.0')
-def copy_tables(since, full_path, subset=None):
- def _copy_table(table, query, path):
- file_path = os.path.join(path, table + '_table.csv')
- file = open(file_path, 'w', encoding='utf-8')
- with connection.cursor() as cursor:
- cursor.copy_expert(query, file)
- file.close()
- return file_path
+'''
+The event table can be *very* large, and we have a 100MB upload limit.
+Split large table dumps at dump time into a series of files.
+'''
+MAX_TABLE_SIZE = 200 * 1048576
+
+
+class FileSplitter(io.StringIO):
+ def __init__(self, filespec=None, *args, **kwargs):
+ self.filespec = filespec
+ self.files = []
+ self.currentfile = None
+ self.header = None
+ self.counter = 0
+ self.cycle_file()
+
+ def cycle_file(self):
+ if self.currentfile:
+ self.currentfile.close()
+ self.counter = 0
+ fname = '{}_split{}'.format(self.filespec, len(self.files))
+ self.currentfile = open(fname, 'w', encoding='utf-8')
+ self.files.append(fname)
+ if self.header:
+ self.currentfile.write('{}\n'.format(self.header))
+
+ def file_list(self):
+ self.currentfile.close()
+ # Check for an empty dump
+ if len(self.header) + 1 == self.counter:
+ os.remove(self.files[-1])
+ self.files = self.files[:-1]
+ # If we only have one file, remove the suffix
+ if len(self.files) == 1:
+ os.rename(self.files[0],self.files[0].replace('_split0',''))
+ return self.files
+
+ def write(self, s):
+ if not self.header:
+ self.header = s[0:s.index('\n')]
+ self.counter += self.currentfile.write(s)
+ if self.counter >= MAX_TABLE_SIZE:
+ self.cycle_file()
+
+
+def _copy_table(table, query, path):
+ file_path = os.path.join(path, table + '_table.csv')
+ file = FileSplitter(filespec=file_path)
+ with connection.cursor() as cursor:
+ cursor.copy_expert(query, file)
+ return file.file_list()
+
+
+@register('events_table', '1.1', format='csv', description=_('Automation task records'), expensive=True)
+def events_table(since, full_path, until, **kwargs):
events_query = '''COPY (SELECT main_jobevent.id,
main_jobevent.created,
main_jobevent.uuid,
@@ -262,18 +305,21 @@ def copy_tables(since, full_path, subset=None):
main_jobevent.event_data::json->'res'->'warnings' AS warnings,
main_jobevent.event_data::json->'res'->'deprecations' AS deprecations
FROM main_jobevent
- WHERE main_jobevent.created > {}
- ORDER BY main_jobevent.id ASC) TO STDOUT WITH CSV HEADER'''.format(since.strftime("'%Y-%m-%d %H:%M:%S'"))
- if not subset or 'events' in subset:
- _copy_table(table='events', query=events_query, path=full_path)
+ WHERE (main_jobevent.created > '{}' AND main_jobevent.created <= '{}')
+ ORDER BY main_jobevent.id ASC) TO STDOUT WITH CSV HEADER
+ '''.format(since.isoformat(),until.isoformat())
+ return _copy_table(table='events', query=events_query, path=full_path)
+
+@register('unified_jobs_table', '1.1', format='csv', description=_('Data on jobs run'), expensive=True)
+def unified_jobs_table(since, full_path, until, **kwargs):
unified_job_query = '''COPY (SELECT main_unifiedjob.id,
main_unifiedjob.polymorphic_ctype_id,
django_content_type.model,
main_unifiedjob.organization_id,
main_organization.name as organization_name,
main_job.inventory_id,
- main_inventory.name,
+ main_inventory.name as inventory_name,
main_unifiedjob.created,
main_unifiedjob.name,
main_unifiedjob.unified_job_template_id,
@@ -294,12 +340,16 @@ def copy_tables(since, full_path, subset=None):
LEFT JOIN main_job ON main_unifiedjob.id = main_job.unifiedjob_ptr_id
LEFT JOIN main_inventory ON main_job.inventory_id = main_inventory.id
LEFT JOIN main_organization ON main_organization.id = main_unifiedjob.organization_id
- WHERE (main_unifiedjob.created > {0} OR main_unifiedjob.finished > {0})
+ WHERE ((main_unifiedjob.created > '{0}' AND main_unifiedjob.created <= '{1}')
+ OR (main_unifiedjob.finished > '{0}' AND main_unifiedjob.finished <= '{1}'))
AND main_unifiedjob.launch_type != 'sync'
- ORDER BY main_unifiedjob.id ASC) TO STDOUT WITH CSV HEADER'''.format(since.strftime("'%Y-%m-%d %H:%M:%S'"))
- if not subset or 'unified_jobs' in subset:
- _copy_table(table='unified_jobs', query=unified_job_query, path=full_path)
+ ORDER BY main_unifiedjob.id ASC) TO STDOUT WITH CSV HEADER
+ '''.format(since.isoformat(),until.isoformat())
+ return _copy_table(table='unified_jobs', query=unified_job_query, path=full_path)
+
+@register('unified_job_template_table', '1.0', format='csv', description=_('Data on job templates'))
+def unified_job_template_table(since, full_path, **kwargs):
unified_job_template_query = '''COPY (SELECT main_unifiedjobtemplate.id,
main_unifiedjobtemplate.polymorphic_ctype_id,
django_content_type.model,
@@ -318,9 +368,11 @@ def copy_tables(since, full_path, subset=None):
FROM main_unifiedjobtemplate, django_content_type
WHERE main_unifiedjobtemplate.polymorphic_ctype_id = django_content_type.id
ORDER BY main_unifiedjobtemplate.id ASC) TO STDOUT WITH CSV HEADER'''
- if not subset or 'unified_job_template' in subset:
- _copy_table(table='unified_job_template', query=unified_job_template_query, path=full_path)
+ return _copy_table(table='unified_job_template', query=unified_job_template_query, path=full_path)
+
+@register('workflow_job_node_table', '1.0', format='csv', description=_('Data on workflow runs'), expensive=True)
+def workflow_job_node_table(since, full_path, until, **kwargs):
workflow_job_node_query = '''COPY (SELECT main_workflowjobnode.id,
main_workflowjobnode.created,
main_workflowjobnode.modified,
@@ -349,11 +401,14 @@ def copy_tables(since, full_path, subset=None):
FROM main_workflowjobnode_always_nodes
GROUP BY from_workflowjobnode_id
) always_nodes ON main_workflowjobnode.id = always_nodes.from_workflowjobnode_id
- WHERE main_workflowjobnode.modified > {}
- ORDER BY main_workflowjobnode.id ASC) TO STDOUT WITH CSV HEADER'''.format(since.strftime("'%Y-%m-%d %H:%M:%S'"))
- if not subset or 'workflow_job_node' in subset:
- _copy_table(table='workflow_job_node', query=workflow_job_node_query, path=full_path)
+ WHERE (main_workflowjobnode.modified > '{}' AND main_workflowjobnode.modified <= '{}')
+ ORDER BY main_workflowjobnode.id ASC) TO STDOUT WITH CSV HEADER
+ '''.format(since.isoformat(),until.isoformat())
+ return _copy_table(table='workflow_job_node', query=workflow_job_node_query, path=full_path)
+
+@register('workflow_job_template_node_table', '1.0', format='csv', description=_('Data on workflows'))
+def workflow_job_template_node_table(since, full_path, **kwargs):
workflow_job_template_node_query = '''COPY (SELECT main_workflowjobtemplatenode.id,
main_workflowjobtemplatenode.created,
main_workflowjobtemplatenode.modified,
@@ -381,7 +436,4 @@ def copy_tables(since, full_path, subset=None):
GROUP BY from_workflowjobtemplatenode_id
) always_nodes ON main_workflowjobtemplatenode.id = always_nodes.from_workflowjobtemplatenode_id
ORDER BY main_workflowjobtemplatenode.id ASC) TO STDOUT WITH CSV HEADER'''
- if not subset or 'workflow_job_template_node' in subset:
- _copy_table(table='workflow_job_template_node', query=workflow_job_template_node_query, path=full_path)
-
- return
+ return _copy_table(table='workflow_job_template_node', query=workflow_job_template_node_query, path=full_path)
diff --git a/awx/main/analytics/core.py b/awx/main/analytics/core.py
index bab62b4a3c..fe48fb30bf 100644
--- a/awx/main/analytics/core.py
+++ b/awx/main/analytics/core.py
@@ -14,17 +14,13 @@ from rest_framework.exceptions import PermissionDenied
from awx.conf.license import get_license
from awx.main.models import Job
from awx.main.access import access_registry
-from awx.main.models.ha import TowerAnalyticsState
from awx.main.utils import get_awx_http_client_headers, set_environ
-
-__all__ = ['register', 'gather', 'ship', 'table_version']
+__all__ = ['register', 'gather', 'ship']
logger = logging.getLogger('awx.main.analytics')
-manifest = dict()
-
def _valid_license():
try:
@@ -37,11 +33,38 @@ def _valid_license():
return True
-def register(key, version):
+def all_collectors():
+ from awx.main.analytics import collectors
+
+ collector_dict = {}
+ module = collectors
+ for name, func in inspect.getmembers(module):
+ if inspect.isfunction(func) and hasattr(func, '__awx_analytics_key__'):
+ key = func.__awx_analytics_key__
+ desc = func.__awx_analytics_description__ or ''
+ version = func.__awx_analytics_version__
+ collector_dict[key] = { 'name': key, 'version': version, 'description': desc}
+ return collector_dict
+
+
+def expensive_collectors():
+ from awx.main.analytics import collectors
+
+ ret = []
+ module = collectors
+ for name, func in inspect.getmembers(module):
+ if inspect.isfunction(func) and hasattr(func, '__awx_analytics_key__') and func.__awx_expensive__:
+ ret.append(func.__awx_analytics_key__)
+ return ret
+
+
+def register(key, version, description=None, format='json', expensive=False):
"""
A decorator used to register a function as a metric collector.
- Decorated functions should return JSON-serializable objects.
+ Decorated functions should do the following based on format:
+ - json: return JSON-serializable objects.
+ - csv: write CSV data to a filename named 'key'
@register('projects_by_scm_type', 1)
def projects_by_scm_type():
@@ -51,100 +74,153 @@ def register(key, version):
def decorate(f):
f.__awx_analytics_key__ = key
f.__awx_analytics_version__ = version
+ f.__awx_analytics_description__ = description
+ f.__awx_analytics_type__ = format
+ f.__awx_expensive__ = expensive
return f
return decorate
-def table_version(file_name, version):
-
- global manifest
- manifest[file_name] = version
-
- def decorate(f):
- return f
-
- return decorate
-
-
-def gather(dest=None, module=None, collection_type='scheduled'):
+def gather(dest=None, module=None, subset = None, since = None, until = now(), collection_type='scheduled'):
"""
Gather all defined metrics and write them as JSON files in a .tgz
:param dest: the (optional) absolute path to write a compressed tarball
- :pararm module: the module to search for registered analytic collector
+ :param module: the module to search for registered analytic collector
functions; defaults to awx.main.analytics.collectors
"""
+ def _write_manifest(destdir, manifest):
+ path = os.path.join(destdir, 'manifest.json')
+ with open(path, 'w', encoding='utf-8') as f:
+ try:
+ json.dump(manifest, f)
+ except Exception:
+ f.close()
+ os.remove(f.name)
+ logger.exception("Could not generate manifest.json")
- run_now = now()
- state = TowerAnalyticsState.get_solo()
- last_run = state.last_run
- logger.debug("Last analytics run was: {}".format(last_run))
+ last_run = since or settings.AUTOMATION_ANALYTICS_LAST_GATHER or (now() - timedelta(weeks=4))
+ logger.debug("Last analytics run was: {}".format(settings.AUTOMATION_ANALYTICS_LAST_GATHER))
- max_interval = now() - timedelta(weeks=4)
- if last_run < max_interval or not last_run:
- last_run = max_interval
-
if _valid_license() is False:
logger.exception("Invalid License provided, or No License Provided")
- return "Error: Invalid License provided, or No License Provided"
+ return None
if collection_type != 'dry-run' and not settings.INSIGHTS_TRACKING_STATE:
logger.error("Automation Analytics not enabled. Use --dry-run to gather locally without sending.")
- return
+ return None
- if module is None:
+ collector_list = []
+ if module:
+ collector_module = module
+ else:
from awx.main.analytics import collectors
- module = collectors
-
+ collector_module = collectors
+ for name, func in inspect.getmembers(collector_module):
+ if (
+ inspect.isfunction(func) and
+ hasattr(func, '__awx_analytics_key__') and
+ (not subset or name in subset)
+ ):
+ collector_list.append((name, func))
+ manifest = dict()
dest = dest or tempfile.mkdtemp(prefix='awx_analytics')
- for name, func in inspect.getmembers(module):
- if inspect.isfunction(func) and hasattr(func, '__awx_analytics_key__'):
+ gather_dir = os.path.join(dest, 'stage')
+ os.mkdir(gather_dir, 0o700)
+ num_splits = 1
+ for name, func in collector_list:
+ if func.__awx_analytics_type__ == 'json':
key = func.__awx_analytics_key__
- manifest['{}.json'.format(key)] = func.__awx_analytics_version__
- path = '{}.json'.format(os.path.join(dest, key))
+ path = '{}.json'.format(os.path.join(gather_dir, key))
with open(path, 'w', encoding='utf-8') as f:
try:
- if func.__name__ == 'query_info':
- json.dump(func(last_run, collection_type=collection_type), f)
- else:
- json.dump(func(last_run), f)
+ json.dump(func(last_run, collection_type=collection_type, until=until), f)
+ manifest['{}.json'.format(key)] = func.__awx_analytics_version__
except Exception:
logger.exception("Could not generate metric {}.json".format(key))
f.close()
os.remove(f.name)
-
- path = os.path.join(dest, 'manifest.json')
- with open(path, 'w', encoding='utf-8') as f:
- try:
- json.dump(manifest, f)
- except Exception:
- logger.exception("Could not generate manifest.json")
- f.close()
- os.remove(f.name)
+ elif func.__awx_analytics_type__ == 'csv':
+ key = func.__awx_analytics_key__
+ try:
+ files = func(last_run, full_path=gather_dir, until=until)
+ if files:
+ manifest['{}.csv'.format(key)] = func.__awx_analytics_version__
+ if len(files) > num_splits:
+ num_splits = len(files)
+ except Exception:
+ logger.exception("Could not generate metric {}.csv".format(key))
- try:
- collectors.copy_tables(since=last_run, full_path=dest)
- except Exception:
- logger.exception("Could not copy tables")
-
- # can't use isoformat() since it has colons, which GNU tar doesn't like
- tarname = '_'.join([
- settings.SYSTEM_UUID,
- run_now.strftime('%Y-%m-%d-%H%M%S%z')
- ])
- try:
- tgz = shutil.make_archive(
- os.path.join(os.path.dirname(dest), tarname),
- 'gztar',
- dest
- )
- return tgz
- except Exception:
- logger.exception("Failed to write analytics archive file")
- finally:
+ if not manifest:
+ # No data was collected
+ logger.warning("No data from {} to {}".format(last_run, until))
shutil.rmtree(dest)
+ return None
+
+ # Always include config.json if we're using our collectors
+ if 'config.json' not in manifest.keys() and not module:
+ from awx.main.analytics import collectors
+ config = collectors.config
+ path = '{}.json'.format(os.path.join(gather_dir, config.__awx_analytics_key__))
+ with open(path, 'w', encoding='utf-8') as f:
+ try:
+ json.dump(collectors.config(last_run), f)
+ manifest['config.json'] = config.__awx_analytics_version__
+ except Exception:
+ logger.exception("Could not generate metric {}.json".format(key))
+ f.close()
+ os.remove(f.name)
+ shutil.rmtree(dest)
+ return None
+
+ stage_dirs = [gather_dir]
+ if num_splits > 1:
+ for i in range(0, num_splits):
+ split_path = os.path.join(dest, 'split{}'.format(i))
+ os.mkdir(split_path, 0o700)
+ filtered_manifest = {}
+ shutil.copy(os.path.join(gather_dir, 'config.json'), split_path)
+ filtered_manifest['config.json'] = manifest['config.json']
+ suffix = '_split{}'.format(i)
+ for file in os.listdir(gather_dir):
+ if file.endswith(suffix):
+ old_file = os.path.join(gather_dir, file)
+ new_filename = file.replace(suffix, '')
+ new_file = os.path.join(split_path, new_filename)
+ shutil.move(old_file, new_file)
+ filtered_manifest[new_filename] = manifest[new_filename]
+ _write_manifest(split_path, filtered_manifest)
+ stage_dirs.append(split_path)
+
+ for item in list(manifest.keys()):
+ if not os.path.exists(os.path.join(gather_dir, item)):
+ manifest.pop(item)
+ _write_manifest(gather_dir, manifest)
+
+ tarfiles = []
+ try:
+ for i in range(0, len(stage_dirs)):
+ stage_dir = stage_dirs[i]
+ # can't use isoformat() since it has colons, which GNU tar doesn't like
+ tarname = '_'.join([
+ settings.SYSTEM_UUID,
+ until.strftime('%Y-%m-%d-%H%M%S%z'),
+ str(i)
+ ])
+ tgz = shutil.make_archive(
+ os.path.join(os.path.dirname(dest), tarname),
+ 'gztar',
+ stage_dir
+ )
+ tarfiles.append(tgz)
+ except Exception:
+ shutil.rmtree(stage_dir, ignore_errors = True)
+ logger.exception("Failed to write analytics archive file")
+ finally:
+ shutil.rmtree(dest, ignore_errors = True)
+ return tarfiles
def ship(path):
@@ -154,6 +230,9 @@ def ship(path):
if not path:
logger.error('Automation Analytics TAR not found')
return
+ if not os.path.exists(path):
+ logger.error('Automation Analytics TAR {} not found'.format(path))
+ return
if "Error:" in str(path):
return
try:
@@ -184,10 +263,7 @@ def ship(path):
if response.status_code >= 300:
return logger.exception('Upload failed with status {}, {}'.format(response.status_code,
response.text))
- run_now = now()
- state = TowerAnalyticsState.get_solo()
- state.last_run = run_now
- state.save()
finally:
# cleanup tar.gz
- os.remove(path)
+ if os.path.exists(path):
+ os.remove(path)
diff --git a/awx/main/conf.py b/awx/main/conf.py
index 8d091894d6..3b41c3a19b 100644
--- a/awx/main/conf.py
+++ b/awx/main/conf.py
@@ -2,7 +2,6 @@
import json
import logging
import os
-from distutils.version import LooseVersion as Version
# Django
from django.utils.translation import ugettext_lazy as _
@@ -149,7 +148,7 @@ register(
default='https://example.com',
schemes=('http', 'https'),
allow_plain_hostname=True, # Allow hostname only without TLD.
- label=_('Automation Analytics upload URL.'),
+ label=_('Automation Analytics upload URL'),
help_text=_('This setting is used to to configure data collection for the Automation Analytics dashboard'),
category=_('System'),
category_slug='system',
@@ -254,6 +253,7 @@ register(
help_text=_('The number of seconds to sleep between status checks for jobs running on isolated instances.'),
category=_('Jobs'),
category_slug='jobs',
+ unit=_('seconds'),
)
register(
@@ -265,6 +265,7 @@ register(
'This includes the time needed to copy source control files (playbooks) to the isolated instance.'),
category=_('Jobs'),
category_slug='jobs',
+ unit=_('seconds'),
)
register(
@@ -277,6 +278,7 @@ register(
'Value should be substantially greater than expected network latency.'),
category=_('Jobs'),
category_slug='jobs',
+ unit=_('seconds'),
)
register(
@@ -436,93 +438,12 @@ register(
category_slug='jobs',
)
-register(
- 'PRIMARY_GALAXY_URL',
- field_class=fields.URLField,
- required=False,
- allow_blank=True,
- label=_('Primary Galaxy Server URL'),
- help_text=_(
- 'For organizations that run their own Galaxy service, this gives the option to specify a '
- 'host as the primary galaxy server. Requirements will be downloaded from the primary if the '
- 'specific role or collection is available there. If the content is not avilable in the primary, '
- 'or if this field is left blank, it will default to galaxy.ansible.com.'
- ),
- category=_('Jobs'),
- category_slug='jobs'
-)
-
-register(
- 'PRIMARY_GALAXY_USERNAME',
- field_class=fields.CharField,
- required=False,
- allow_blank=True,
- label=_('Primary Galaxy Server Username'),
- help_text=_('(This setting is deprecated and will be removed in a future release) '
- 'For using a galaxy server at higher precedence than the public Ansible Galaxy. '
- 'The username to use for basic authentication against the Galaxy instance, '
- 'this is mutually exclusive with PRIMARY_GALAXY_TOKEN.'),
- category=_('Jobs'),
- category_slug='jobs'
-)
-
-register(
- 'PRIMARY_GALAXY_PASSWORD',
- field_class=fields.CharField,
- encrypted=True,
- required=False,
- allow_blank=True,
- label=_('Primary Galaxy Server Password'),
- help_text=_('(This setting is deprecated and will be removed in a future release) '
- 'For using a galaxy server at higher precedence than the public Ansible Galaxy. '
- 'The password to use for basic authentication against the Galaxy instance, '
- 'this is mutually exclusive with PRIMARY_GALAXY_TOKEN.'),
- category=_('Jobs'),
- category_slug='jobs'
-)
-
-register(
- 'PRIMARY_GALAXY_TOKEN',
- field_class=fields.CharField,
- encrypted=True,
- required=False,
- allow_blank=True,
- label=_('Primary Galaxy Server Token'),
- help_text=_('For using a galaxy server at higher precedence than the public Ansible Galaxy. '
- 'The token to use for connecting with the Galaxy instance, '
- 'this is mutually exclusive with corresponding username and password settings.'),
- category=_('Jobs'),
- category_slug='jobs'
-)
-
-register(
- 'PRIMARY_GALAXY_AUTH_URL',
- field_class=fields.CharField,
- required=False,
- allow_blank=True,
- label=_('Primary Galaxy Authentication URL'),
- help_text=_('For using a galaxy server at higher precedence than the public Ansible Galaxy. '
- 'The token_endpoint of a Keycloak server.'),
- category=_('Jobs'),
- category_slug='jobs'
-)
-
-register(
- 'PUBLIC_GALAXY_ENABLED',
- field_class=fields.BooleanField,
- default=True,
- label=_('Allow Access to Public Galaxy'),
- help_text=_('Allow or deny access to the public Ansible Galaxy during project updates.'),
- category=_('Jobs'),
- category_slug='jobs'
-)
-
register(
'GALAXY_IGNORE_CERTS',
field_class=fields.BooleanField,
default=False,
label=_('Ignore Ansible Galaxy SSL Certificate Verification'),
- help_text=_('If set to true, certificate validation will not be done when'
+ help_text=_('If set to true, certificate validation will not be done when '
'installing content from any Galaxy server.'),
category=_('Jobs'),
category_slug='jobs'
@@ -579,6 +500,7 @@ register(
'timeout should be imposed. A timeout set on an individual job template will override this.'),
category=_('Jobs'),
category_slug='jobs',
+ unit=_('seconds'),
)
register(
@@ -591,6 +513,7 @@ register(
'timeout should be imposed. A timeout set on an individual inventory source will override this.'),
category=_('Jobs'),
category_slug='jobs',
+ unit=_('seconds'),
)
register(
@@ -603,6 +526,7 @@ register(
'timeout should be imposed. A timeout set on an individual project will override this.'),
category=_('Jobs'),
category_slug='jobs',
+ unit=_('seconds'),
)
register(
@@ -617,6 +541,7 @@ register(
'Use a value of 0 to indicate that no timeout should be imposed.'),
category=_('Jobs'),
category_slug='jobs',
+ unit=_('seconds'),
)
register(
@@ -624,7 +549,7 @@ register(
field_class=fields.IntegerField,
allow_null=False,
default=200,
- label=_('Maximum number of forks per job.'),
+ label=_('Maximum number of forks per job'),
help_text=_('Saving a Job Template with more than this number of forks will result in an error. '
'When set to 0, no limit is applied.'),
category=_('Jobs'),
@@ -754,6 +679,7 @@ register(
'aggregator protocols.'),
category=_('Logging'),
category_slug='logging',
+ unit=_('seconds'),
)
register(
'LOG_AGGREGATOR_VERIFY_CERT',
@@ -834,7 +760,8 @@ register(
default=14400, # every 4 hours
min_value=1800, # every 30 minutes
category=_('System'),
- category_slug='system'
+ category_slug='system',
+ unit=_('seconds'),
)
@@ -856,84 +783,4 @@ def logging_validate(serializer, attrs):
return attrs
-def galaxy_validate(serializer, attrs):
- """Ansible Galaxy config options have mutual exclusivity rules, these rules
- are enforced here on serializer validation so that users will not be able
- to save settings which obviously break all project updates.
- """
- prefix = 'PRIMARY_GALAXY_'
- errors = {}
-
- def _new_value(setting_name):
- if setting_name in attrs:
- return attrs[setting_name]
- elif not serializer.instance:
- return ''
- return getattr(serializer.instance, setting_name, '')
-
- if not _new_value('PRIMARY_GALAXY_URL'):
- if _new_value('PUBLIC_GALAXY_ENABLED') is False:
- msg = _('A URL for Primary Galaxy must be defined before disabling public Galaxy.')
- # put error in both keys because UI has trouble with errors in toggles
- for key in ('PRIMARY_GALAXY_URL', 'PUBLIC_GALAXY_ENABLED'):
- errors.setdefault(key, [])
- errors[key].append(msg)
- raise serializers.ValidationError(errors)
-
- from awx.main.constants import GALAXY_SERVER_FIELDS
- if not any('{}{}'.format(prefix, subfield.upper()) in attrs for subfield in GALAXY_SERVER_FIELDS):
- return attrs
-
- galaxy_data = {}
- for subfield in GALAXY_SERVER_FIELDS:
- galaxy_data[subfield] = _new_value('{}{}'.format(prefix, subfield.upper()))
- if not galaxy_data['url']:
- for k, v in galaxy_data.items():
- if v:
- setting_name = '{}{}'.format(prefix, k.upper())
- errors.setdefault(setting_name, [])
- errors[setting_name].append(_(
- 'Cannot provide field if PRIMARY_GALAXY_URL is not set.'
- ))
- for k in GALAXY_SERVER_FIELDS:
- if galaxy_data[k]:
- setting_name = '{}{}'.format(prefix, k.upper())
- if (not serializer.instance) or (not getattr(serializer.instance, setting_name, '')):
- # new auth is applied, so check if compatible with version
- from awx.main.utils import get_ansible_version
- current_version = get_ansible_version()
- min_version = '2.9'
- if Version(current_version) < Version(min_version):
- errors.setdefault(setting_name, [])
- errors[setting_name].append(_(
- 'Galaxy server settings are not available until Ansible {min_version}, '
- 'you are running {current_version}.'
- ).format(min_version=min_version, current_version=current_version))
- if (galaxy_data['password'] or galaxy_data['username']) and (galaxy_data['token'] or galaxy_data['auth_url']):
- for k in ('password', 'username', 'token', 'auth_url'):
- setting_name = '{}{}'.format(prefix, k.upper())
- if setting_name in attrs:
- errors.setdefault(setting_name, [])
- errors[setting_name].append(_(
- 'Setting Galaxy token and authentication URL is mutually exclusive with username and password.'
- ))
- if bool(galaxy_data['username']) != bool(galaxy_data['password']):
- msg = _('If authenticating via username and password, both must be provided.')
- for k in ('username', 'password'):
- setting_name = '{}{}'.format(prefix, k.upper())
- errors.setdefault(setting_name, [])
- errors[setting_name].append(msg)
- if bool(galaxy_data['token']) != bool(galaxy_data['auth_url']):
- msg = _('If authenticating via token, both token and authentication URL must be provided.')
- for k in ('token', 'auth_url'):
- setting_name = '{}{}'.format(prefix, k.upper())
- errors.setdefault(setting_name, [])
- errors[setting_name].append(msg)
-
- if errors:
- raise serializers.ValidationError(errors)
- return attrs
-
-
register_validate('logging', logging_validate)
-register_validate('jobs', galaxy_validate)
diff --git a/awx/main/constants.py b/awx/main/constants.py
index c0382c7504..323f61f311 100644
--- a/awx/main/constants.py
+++ b/awx/main/constants.py
@@ -50,7 +50,3 @@ LOGGER_BLOCKLIST = (
# loggers that may be called getting logging settings
'awx.conf'
)
-
-# these correspond to both AWX and Ansible settings to keep naming consistent
-# for instance, settings.PRIMARY_GALAXY_AUTH_URL vs env var ANSIBLE_GALAXY_SERVER_FOO_AUTH_URL
-GALAXY_SERVER_FIELDS = ('url', 'username', 'password', 'token', 'auth_url')
diff --git a/awx/main/consumers.py b/awx/main/consumers.py
index d32219b3ac..b6d8872ebd 100644
--- a/awx/main/consumers.py
+++ b/awx/main/consumers.py
@@ -1,5 +1,3 @@
-import collections
-import functools
import json
import logging
import time
@@ -14,40 +12,12 @@ from django.contrib.auth.models import User
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from channels.layers import get_channel_layer
from channels.db import database_sync_to_async
-from channels_redis.core import RedisChannelLayer
logger = logging.getLogger('awx.main.consumers')
XRF_KEY = '_auth_user_xrf'
-class BoundedQueue(asyncio.Queue):
-
- def put_nowait(self, item):
- if self.full():
- # dispose the oldest item
- # if we actually get into this code block, it likely means that
- # this specific consumer has stopped reading
- # unfortunately, channels_redis will just happily continue to
- # queue messages specific to their channel until the heat death
- # of the sun: https://github.com/django/channels_redis/issues/212
- # this isn't a huge deal for browser clients that disconnect,
- # but it *does* cause a problem for our global broadcast topic
- # that's used to broadcast messages to peers in a cluster
- # if we get into this code block, it's better to drop messages
- # than to continue to malloc() forever
- self.get_nowait()
- return super(BoundedQueue, self).put_nowait(item)
-
-
-class ExpiringRedisChannelLayer(RedisChannelLayer):
- def __init__(self, *args, **kw):
- super(ExpiringRedisChannelLayer, self).__init__(*args, **kw)
- self.receive_buffer = collections.defaultdict(
- functools.partial(BoundedQueue, self.capacity)
- )
-
-
class WebsocketSecretAuthHelper:
"""
Middlewareish for websockets to verify node websocket broadcast interconnect.
diff --git a/awx/main/credential_plugins/hashivault.py b/awx/main/credential_plugins/hashivault.py
index 28f213061b..7e262912a4 100644
--- a/awx/main/credential_plugins/hashivault.py
+++ b/awx/main/credential_plugins/hashivault.py
@@ -40,6 +40,13 @@ base_inputs = {
'multiline': False,
'secret': True,
'help_text': _('The Secret ID for AppRole Authentication')
+ }, {
+ 'id': 'default_auth_path',
+ 'label': _('Path to Approle Auth'),
+ 'type': 'string',
+ 'multiline': False,
+ 'default': 'approle',
+ 'help_text': _('The AppRole Authentication path to use if one isn\'t provided in the metadata when linking to an input field. Defaults to \'approle\'')
}
],
'metadata': [{
@@ -47,10 +54,11 @@ base_inputs = {
'label': _('Path to Secret'),
'type': 'string',
'help_text': _('The path to the secret stored in the secret backend e.g, /some/secret/')
- },{
+ }, {
'id': 'auth_path',
'label': _('Path to Auth'),
'type': 'string',
+ 'multiline': False,
'help_text': _('The path where the Authentication method is mounted e.g, approle')
}],
'required': ['url', 'secret_path'],
@@ -118,7 +126,9 @@ def handle_auth(**kwargs):
def approle_auth(**kwargs):
role_id = kwargs['role_id']
secret_id = kwargs['secret_id']
- auth_path = kwargs.get('auth_path') or 'approle'
+ # we first try to use the 'auth_path' from the metadata
+ # if not found we try to fetch the 'default_auth_path' from inputs
+ auth_path = kwargs.get('auth_path') or kwargs['default_auth_path']
url = urljoin(kwargs['url'], 'v1')
cacert = kwargs.get('cacert', None)
diff --git a/awx/main/dispatch/control.py b/awx/main/dispatch/control.py
index 6b3c13499d..47cc60b40d 100644
--- a/awx/main/dispatch/control.py
+++ b/awx/main/dispatch/control.py
@@ -2,6 +2,9 @@ import logging
import uuid
import json
+from django.conf import settings
+import redis
+
from awx.main.dispatch import get_local_queuename
from . import pg_bus_conn
@@ -21,7 +24,15 @@ class Control(object):
self.queuename = host or get_local_queuename()
def status(self, *args, **kwargs):
- return self.control_with_reply('status', *args, **kwargs)
+ r = redis.Redis.from_url(settings.BROKER_URL)
+ if self.service == 'dispatcher':
+ stats = r.get(f'awx_{self.service}_statistics') or b''
+ return stats.decode('utf-8')
+ else:
+ workers = []
+ for key in r.keys('awx_callback_receiver_statistics_*'):
+ workers.append(r.get(key).decode('utf-8'))
+ return '\n'.join(workers)
def running(self, *args, **kwargs):
return self.control_with_reply('running', *args, **kwargs)
diff --git a/awx/main/dispatch/pool.py b/awx/main/dispatch/pool.py
index f5b38262ad..dc97402788 100644
--- a/awx/main/dispatch/pool.py
+++ b/awx/main/dispatch/pool.py
@@ -5,6 +5,7 @@ import signal
import sys
import time
import traceback
+from datetime import datetime
from uuid import uuid4
import collections
@@ -27,6 +28,12 @@ else:
logger = logging.getLogger('awx.main.dispatch')
+class NoOpResultQueue(object):
+
+ def put(self, item):
+ pass
+
+
class PoolWorker(object):
'''
Used to track a worker child process and its pending and finished messages.
@@ -56,11 +63,13 @@ class PoolWorker(object):
It is "idle" when self.managed_tasks is empty.
'''
- def __init__(self, queue_size, target, args):
+ track_managed_tasks = False
+
+ def __init__(self, queue_size, target, args, **kwargs):
self.messages_sent = 0
self.messages_finished = 0
self.managed_tasks = collections.OrderedDict()
- self.finished = MPQueue(queue_size)
+ self.finished = MPQueue(queue_size) if self.track_managed_tasks else NoOpResultQueue()
self.queue = MPQueue(queue_size)
self.process = Process(target=target, args=(self.queue, self.finished) + args)
self.process.daemon = True
@@ -74,7 +83,8 @@ class PoolWorker(object):
if not body.get('uuid'):
body['uuid'] = str(uuid4())
uuid = body['uuid']
- self.managed_tasks[uuid] = body
+ if self.track_managed_tasks:
+ self.managed_tasks[uuid] = body
self.queue.put(body, block=True, timeout=5)
self.messages_sent += 1
self.calculate_managed_tasks()
@@ -111,6 +121,8 @@ class PoolWorker(object):
return str(self.process.exitcode)
def calculate_managed_tasks(self):
+ if not self.track_managed_tasks:
+ return
# look to see if any tasks were finished
finished = []
for _ in range(self.finished.qsize()):
@@ -135,6 +147,8 @@ class PoolWorker(object):
@property
def current_task(self):
+ if not self.track_managed_tasks:
+ return None
self.calculate_managed_tasks()
# the task at [0] is the one that's running right now (or is about to
# be running)
@@ -145,6 +159,8 @@ class PoolWorker(object):
@property
def orphaned_tasks(self):
+ if not self.track_managed_tasks:
+ return []
orphaned = []
if not self.alive:
# if this process had a running task that never finished,
@@ -179,6 +195,11 @@ class PoolWorker(object):
return not self.busy
+class StatefulPoolWorker(PoolWorker):
+
+ track_managed_tasks = True
+
+
class WorkerPool(object):
'''
Creates a pool of forked PoolWorkers.
@@ -200,6 +221,7 @@ class WorkerPool(object):
)
'''
+ pool_cls = PoolWorker
debug_meta = ''
def __init__(self, min_workers=None, queue_size=None):
@@ -225,7 +247,7 @@ class WorkerPool(object):
# for the DB and cache connections (that way lies race conditions)
django_connection.close()
django_cache.close()
- worker = PoolWorker(self.queue_size, self.target, (idx,) + self.target_args)
+ worker = self.pool_cls(self.queue_size, self.target, (idx,) + self.target_args)
self.workers.append(worker)
try:
worker.start()
@@ -236,13 +258,13 @@ class WorkerPool(object):
return idx, worker
def debug(self, *args, **kwargs):
- self.cleanup()
tmpl = Template(
+ 'Recorded at: {{ dt }} \n'
'{{ pool.name }}[pid:{{ pool.pid }}] workers total={{ workers|length }} {{ meta }} \n'
'{% for w in workers %}'
'. worker[pid:{{ w.pid }}]{% if not w.alive %} GONE exit={{ w.exitcode }}{% endif %}'
' sent={{ w.messages_sent }}'
- ' finished={{ w.messages_finished }}'
+ '{% if w.messages_finished %} finished={{ w.messages_finished }}{% endif %}'
' qsize={{ w.managed_tasks|length }}'
' rss={{ w.mb }}MB'
'{% for task in w.managed_tasks.values() %}'
@@ -260,7 +282,11 @@ class WorkerPool(object):
'\n'
'{% endfor %}'
)
- return tmpl.render(pool=self, workers=self.workers, meta=self.debug_meta)
+ now = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC')
+ return tmpl.render(
+ pool=self, workers=self.workers, meta=self.debug_meta,
+ dt=now
+ )
def write(self, preferred_queue, body):
queue_order = sorted(range(len(self.workers)), key=lambda x: -1 if x==preferred_queue else x)
@@ -293,6 +319,8 @@ class AutoscalePool(WorkerPool):
down based on demand
'''
+ pool_cls = StatefulPoolWorker
+
def __init__(self, *args, **kwargs):
self.max_workers = kwargs.pop('max_workers', None)
super(AutoscalePool, self).__init__(*args, **kwargs)
@@ -309,6 +337,10 @@ class AutoscalePool(WorkerPool):
# max workers can't be less than min_workers
self.max_workers = max(self.min_workers, self.max_workers)
+ def debug(self, *args, **kwargs):
+ self.cleanup()
+ return super(AutoscalePool, self).debug(*args, **kwargs)
+
@property
def should_grow(self):
if len(self.workers) < self.min_workers:
diff --git a/awx/main/dispatch/worker/base.py b/awx/main/dispatch/worker/base.py
index 7001cd9bb9..8b44c71e43 100644
--- a/awx/main/dispatch/worker/base.py
+++ b/awx/main/dispatch/worker/base.py
@@ -43,6 +43,9 @@ class WorkerSignalHandler:
class AWXConsumerBase(object):
+
+ last_stats = time.time()
+
def __init__(self, name, worker, queues=[], pool=None):
self.should_stop = False
@@ -54,6 +57,7 @@ class AWXConsumerBase(object):
if pool is None:
self.pool = WorkerPool()
self.pool.init_workers(self.worker.work_loop)
+ self.redis = redis.Redis.from_url(settings.BROKER_URL)
@property
def listening_on(self):
@@ -99,6 +103,16 @@ class AWXConsumerBase(object):
queue = 0
self.pool.write(queue, body)
self.total_messages += 1
+ self.record_statistics()
+
+ def record_statistics(self):
+ if time.time() - self.last_stats > 1: # buffer stat recording to once per second
+ try:
+ self.redis.set(f'awx_{self.name}_statistics', self.pool.debug())
+ self.last_stats = time.time()
+ except Exception:
+ logger.exception(f"encountered an error communicating with redis to store {self.name} statistics")
+ self.last_stats = time.time()
def run(self, *args, **kwargs):
signal.signal(signal.SIGINT, self.stop)
@@ -118,23 +132,9 @@ class AWXConsumerRedis(AWXConsumerBase):
super(AWXConsumerRedis, self).run(*args, **kwargs)
self.worker.on_start()
- time_to_sleep = 1
while True:
- queue = redis.Redis.from_url(settings.BROKER_URL)
- while True:
- try:
- res = queue.blpop(self.queues)
- time_to_sleep = 1
- res = json.loads(res[1])
- self.process_task(res)
- except redis.exceptions.RedisError:
- time_to_sleep = min(time_to_sleep * 2, 30)
- logger.exception(f"encountered an error communicating with redis. Reconnect attempt in {time_to_sleep} seconds")
- time.sleep(time_to_sleep)
- except (json.JSONDecodeError, KeyError):
- logger.exception("failed to decode JSON message from redis")
- if self.should_stop:
- return
+ logger.debug(f'{os.getpid()} is alive')
+ time.sleep(60)
class AWXConsumerPG(AWXConsumerBase):
diff --git a/awx/main/dispatch/worker/callback.py b/awx/main/dispatch/worker/callback.py
index 1314f33f7c..79033e329a 100644
--- a/awx/main/dispatch/worker/callback.py
+++ b/awx/main/dispatch/worker/callback.py
@@ -1,4 +1,5 @@
import cProfile
+import json
import logging
import os
import pstats
@@ -6,12 +7,15 @@ import signal
import tempfile
import time
import traceback
-from queue import Empty as QueueEmpty
from django.conf import settings
from django.utils.timezone import now as tz_now
from django.db import DatabaseError, OperationalError, connection as django_connection
-from django.db.utils import InterfaceError, InternalError, IntegrityError
+from django.db.utils import InterfaceError, InternalError
+
+import psutil
+
+import redis
from awx.main.consumers import emit_channel_notification
from awx.main.models import (JobEvent, AdHocCommandEvent, ProjectUpdateEvent,
@@ -24,10 +28,6 @@ from .base import BaseWorker
logger = logging.getLogger('awx.main.commands.run_callback_receiver')
-# the number of seconds to buffer events in memory before flushing
-# using JobEvent.objects.bulk_create()
-BUFFER_SECONDS = .1
-
class CallbackBrokerWorker(BaseWorker):
'''
@@ -39,21 +39,57 @@ class CallbackBrokerWorker(BaseWorker):
'''
MAX_RETRIES = 2
+ last_stats = time.time()
+ total = 0
+ last_event = ''
prof = None
def __init__(self):
self.buff = {}
+ self.pid = os.getpid()
+ self.redis = redis.Redis.from_url(settings.BROKER_URL)
+ for key in self.redis.keys('awx_callback_receiver_statistics_*'):
+ self.redis.delete(key)
def read(self, queue):
try:
- return queue.get(block=True, timeout=BUFFER_SECONDS)
- except QueueEmpty:
- return {'event': 'FLUSH'}
+ res = self.redis.blpop(settings.CALLBACK_QUEUE, timeout=settings.JOB_EVENT_BUFFER_SECONDS)
+ if res is None:
+ return {'event': 'FLUSH'}
+ self.total += 1
+ return json.loads(res[1])
+ except redis.exceptions.RedisError:
+ logger.exception("encountered an error communicating with redis")
+ time.sleep(1)
+ except (json.JSONDecodeError, KeyError):
+ logger.exception("failed to decode JSON message from redis")
+ finally:
+ self.record_statistics()
+ return {'event': 'FLUSH'}
+
+ def record_statistics(self):
+ # buffer stat recording to once per (by default) 5s
+ if time.time() - self.last_stats > settings.JOB_EVENT_STATISTICS_INTERVAL:
+ try:
+ self.redis.set(f'awx_callback_receiver_statistics_{self.pid}', self.debug())
+ self.last_stats = time.time()
+ except Exception:
+ logger.exception("encountered an error communicating with redis")
+ self.last_stats = time.time()
+
+ def debug(self):
+ return f'. worker[pid:{self.pid}] sent={self.total} rss={self.mb}MB {self.last_event}'
+
+ @property
+ def mb(self):
+ return '{:0.3f}'.format(
+ psutil.Process(self.pid).memory_info().rss / 1024.0 / 1024.0
+ )
def toggle_profiling(self, *args):
if self.prof:
self.prof.disable()
- filename = f'callback-{os.getpid()}.pstats'
+ filename = f'callback-{self.pid}.pstats'
filepath = os.path.join(tempfile.gettempdir(), filename)
with open(filepath, 'w') as f:
pstats.Stats(self.prof, stream=f).sort_stats('cumulative').print_stats()
@@ -84,20 +120,12 @@ class CallbackBrokerWorker(BaseWorker):
e.modified = now
try:
cls.objects.bulk_create(events)
- except Exception as exc:
+ except Exception:
# if an exception occurs, we should re-attempt to save the
# events one-by-one, because something in the list is
- # broken/stale (e.g., an IntegrityError on a specific event)
+ # broken/stale
for e in events:
try:
- if (
- isinstance(exc, IntegrityError) and
- getattr(e, 'host_id', '')
- ):
- # this is one potential IntegrityError we can
- # work around - if the host disappears before
- # the event can be processed
- e.host_id = None
e.save()
except Exception:
logger.exception('Database Error Saving Job Event')
@@ -108,6 +136,8 @@ class CallbackBrokerWorker(BaseWorker):
def perform_work(self, body):
try:
flush = body.get('event') == 'FLUSH'
+ if flush:
+ self.last_event = ''
if not flush:
event_map = {
'job_id': JobEvent,
@@ -123,6 +153,8 @@ class CallbackBrokerWorker(BaseWorker):
job_identifier = body[key]
break
+ self.last_event = f'\n\t- {cls.__name__} for #{job_identifier} ({body.get("event", "")} {body.get("uuid", "")})' # noqa
+
if body.get('event') == 'EOF':
try:
final_counter = body.get('final_counter', 0)
diff --git a/awx/main/management/commands/create_preload_data.py b/awx/main/management/commands/create_preload_data.py
index 297622af46..9b1d131735 100644
--- a/awx/main/management/commands/create_preload_data.py
+++ b/awx/main/management/commands/create_preload_data.py
@@ -42,6 +42,16 @@ class Command(BaseCommand):
},
created_by=superuser)
c.admin_role.members.add(superuser)
+ public_galaxy_credential = Credential(
+ name='Ansible Galaxy',
+ managed_by_tower=True,
+ credential_type=CredentialType.objects.get(kind='galaxy'),
+ inputs = {
+ 'url': 'https://galaxy.ansible.com/'
+ }
+ )
+ public_galaxy_credential.save()
+ o.galaxy_credentials.add(public_galaxy_credential)
i = Inventory.objects.create(name='Demo Inventory',
organization=o,
created_by=superuser)
diff --git a/awx/main/management/commands/gather_analytics.py b/awx/main/management/commands/gather_analytics.py
index aa096d6f28..b5e8427955 100644
--- a/awx/main/management/commands/gather_analytics.py
+++ b/awx/main/management/commands/gather_analytics.py
@@ -1,6 +1,9 @@
import logging
+
from awx.main.analytics import gather, ship
+from dateutil import parser
from django.core.management.base import BaseCommand
+from django.utils.timezone import now
class Command(BaseCommand):
@@ -15,6 +18,10 @@ class Command(BaseCommand):
help='Gather analytics without shipping. Works even if analytics are disabled in settings.')
parser.add_argument('--ship', dest='ship', action='store_true',
help='Enable to ship metrics to the Red Hat Cloud')
+ parser.add_argument('--since', dest='since', action='store',
+ help='Start date for collection')
+ parser.add_argument('--until', dest='until', action='store',
+ help='End date for collection')
def init_logging(self):
self.logger = logging.getLogger('awx.main.analytics')
@@ -28,11 +35,28 @@ class Command(BaseCommand):
self.init_logging()
opt_ship = options.get('ship')
opt_dry_run = options.get('dry-run')
+ opt_since = options.get('since') or None
+ opt_until = options.get('until') or None
+
+ if opt_since:
+ since = parser.parse(opt_since)
+ else:
+ since = None
+ if opt_until:
+ until = parser.parse(opt_until)
+ else:
+ until = now()
+
if opt_ship and opt_dry_run:
self.logger.error('Both --ship and --dry-run cannot be processed at the same time.')
return
- tgz = gather(collection_type='manual' if not opt_dry_run else 'dry-run')
- if tgz:
- self.logger.debug(tgz)
+ tgzfiles = gather(collection_type='manual' if not opt_dry_run else 'dry-run', since = since, until = until)
+ if tgzfiles:
+ for tgz in tgzfiles:
+ self.logger.info(tgz)
+ else:
+ self.logger.error('No analytics collected')
if opt_ship:
- ship(tgz)
+ if tgzfiles:
+ for tgz in tgzfiles:
+ ship(tgz)
diff --git a/awx/main/management/commands/run_callback_receiver.py b/awx/main/management/commands/run_callback_receiver.py
index 7e28330067..23922a7537 100644
--- a/awx/main/management/commands/run_callback_receiver.py
+++ b/awx/main/management/commands/run_callback_receiver.py
@@ -4,6 +4,7 @@
from django.conf import settings
from django.core.management.base import BaseCommand
+from awx.main.dispatch.control import Control
from awx.main.dispatch.worker import AWXConsumerRedis, CallbackBrokerWorker
@@ -15,7 +16,14 @@ class Command(BaseCommand):
'''
help = 'Launch the job callback receiver'
+ def add_arguments(self, parser):
+ parser.add_argument('--status', dest='status', action='store_true',
+ help='print the internal state of any running dispatchers')
+
def handle(self, *arg, **options):
+ if options.get('status'):
+ print(Control('callback_receiver').status())
+ return
consumer = None
try:
consumer = AWXConsumerRedis(
diff --git a/awx/main/migrations/0120_galaxy_credentials.py b/awx/main/migrations/0120_galaxy_credentials.py
new file mode 100644
index 0000000000..a94c22e30b
--- /dev/null
+++ b/awx/main/migrations/0120_galaxy_credentials.py
@@ -0,0 +1,51 @@
+# Generated by Django 2.2.11 on 2020-08-04 15:19
+
+import logging
+
+import awx.main.fields
+from awx.main.utils.encryption import encrypt_field, decrypt_field
+
+from django.db import migrations, models
+from django.utils.timezone import now
+import django.db.models.deletion
+
+from awx.main.migrations import _galaxy as galaxy
+from awx.main.models import CredentialType as ModernCredentialType
+from awx.main.utils.common import set_current_apps
+
+logger = logging.getLogger('awx.main.migrations')
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('main', '0119_inventory_plugins'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='credentialtype',
+ name='kind',
+ field=models.CharField(choices=[('ssh', 'Machine'), ('vault', 'Vault'), ('net', 'Network'), ('scm', 'Source Control'), ('cloud', 'Cloud'), ('token', 'Personal Access Token'), ('insights', 'Insights'), ('external', 'External'), ('kubernetes', 'Kubernetes'), ('galaxy', 'Galaxy/Automation Hub')], max_length=32),
+ ),
+ migrations.CreateModel(
+ name='OrganizationGalaxyCredentialMembership',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('position', models.PositiveIntegerField(db_index=True, default=None, null=True)),
+ ('credential', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Credential')),
+ ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Organization')),
+ ],
+ ),
+ migrations.AddField(
+ model_name='organization',
+ name='galaxy_credentials',
+ field=awx.main.fields.OrderedManyToManyField(blank=True, related_name='organization_galaxy_credentials', through='main.OrganizationGalaxyCredentialMembership', to='main.Credential'),
+ ),
+ migrations.AddField(
+ model_name='credential',
+ name='managed_by_tower',
+ field=models.BooleanField(default=False, editable=False),
+ ),
+ migrations.RunPython(galaxy.migrate_galaxy_settings)
+ ]
diff --git a/awx/main/migrations/0121_delete_toweranalyticsstate.py b/awx/main/migrations/0121_delete_toweranalyticsstate.py
new file mode 100644
index 0000000000..d1e1ceb37c
--- /dev/null
+++ b/awx/main/migrations/0121_delete_toweranalyticsstate.py
@@ -0,0 +1,16 @@
+# Generated by Django 2.2.11 on 2020-07-24 17:41
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('main', '0120_galaxy_credentials'),
+ ]
+
+ operations = [
+ migrations.DeleteModel(
+ name='TowerAnalyticsState',
+ ),
+ ]
diff --git a/awx/main/migrations/_galaxy.py b/awx/main/migrations/_galaxy.py
new file mode 100644
index 0000000000..b85b7b3aaf
--- /dev/null
+++ b/awx/main/migrations/_galaxy.py
@@ -0,0 +1,125 @@
+# Generated by Django 2.2.11 on 2020-08-04 15:19
+
+import logging
+
+from awx.main.utils.encryption import encrypt_field, decrypt_field
+
+from django.conf import settings
+from django.utils.timezone import now
+
+from awx.main.models import CredentialType as ModernCredentialType
+from awx.main.utils.common import set_current_apps
+
+logger = logging.getLogger('awx.main.migrations')
+
+
+def migrate_galaxy_settings(apps, schema_editor):
+ Organization = apps.get_model('main', 'Organization')
+ if Organization.objects.count() == 0:
+ # nothing to migrate
+ return
+ set_current_apps(apps)
+ ModernCredentialType.setup_tower_managed_defaults()
+ CredentialType = apps.get_model('main', 'CredentialType')
+ Credential = apps.get_model('main', 'Credential')
+ Setting = apps.get_model('conf', 'Setting')
+
+ galaxy_type = CredentialType.objects.get(kind='galaxy')
+ private_galaxy_url = Setting.objects.filter(key='PRIMARY_GALAXY_URL').first()
+
+ # by default, prior versions of AWX/Tower automatically pulled content
+ # from galaxy.ansible.com
+ public_galaxy_enabled = True
+ public_galaxy_setting = Setting.objects.filter(key='PUBLIC_GALAXY_ENABLED').first()
+ if public_galaxy_setting and public_galaxy_setting.value is False:
+ # ...UNLESS this behavior was explicitly disabled via this setting
+ public_galaxy_enabled = False
+
+ public_galaxy_credential = Credential(
+ created=now(),
+ modified=now(),
+ name='Ansible Galaxy',
+ managed_by_tower=True,
+ credential_type=galaxy_type,
+ inputs = {
+ 'url': 'https://galaxy.ansible.com/'
+ }
+ )
+ public_galaxy_credential.save()
+
+ for org in Organization.objects.all():
+ if private_galaxy_url and private_galaxy_url.value:
+ # If a setting exists for a private Galaxy URL, make a credential for it
+ username = Setting.objects.filter(key='PRIMARY_GALAXY_USERNAME').first()
+ password = Setting.objects.filter(key='PRIMARY_GALAXY_PASSWORD').first()
+ if (username and username.value) or (password and password.value):
+ logger.error(
+ f'Specifying HTTP basic auth for the Ansible Galaxy API '
+ f'({private_galaxy_url.value}) is no longer supported. '
+ 'Please provide an API token instead after your upgrade '
+ 'has completed',
+ )
+ inputs = {
+ 'url': private_galaxy_url.value
+ }
+ token = Setting.objects.filter(key='PRIMARY_GALAXY_TOKEN').first()
+ if token and token.value:
+ inputs['token'] = decrypt_field(token, 'value')
+ auth_url = Setting.objects.filter(key='PRIMARY_GALAXY_AUTH_URL').first()
+ if auth_url and auth_url.value:
+ inputs['auth_url'] = auth_url.value
+ name = f'Private Galaxy ({private_galaxy_url.value})'
+ if 'cloud.redhat.com' in inputs['url']:
+ name = f'Ansible Automation Hub ({private_galaxy_url.value})'
+ cred = Credential(
+ created=now(),
+ modified=now(),
+ name=name,
+ organization=org,
+ credential_type=galaxy_type,
+ inputs=inputs
+ )
+ cred.save()
+ if token and token.value:
+ # encrypt based on the primary key from the prior save
+ cred.inputs['token'] = encrypt_field(cred, 'token')
+ cred.save()
+ org.galaxy_credentials.add(cred)
+
+ fallback_servers = getattr(settings, 'FALLBACK_GALAXY_SERVERS', [])
+ for fallback in fallback_servers:
+ url = fallback.get('url', None)
+ auth_url = fallback.get('auth_url', None)
+ username = fallback.get('username', None)
+ password = fallback.get('password', None)
+ token = fallback.get('token', None)
+ if username or password:
+ logger.error(
+ f'Specifying HTTP basic auth for the Ansible Galaxy API '
+ f'({url}) is no longer supported. '
+ 'Please provide an API token instead after your upgrade '
+ 'has completed',
+ )
+ inputs = {'url': url}
+ if token:
+ inputs['token'] = token
+ if auth_url:
+ inputs['auth_url'] = auth_url
+ cred = Credential(
+ created=now(),
+ modified=now(),
+ name=f'Ansible Galaxy ({url})',
+ organization=org,
+ credential_type=galaxy_type,
+ inputs=inputs
+ )
+ cred.save()
+ if token:
+ # encrypt based on the primary key from the prior save
+ cred.inputs['token'] = encrypt_field(cred, 'token')
+ cred.save()
+ org.galaxy_credentials.add(cred)
+
+ if public_galaxy_enabled:
+ # If public Galaxy was enabled, associate it to the org
+ org.galaxy_credentials.add(public_galaxy_credential)
diff --git a/awx/main/models/credential/__init__.py b/awx/main/models/credential/__init__.py
index 36bb2684ea..df12177aae 100644
--- a/awx/main/models/credential/__init__.py
+++ b/awx/main/models/credential/__init__.py
@@ -96,6 +96,10 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
help_text=_('Specify the type of credential you want to create. Refer '
'to the Ansible Tower documentation for details on each type.')
)
+ managed_by_tower = models.BooleanField(
+ default=False,
+ editable=False
+ )
organization = models.ForeignKey(
'Organization',
null=True,
@@ -331,6 +335,7 @@ class CredentialType(CommonModelNameNotUnique):
('insights', _('Insights')),
('external', _('External')),
('kubernetes', _('Kubernetes')),
+ ('galaxy', _('Galaxy/Automation Hub')),
)
kind = models.CharField(
@@ -1173,6 +1178,38 @@ ManagedCredentialType(
)
+ManagedCredentialType(
+ namespace='galaxy_api_token',
+ kind='galaxy',
+ name=ugettext_noop('Ansible Galaxy/Automation Hub API Token'),
+ inputs={
+ 'fields': [{
+ 'id': 'url',
+ 'label': ugettext_noop('Galaxy Server URL'),
+ 'type': 'string',
+ 'help_text': ugettext_noop('The URL of the Galaxy instance to connect to.')
+ },{
+ 'id': 'auth_url',
+ 'label': ugettext_noop('Auth Server URL'),
+ 'type': 'string',
+ 'help_text': ugettext_noop(
+ 'The URL of a Keycloak server token_endpoint, if using '
+ 'SSO auth.'
+ )
+ },{
+ 'id': 'token',
+ 'label': ugettext_noop('API Token'),
+ 'type': 'string',
+ 'secret': True,
+ 'help_text': ugettext_noop(
+ 'A token to use for authentication against the Galaxy instance.'
+ )
+ }],
+ 'required': ['url'],
+ }
+)
+
+
class CredentialInputSource(PrimordialModel):
class Meta:
diff --git a/awx/main/models/events.py b/awx/main/models/events.py
index 1f79b0e24b..90cc6f6094 100644
--- a/awx/main/models/events.py
+++ b/awx/main/models/events.py
@@ -4,6 +4,8 @@ import datetime
import logging
from collections import defaultdict
+from django.conf import settings
+from django.core.exceptions import ObjectDoesNotExist
from django.db import models, DatabaseError, connection
from django.utils.dateparse import parse_datetime
from django.utils.text import Truncator
@@ -57,7 +59,18 @@ def create_host_status_counts(event_data):
return dict(host_status_counts)
+MINIMAL_EVENTS = set([
+ 'playbook_on_play_start', 'playbook_on_task_start',
+ 'playbook_on_stats', 'EOF'
+])
+
+
def emit_event_detail(event):
+ if (
+ settings.UI_LIVE_UPDATES_ENABLED is False and
+ event.event not in MINIMAL_EVENTS
+ ):
+ return
cls = event.__class__
relation = {
JobEvent: 'job_id',
@@ -337,41 +350,47 @@ class BasePlaybookEvent(CreatedModifiedModel):
pass
if isinstance(self, JobEvent):
- hostnames = self._hostnames()
- self._update_host_summary_from_stats(set(hostnames))
- if self.job.inventory:
- try:
- self.job.inventory.update_computed_fields()
- except DatabaseError:
- logger.exception('Computed fields database error saving event {}'.format(self.pk))
+ try:
+ job = self.job
+ except ObjectDoesNotExist:
+ job = None
+ if job:
+ hostnames = self._hostnames()
+ self._update_host_summary_from_stats(set(hostnames))
+ if job.inventory:
+ try:
+ job.inventory.update_computed_fields()
+ except DatabaseError:
+ logger.exception('Computed fields database error saving event {}'.format(self.pk))
- # find parent links and progagate changed=T and failed=T
- changed = self.job.job_events.filter(changed=True).exclude(parent_uuid=None).only('parent_uuid').values_list('parent_uuid', flat=True).distinct() # noqa
- failed = self.job.job_events.filter(failed=True).exclude(parent_uuid=None).only('parent_uuid').values_list('parent_uuid', flat=True).distinct() # noqa
+ # find parent links and progagate changed=T and failed=T
+ changed = job.job_events.filter(changed=True).exclude(parent_uuid=None).only('parent_uuid').values_list('parent_uuid', flat=True).distinct() # noqa
+ failed = job.job_events.filter(failed=True).exclude(parent_uuid=None).only('parent_uuid').values_list('parent_uuid', flat=True).distinct() # noqa
- JobEvent.objects.filter(
- job_id=self.job_id, uuid__in=changed
- ).update(changed=True)
- JobEvent.objects.filter(
- job_id=self.job_id, uuid__in=failed
- ).update(failed=True)
+ JobEvent.objects.filter(
+ job_id=self.job_id, uuid__in=changed
+ ).update(changed=True)
+ JobEvent.objects.filter(
+ job_id=self.job_id, uuid__in=failed
+ ).update(failed=True)
- # send success/failure notifications when we've finished handling the playbook_on_stats event
- from awx.main.tasks import handle_success_and_failure_notifications # circular import
+ # send success/failure notifications when we've finished handling the playbook_on_stats event
+ from awx.main.tasks import handle_success_and_failure_notifications # circular import
- def _send_notifications():
- handle_success_and_failure_notifications.apply_async([self.job.id])
- connection.on_commit(_send_notifications)
+ def _send_notifications():
+ handle_success_and_failure_notifications.apply_async([job.id])
+ connection.on_commit(_send_notifications)
for field in ('playbook', 'play', 'task', 'role'):
value = force_text(event_data.get(field, '')).strip()
if value != getattr(self, field):
setattr(self, field, value)
- analytics_logger.info(
- 'Event data saved.',
- extra=dict(python_objects=dict(job_event=self))
- )
+ if settings.LOG_AGGREGATOR_ENABLED:
+ analytics_logger.info(
+ 'Event data saved.',
+ extra=dict(python_objects=dict(job_event=self))
+ )
@classmethod
def create_from_data(cls, **kwargs):
@@ -484,7 +503,11 @@ class JobEvent(BasePlaybookEvent):
def _update_host_summary_from_stats(self, hostnames):
with ignore_inventory_computed_fields():
- if not self.job or not self.job.inventory:
+ try:
+ if not self.job or not self.job.inventory:
+ logger.info('Event {} missing job or inventory, host summaries not updated'.format(self.pk))
+ return
+ except ObjectDoesNotExist:
logger.info('Event {} missing job or inventory, host summaries not updated'.format(self.pk))
return
job = self.job
@@ -520,13 +543,21 @@ class JobEvent(BasePlaybookEvent):
(summary['host_id'], summary['id'])
for summary in JobHostSummary.objects.filter(job_id=job.id).values('id', 'host_id')
)
+ updated_hosts = set()
for h in all_hosts:
# if the hostname *shows up* in the playbook_on_stats event
if h.name in hostnames:
h.last_job_id = job.id
+ updated_hosts.add(h)
if h.id in host_mapping:
h.last_job_host_summary_id = host_mapping[h.id]
- Host.objects.bulk_update(all_hosts, ['last_job_id', 'last_job_host_summary_id'])
+ updated_hosts.add(h)
+
+ Host.objects.bulk_update(
+ list(updated_hosts),
+ ['last_job_id', 'last_job_host_summary_id'],
+ batch_size=100
+ )
@property
diff --git a/awx/main/models/ha.py b/awx/main/models/ha.py
index ac7df97e10..fc4e9c022e 100644
--- a/awx/main/models/ha.py
+++ b/awx/main/models/ha.py
@@ -12,6 +12,7 @@ from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.utils.timezone import now, timedelta
+import redis
from solo.models import SingletonModel
from awx import __version__ as awx_application_version
@@ -23,7 +24,7 @@ from awx.main.models.unified_jobs import UnifiedJob
from awx.main.utils import get_cpu_capacity, get_mem_capacity, get_system_task_capacity
from awx.main.models.mixins import RelatedJobsMixin
-__all__ = ('Instance', 'InstanceGroup', 'TowerScheduleState', 'TowerAnalyticsState')
+__all__ = ('Instance', 'InstanceGroup', 'TowerScheduleState')
class HasPolicyEditsMixin(HasEditsMixin):
@@ -152,6 +153,14 @@ class Instance(HasPolicyEditsMixin, BaseModel):
self.capacity = get_system_task_capacity(self.capacity_adjustment)
else:
self.capacity = 0
+
+ try:
+ # if redis is down for some reason, that means we can't persist
+ # playbook event data; we should consider this a zero capacity event
+ redis.Redis.from_url(settings.BROKER_URL).ping()
+ except redis.ConnectionError:
+ self.capacity = 0
+
self.cpu = cpu[0]
self.memory = mem[0]
self.cpu_capacity = cpu[1]
@@ -287,10 +296,6 @@ class TowerScheduleState(SingletonModel):
schedule_last_run = models.DateTimeField(auto_now_add=True)
-class TowerAnalyticsState(SingletonModel):
- last_run = models.DateTimeField(auto_now_add=True)
-
-
def schedule_policy_task():
from awx.main.tasks import apply_cluster_membership_policies
connection.on_commit(lambda: apply_cluster_membership_policies.apply_async())
diff --git a/awx/main/models/notifications.py b/awx/main/models/notifications.py
index c374f60420..11d97c7690 100644
--- a/awx/main/models/notifications.py
+++ b/awx/main/models/notifications.py
@@ -393,7 +393,11 @@ class JobNotificationMixin(object):
'job': job_context,
'job_friendly_name': self.get_notification_friendly_name(),
'url': self.get_ui_url(),
- 'job_metadata': json.dumps(self.notification_data(), indent=4)
+ 'job_metadata': json.dumps(
+ self.notification_data(),
+ ensure_ascii=False,
+ indent=4
+ )
}
def build_context(node, fields, allowed_fields):
diff --git a/awx/main/models/organization.py b/awx/main/models/organization.py
index 23ce65f5e9..bf2e07d255 100644
--- a/awx/main/models/organization.py
+++ b/awx/main/models/organization.py
@@ -45,6 +45,12 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi
blank=True,
through='OrganizationInstanceGroupMembership'
)
+ galaxy_credentials = OrderedManyToManyField(
+ 'Credential',
+ blank=True,
+ through='OrganizationGalaxyCredentialMembership',
+ related_name='%(class)s_galaxy_credentials'
+ )
max_hosts = models.PositiveIntegerField(
blank=True,
default=0,
@@ -108,6 +114,23 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi
return UnifiedJob.objects.non_polymorphic().filter(organization=self)
+class OrganizationGalaxyCredentialMembership(models.Model):
+
+ organization = models.ForeignKey(
+ 'Organization',
+ on_delete=models.CASCADE
+ )
+ credential = models.ForeignKey(
+ 'Credential',
+ on_delete=models.CASCADE
+ )
+ position = models.PositiveIntegerField(
+ null=True,
+ default=None,
+ db_index=True,
+ )
+
+
class Team(CommonModelNameNotUnique, ResourceMixin):
'''
A team is a group of users that work on common projects.
diff --git a/awx/main/models/schedules.py b/awx/main/models/schedules.py
index a3dd32d6b0..5b907a4333 100644
--- a/awx/main/models/schedules.py
+++ b/awx/main/models/schedules.py
@@ -205,10 +205,15 @@ class Schedule(PrimordialModel, LaunchTimeConfig):
'A valid TZID must be provided (e.g., America/New_York)'
)
- if fast_forward and ('MINUTELY' in rrule or 'HOURLY' in rrule):
+ if (
+ fast_forward and
+ ('MINUTELY' in rrule or 'HOURLY' in rrule) and
+ 'COUNT=' not in rrule
+ ):
try:
first_event = x[0]
- if first_event < now():
+ # If the first event was over a week ago...
+ if (now() - first_event).days > 7:
# hourly/minutely rrules with far-past DTSTART values
# are *really* slow to precompute
# start *from* one week ago to speed things up drastically
diff --git a/awx/main/models/workflow.py b/awx/main/models/workflow.py
index aaf59b25b8..d3e9d2d957 100644
--- a/awx/main/models/workflow.py
+++ b/awx/main/models/workflow.py
@@ -776,6 +776,10 @@ class WorkflowApproval(UnifiedJob, JobNotificationMixin):
self.send_approval_notification('running')
return can_start
+ @property
+ def event_processing_finished(self):
+ return True
+
def send_approval_notification(self, approval_status):
from awx.main.tasks import send_notifications # avoid circular import
if self.workflow_job_template is None:
diff --git a/awx/main/redact.py b/awx/main/redact.py
index 4c286eb9a8..32899d935e 100644
--- a/awx/main/redact.py
+++ b/awx/main/redact.py
@@ -1,8 +1,6 @@
import re
import urllib.parse as urlparse
-from django.conf import settings
-
REPLACE_STR = '$encrypted$'
@@ -12,12 +10,6 @@ class UriCleaner(object):
@staticmethod
def remove_sensitive(cleartext):
- # exclude_list contains the items that will _not_ be redacted
- exclude_list = [settings.PUBLIC_GALAXY_SERVER['url']]
- if settings.PRIMARY_GALAXY_URL:
- exclude_list += [settings.PRIMARY_GALAXY_URL]
- if settings.FALLBACK_GALAXY_SERVERS:
- exclude_list += [server['url'] for server in settings.FALLBACK_GALAXY_SERVERS]
redactedtext = cleartext
text_index = 0
while True:
@@ -25,10 +17,6 @@ class UriCleaner(object):
if not match:
break
uri_str = match.group(1)
- # Do not redact items from the exclude list
- if any(uri_str.startswith(exclude_uri) for exclude_uri in exclude_list):
- text_index = match.start() + len(uri_str)
- continue
try:
# May raise a ValueError if invalid URI for one reason or another
o = urlparse.urlsplit(uri_str)
diff --git a/awx/main/scheduler/task_manager.py b/awx/main/scheduler/task_manager.py
index cba6161d83..9f4818bd37 100644
--- a/awx/main/scheduler/task_manager.py
+++ b/awx/main/scheduler/task_manager.py
@@ -12,6 +12,7 @@ import random
from django.db import transaction, connection
from django.utils.translation import ugettext_lazy as _, gettext_noop
from django.utils.timezone import now as tz_now
+from django.conf import settings
# AWX
from awx.main.dispatch.reaper import reap_job
@@ -45,6 +46,12 @@ class TaskManager():
def __init__(self):
self.graph = dict()
+ # start task limit indicates how many pending jobs can be started on this
+ # .schedule() run. Starting jobs is expensive, and there is code in place to reap
+ # the task manager after 5 minutes. At scale, the task manager can easily take more than
+ # 5 minutes to start pending jobs. If this limit is reached, pending jobs
+ # will no longer be started and will be started on the next task manager cycle.
+ self.start_task_limit = settings.START_TASK_LIMIT
for rampart_group in InstanceGroup.objects.prefetch_related('instances'):
self.graph[rampart_group.name] = dict(graph=DependencyGraph(rampart_group.name),
capacity_total=rampart_group.capacity,
@@ -189,6 +196,10 @@ class TaskManager():
return result
def start_task(self, task, rampart_group, dependent_tasks=None, instance=None):
+ self.start_task_limit -= 1
+ if self.start_task_limit == 0:
+ # schedule another run immediately after this task manager
+ schedule_task_manager()
from awx.main.tasks import handle_work_error, handle_work_success
dependent_tasks = dependent_tasks or []
@@ -448,6 +459,8 @@ class TaskManager():
def process_pending_tasks(self, pending_tasks):
running_workflow_templates = set([wf.unified_job_template_id for wf in self.get_running_workflow_jobs()])
for task in pending_tasks:
+ if self.start_task_limit <= 0:
+ break
if self.is_job_blocked(task):
logger.debug("{} is blocked from running".format(task.log_format))
continue
diff --git a/awx/main/tasks.py b/awx/main/tasks.py
index 0c7b219371..0e03055055 100644
--- a/awx/main/tasks.py
+++ b/awx/main/tasks.py
@@ -51,8 +51,9 @@ import ansible_runner
# AWX
from awx import __version__ as awx_application_version
-from awx.main.constants import PRIVILEGE_ESCALATION_METHODS, STANDARD_INVENTORY_UPDATE_ENV, GALAXY_SERVER_FIELDS
+from awx.main.constants import PRIVILEGE_ESCALATION_METHODS, STANDARD_INVENTORY_UPDATE_ENV
from awx.main.access import access_registry
+from awx.main.analytics import all_collectors, expensive_collectors
from awx.main.redact import UriCleaner
from awx.main.models import (
Schedule, TowerScheduleState, Instance, InstanceGroup,
@@ -355,6 +356,26 @@ def send_notifications(notification_list, job_id=None):
@task(queue=get_local_queuename)
def gather_analytics():
+ def _gather_and_ship(subset, since, until):
+ tgzfiles = []
+ try:
+ tgzfiles = analytics.gather(subset=subset, since=since, until=until)
+ # empty analytics without raising an exception is not an error
+ if not tgzfiles:
+ return True
+ logger.info('Gathered analytics from {} to {}: {}'.format(since, until, tgzfiles))
+ for tgz in tgzfiles:
+ analytics.ship(tgz)
+ except Exception:
+ logger.exception('Error gathering and sending analytics for {} to {}.'.format(since,until))
+ return False
+ finally:
+ if tgzfiles:
+ for tgz in tgzfiles:
+ if os.path.exists(tgz):
+ os.remove(tgz)
+ return True
+
from awx.conf.models import Setting
from rest_framework.fields import DateTimeField
if not settings.INSIGHTS_TRACKING_STATE:
@@ -373,16 +394,29 @@ def gather_analytics():
if acquired is False:
logger.debug('Not gathering analytics, another task holds lock')
return
- try:
- tgz = analytics.gather()
- if not tgz:
- return
- logger.info('gathered analytics: {}'.format(tgz))
- analytics.ship(tgz)
- settings.AUTOMATION_ANALYTICS_LAST_GATHER = gather_time
- finally:
- if os.path.exists(tgz):
- os.remove(tgz)
+ subset = list(all_collectors().keys())
+ incremental_collectors = []
+ for collector in expensive_collectors():
+ if collector in subset:
+ subset.remove(collector)
+ incremental_collectors.append(collector)
+
+ # Cap gathering at 4 weeks of data if there has been no data gathering
+ since = last_time or (gather_time - timedelta(weeks=4))
+
+ if incremental_collectors:
+ start = since
+ until = None
+ while start < gather_time:
+ until = start + timedelta(hours = 4)
+ if (until > gather_time):
+ until = gather_time
+ if not _gather_and_ship(incremental_collectors, since=start, until=until):
+ break
+ start = until
+ settings.AUTOMATION_ANALYTICS_LAST_GATHER = until
+ if subset:
+ _gather_and_ship(subset, since=since, until=gather_time)
@task(queue=get_local_queuename)
@@ -1472,6 +1506,8 @@ class BaseTask(object):
self.instance.job_explanation = "Job terminated due to timeout"
status = 'failed'
extra_update_fields['job_explanation'] = self.instance.job_explanation
+ # ensure failure notification sends even if playbook_on_stats event is not triggered
+ handle_success_and_failure_notifications.apply_async([self.instance.job.id])
except InvalidVirtualenvError as e:
extra_update_fields['job_explanation'] = e.message
@@ -1632,11 +1668,6 @@ class RunJob(BaseTask):
# callbacks to work.
env['JOB_ID'] = str(job.pk)
env['INVENTORY_ID'] = str(job.inventory.pk)
- if job.use_fact_cache:
- library_source = self.get_path_to('..', 'plugins', 'library')
- library_dest = os.path.join(private_data_dir, 'library')
- copy_tree(library_source, library_dest)
- env['ANSIBLE_LIBRARY'] = library_dest
if job.project:
env['PROJECT_REVISION'] = job.project.scm_revision
env['ANSIBLE_RETRY_FILES_ENABLED'] = "False"
@@ -2020,35 +2051,25 @@ class RunProjectUpdate(BaseTask):
env['PROJECT_UPDATE_ID'] = str(project_update.pk)
if settings.GALAXY_IGNORE_CERTS:
env['ANSIBLE_GALAXY_IGNORE'] = True
- # Set up the public Galaxy server, if enabled
- galaxy_configured = False
- if settings.PUBLIC_GALAXY_ENABLED:
- galaxy_servers = [settings.PUBLIC_GALAXY_SERVER] # static setting
- else:
- galaxy_configured = True
- galaxy_servers = []
- # Set up fallback Galaxy servers, if configured
- if settings.FALLBACK_GALAXY_SERVERS:
- galaxy_configured = True
- galaxy_servers = settings.FALLBACK_GALAXY_SERVERS + galaxy_servers
- # Set up the primary Galaxy server, if configured
- if settings.PRIMARY_GALAXY_URL:
- galaxy_configured = True
- galaxy_servers = [{'id': 'primary_galaxy'}] + galaxy_servers
- for key in GALAXY_SERVER_FIELDS:
- value = getattr(settings, 'PRIMARY_GALAXY_{}'.format(key.upper()))
- if value:
- galaxy_servers[0][key] = value
- if galaxy_configured:
- for server in galaxy_servers:
- for key in GALAXY_SERVER_FIELDS:
- if not server.get(key):
- continue
- env_key = ('ANSIBLE_GALAXY_SERVER_{}_{}'.format(server.get('id', 'unnamed'), key)).upper()
- env[env_key] = server[key]
- if galaxy_servers:
- # now set the precedence of galaxy servers
- env['ANSIBLE_GALAXY_SERVER_LIST'] = ','.join([server.get('id', 'unnamed') for server in galaxy_servers])
+
+ # build out env vars for Galaxy credentials (in order)
+ galaxy_server_list = []
+ if project_update.project.organization:
+ for i, cred in enumerate(
+ project_update.project.organization.galaxy_credentials.all()
+ ):
+ env[f'ANSIBLE_GALAXY_SERVER_SERVER{i}_URL'] = cred.get_input('url')
+ auth_url = cred.get_input('auth_url', default=None)
+ token = cred.get_input('token', default=None)
+ if token:
+ env[f'ANSIBLE_GALAXY_SERVER_SERVER{i}_TOKEN'] = token
+ if auth_url:
+ env[f'ANSIBLE_GALAXY_SERVER_SERVER{i}_AUTH_URL'] = auth_url
+ galaxy_server_list.append(f'server{i}')
+
+ if galaxy_server_list:
+ env['ANSIBLE_GALAXY_SERVER_LIST'] = ','.join(galaxy_server_list)
+
return env
def _build_scm_url_extra_vars(self, project_update):
@@ -2121,6 +2142,19 @@ class RunProjectUpdate(BaseTask):
raise RuntimeError('Could not determine a revision to run from project.')
elif not scm_branch:
scm_branch = {'hg': 'tip'}.get(project_update.scm_type, 'HEAD')
+
+ galaxy_creds_are_defined = (
+ project_update.project.organization and
+ project_update.project.organization.galaxy_credentials.exists()
+ )
+ if not galaxy_creds_are_defined and (
+ settings.AWX_ROLES_ENABLED or settings.AWX_COLLECTIONS_ENABLED
+ ):
+ logger.debug(
+ 'Galaxy role/collection syncing is enabled, but no '
+ f'credentials are configured for {project_update.project.organization}.'
+ )
+
extra_vars.update({
'projects_root': settings.PROJECTS_ROOT.rstrip('/'),
'local_path': os.path.basename(project_update.project.local_path),
@@ -2131,8 +2165,8 @@ class RunProjectUpdate(BaseTask):
'scm_url': scm_url,
'scm_branch': scm_branch,
'scm_clean': project_update.scm_clean,
- 'roles_enabled': settings.AWX_ROLES_ENABLED,
- 'collections_enabled': settings.AWX_COLLECTIONS_ENABLED,
+ 'roles_enabled': galaxy_creds_are_defined and settings.AWX_ROLES_ENABLED,
+ 'collections_enabled': galaxy_creds_are_defined and settings.AWX_COLLECTIONS_ENABLED,
})
# apply custom refspec from user for PR refs and the like
if project_update.scm_refspec:
diff --git a/awx/main/tests/factories/README.md b/awx/main/tests/factories/README.md
index c451c02598..916c996cfa 100644
--- a/awx/main/tests/factories/README.md
+++ b/awx/main/tests/factories/README.md
@@ -52,11 +52,11 @@ patterns
--------
`mk` functions are single object fixtures. They should create only a single object with the minimum deps.
-They should also accept a `persited` flag, if they must be persisted to work, they raise an error if persisted=False
+They should also accept a `persisted` flag, if they must be persisted to work, they raise an error if persisted=False
`generate` and `apply` functions are helpers that build up the various parts of a `create` functions objects. These
should be useful for more than one create function to use and should explicitly accept all of the values needed
-to execute. These functions should also be robust and have very speciifc error reporting about constraints and/or
+to execute. These functions should also be robust and have very specific error reporting about constraints and/or
bad values.
`create` functions compose many of the `mk` and `generate` functions to make different object
diff --git a/awx/main/tests/functional/analytics/test_collectors.py b/awx/main/tests/functional/analytics/test_collectors.py
index ff53ac6bb4..1d643588d1 100644
--- a/awx/main/tests/functional/analytics/test_collectors.py
+++ b/awx/main/tests/functional/analytics/test_collectors.py
@@ -1,6 +1,7 @@
import pytest
import tempfile
import os
+import re
import shutil
import csv
@@ -27,7 +28,8 @@ def sqlite_copy_expert(request):
def write_stdout(self, sql, fd):
# Would be cool if we instead properly disected the SQL query and verified
- # it that way. But instead, we just take the nieve approach here.
+ # it that way. But instead, we just take the naive approach here.
+ sql = sql.strip()
assert sql.startswith("COPY (")
assert sql.endswith(") TO STDOUT WITH CSV HEADER")
@@ -35,6 +37,10 @@ def sqlite_copy_expert(request):
sql = sql.replace(") TO STDOUT WITH CSV HEADER", "")
# sqlite equivalent
sql = sql.replace("ARRAY_AGG", "GROUP_CONCAT")
+ # SQLite doesn't support isoformatted dates, because that would be useful
+ sql = sql.replace("+00:00", "")
+ i = re.compile(r'(?P\d\d\d\d-\d\d-\d\d)T')
+ sql = i.sub(r'\g ', sql)
# Remove JSON style queries
# TODO: could replace JSON style queries with sqlite kind of equivalents
@@ -86,7 +92,7 @@ def test_copy_tables_unified_job_query(
job_name = job_template.create_unified_job().name
with tempfile.TemporaryDirectory() as tmpdir:
- collectors.copy_tables(time_start, tmpdir, subset="unified_jobs")
+ collectors.unified_jobs_table(time_start, tmpdir, until = now() + timedelta(seconds=1))
with open(os.path.join(tmpdir, "unified_jobs_table.csv")) as f:
lines = "".join([line for line in f])
@@ -134,7 +140,7 @@ def test_copy_tables_workflow_job_node_query(sqlite_copy_expert, workflow_job):
time_start = now() - timedelta(hours=9)
with tempfile.TemporaryDirectory() as tmpdir:
- collectors.copy_tables(time_start, tmpdir, subset="workflow_job_node_query")
+ collectors.workflow_job_node_table(time_start, tmpdir, until = now() + timedelta(seconds=1))
with open(os.path.join(tmpdir, "workflow_job_node_table.csv")) as f:
reader = csv.reader(f)
# Pop the headers
diff --git a/awx/main/tests/functional/analytics/test_core.py b/awx/main/tests/functional/analytics/test_core.py
index 01f3858661..f3cc1fcd4b 100644
--- a/awx/main/tests/functional/analytics/test_core.py
+++ b/awx/main/tests/functional/analytics/test_core.py
@@ -10,17 +10,17 @@ from awx.main.analytics import gather, register
@register('example', '1.0')
-def example(since):
+def example(since, **kwargs):
return {'awx': 123}
@register('bad_json', '1.0')
-def bad_json(since):
+def bad_json(since, **kwargs):
return set()
@register('throws_error', '1.0')
-def throws_error(since):
+def throws_error(since, **kwargs):
raise ValueError()
@@ -39,9 +39,9 @@ def mock_valid_license():
def test_gather(mock_valid_license):
settings.INSIGHTS_TRACKING_STATE = True
- tgz = gather(module=importlib.import_module(__name__))
+ tgzfiles = gather(module=importlib.import_module(__name__))
files = {}
- with tarfile.open(tgz, "r:gz") as archive:
+ with tarfile.open(tgzfiles[0], "r:gz") as archive:
for member in archive.getmembers():
files[member.name] = archive.extractfile(member)
@@ -53,7 +53,8 @@ def test_gather(mock_valid_license):
assert './bad_json.json' not in files.keys()
assert './throws_error.json' not in files.keys()
try:
- os.remove(tgz)
+ for tgz in tgzfiles:
+ os.remove(tgz)
except Exception:
pass
diff --git a/awx/main/tests/functional/api/test_credential_type.py b/awx/main/tests/functional/api/test_credential_type.py
index c8f87f0c57..bf7aa4ceff 100644
--- a/awx/main/tests/functional/api/test_credential_type.py
+++ b/awx/main/tests/functional/api/test_credential_type.py
@@ -220,7 +220,7 @@ def test_create_valid_kind(kind, get, post, admin):
@pytest.mark.django_db
-@pytest.mark.parametrize('kind', ['ssh', 'vault', 'scm', 'insights', 'kubernetes'])
+@pytest.mark.parametrize('kind', ['ssh', 'vault', 'scm', 'insights', 'kubernetes', 'galaxy'])
def test_create_invalid_kind(kind, get, post, admin):
response = post(reverse('api:credential_type_list'), {
'kind': kind,
diff --git a/awx/main/tests/functional/api/test_job_runtime_params.py b/awx/main/tests/functional/api/test_job_runtime_params.py
index e628623cf1..80b2fcadfb 100644
--- a/awx/main/tests/functional/api/test_job_runtime_params.py
+++ b/awx/main/tests/functional/api/test_job_runtime_params.py
@@ -359,6 +359,71 @@ def test_job_launch_fails_with_missing_vault_password(machine_credential, vault_
assert response.data['passwords_needed_to_start'] == ['vault_password']
+@pytest.mark.django_db
+def test_job_launch_with_added_cred_and_vault_password(credential, machine_credential, vault_credential,
+ deploy_jobtemplate, post, admin):
+ # see: https://github.com/ansible/awx/issues/8202
+ vault_credential.inputs['vault_password'] = 'ASK'
+ vault_credential.save()
+ payload = {
+ 'credentials': [vault_credential.id, machine_credential.id],
+ 'credential_passwords': {'vault_password': 'vault-me'},
+ }
+
+ deploy_jobtemplate.ask_credential_on_launch = True
+ deploy_jobtemplate.credentials.remove(credential)
+ deploy_jobtemplate.credentials.add(vault_credential)
+ deploy_jobtemplate.save()
+
+ with mock.patch.object(Job, 'signal_start') as signal_start:
+ post(
+ reverse('api:job_template_launch', kwargs={'pk': deploy_jobtemplate.pk}),
+ payload,
+ admin,
+ expect=201,
+ )
+ signal_start.assert_called_with(**{
+ 'vault_password': 'vault-me'
+ })
+
+
+@pytest.mark.django_db
+def test_job_launch_with_multiple_launch_time_passwords(credential, machine_credential, vault_credential,
+ deploy_jobtemplate, post, admin):
+ # see: https://github.com/ansible/awx/issues/8202
+ deploy_jobtemplate.ask_credential_on_launch = True
+ deploy_jobtemplate.credentials.remove(credential)
+ deploy_jobtemplate.credentials.add(machine_credential)
+ deploy_jobtemplate.credentials.add(vault_credential)
+ deploy_jobtemplate.save()
+
+ second_machine_credential = Credential(
+ name='SSH #2',
+ credential_type=machine_credential.credential_type,
+ inputs={'password': 'ASK'}
+ )
+ second_machine_credential.save()
+
+ vault_credential.inputs['vault_password'] = 'ASK'
+ vault_credential.save()
+ payload = {
+ 'credentials': [vault_credential.id, second_machine_credential.id],
+ 'credential_passwords': {'ssh_password': 'ssh-me', 'vault_password': 'vault-me'},
+ }
+
+ with mock.patch.object(Job, 'signal_start') as signal_start:
+ post(
+ reverse('api:job_template_launch', kwargs={'pk': deploy_jobtemplate.pk}),
+ payload,
+ admin,
+ expect=201,
+ )
+ signal_start.assert_called_with(**{
+ 'ssh_password': 'ssh-me',
+ 'vault_password': 'vault-me',
+ })
+
+
@pytest.mark.django_db
@pytest.mark.parametrize('launch_kwargs', [
{'vault_password.abc': 'vault-me-1', 'vault_password.xyz': 'vault-me-2'},
diff --git a/awx/main/tests/functional/api/test_organizations.py b/awx/main/tests/functional/api/test_organizations.py
index 0827199676..6c45c0c681 100644
--- a/awx/main/tests/functional/api/test_organizations.py
+++ b/awx/main/tests/functional/api/test_organizations.py
@@ -9,7 +9,7 @@ from django.conf import settings
import pytest
# AWX
-from awx.main.models import ProjectUpdate
+from awx.main.models import ProjectUpdate, CredentialType, Credential
from awx.api.versioning import reverse
@@ -288,3 +288,90 @@ def test_organization_delete_with_active_jobs(delete, admin, organization, organ
assert resp.data['error'] == u"Resource is being used by running jobs."
assert resp_sorted == expect_sorted
+
+
+@pytest.mark.django_db
+def test_galaxy_credential_association_forbidden(alice, organization, post):
+ galaxy = CredentialType.defaults['galaxy_api_token']()
+ galaxy.save()
+
+ cred = Credential.objects.create(
+ credential_type=galaxy,
+ name='Public Galaxy',
+ organization=organization,
+ inputs={
+ 'url': 'https://galaxy.ansible.com/'
+ }
+ )
+ url = reverse('api:organization_galaxy_credentials_list', kwargs={'pk': organization.id})
+ post(
+ url,
+ {'associate': True, 'id': cred.pk},
+ user=alice,
+ expect=403
+ )
+
+
+@pytest.mark.django_db
+def test_galaxy_credential_type_enforcement(admin, organization, post):
+ ssh = CredentialType.defaults['ssh']()
+ ssh.save()
+
+ cred = Credential.objects.create(
+ credential_type=ssh,
+ name='SSH Credential',
+ organization=organization,
+ )
+ url = reverse('api:organization_galaxy_credentials_list', kwargs={'pk': organization.id})
+ resp = post(
+ url,
+ {'associate': True, 'id': cred.pk},
+ user=admin,
+ expect=400
+ )
+ assert resp.data['msg'] == 'Credential must be a Galaxy credential, not Machine.'
+
+
+@pytest.mark.django_db
+def test_galaxy_credential_association(alice, admin, organization, post, get):
+ galaxy = CredentialType.defaults['galaxy_api_token']()
+ galaxy.save()
+
+ for i in range(5):
+ cred = Credential.objects.create(
+ credential_type=galaxy,
+ name=f'Public Galaxy {i + 1}',
+ organization=organization,
+ inputs={
+ 'url': 'https://galaxy.ansible.com/'
+ }
+ )
+ url = reverse('api:organization_galaxy_credentials_list', kwargs={'pk': organization.id})
+ post(
+ url,
+ {'associate': True, 'id': cred.pk},
+ user=admin,
+ expect=204
+ )
+ resp = get(url, user=admin)
+ assert [cred['name'] for cred in resp.data['results']] == [
+ 'Public Galaxy 1',
+ 'Public Galaxy 2',
+ 'Public Galaxy 3',
+ 'Public Galaxy 4',
+ 'Public Galaxy 5',
+ ]
+
+ post(
+ url,
+ {'disassociate': True, 'id': Credential.objects.get(name='Public Galaxy 3').pk},
+ user=admin,
+ expect=204
+ )
+ resp = get(url, user=admin)
+ assert [cred['name'] for cred in resp.data['results']] == [
+ 'Public Galaxy 1',
+ 'Public Galaxy 2',
+ 'Public Galaxy 4',
+ 'Public Galaxy 5',
+ ]
diff --git a/awx/main/tests/functional/models/test_notifications.py b/awx/main/tests/functional/models/test_notifications.py
index 8d514312ae..5e5f19f0fd 100644
--- a/awx/main/tests/functional/models/test_notifications.py
+++ b/awx/main/tests/functional/models/test_notifications.py
@@ -123,6 +123,15 @@ class TestJobNotificationMixin(object):
context = job.context(job_serialization)
check_structure(TestJobNotificationMixin.CONTEXT_STRUCTURE, context)
+
+ @pytest.mark.django_db
+ def test_context_job_metadata_with_unicode(self):
+ job = Job.objects.create(name='批量安装项目')
+ job_serialization = UnifiedJobSerializer(job).to_representation(job)
+ context = job.context(job_serialization)
+ assert '批量安装项目' in context['job_metadata']
+
+
def test_context_stub(self):
"""The context stub is a fake context used to validate custom notification messages. Ensure that
this also has the expected structure. Furthermore, ensure that the stub context contains
diff --git a/awx/main/tests/functional/models/test_project.py b/awx/main/tests/functional/models/test_project.py
index 2cf43c5690..d3c34498b0 100644
--- a/awx/main/tests/functional/models/test_project.py
+++ b/awx/main/tests/functional/models/test_project.py
@@ -1,7 +1,7 @@
import pytest
from unittest import mock
-from awx.main.models import Project
+from awx.main.models import Project, Credential, CredentialType
from awx.main.models.organization import Organization
@@ -57,3 +57,31 @@ def test_foreign_key_change_changes_modified_by(project, organization):
def test_project_related_jobs(project):
update = project.create_unified_job()
assert update.id in [u.id for u in project._get_related_jobs()]
+
+
+@pytest.mark.django_db
+def test_galaxy_credentials(project):
+ org = project.organization
+ galaxy = CredentialType.defaults['galaxy_api_token']()
+ galaxy.save()
+ for i in range(5):
+ cred = Credential.objects.create(
+ name=f'Ansible Galaxy {i + 1}',
+ organization=org,
+ credential_type=galaxy,
+ inputs={
+ 'url': 'https://galaxy.ansible.com/'
+ }
+ )
+ cred.save()
+ org.galaxy_credentials.add(cred)
+
+ assert [
+ cred.name for cred in org.galaxy_credentials.all()
+ ] == [
+ 'Ansible Galaxy 1',
+ 'Ansible Galaxy 2',
+ 'Ansible Galaxy 3',
+ 'Ansible Galaxy 4',
+ 'Ansible Galaxy 5',
+ ]
diff --git a/awx/main/tests/functional/models/test_schedule.py b/awx/main/tests/functional/models/test_schedule.py
index 5575921ff0..fb5bfbf271 100644
--- a/awx/main/tests/functional/models/test_schedule.py
+++ b/awx/main/tests/functional/models/test_schedule.py
@@ -1,4 +1,4 @@
-from datetime import datetime
+from datetime import datetime, timedelta
from contextlib import contextmanager
from django.utils.timezone import now
@@ -161,6 +161,58 @@ class TestComputedFields:
assert job_template.next_schedule == expected_schedule
+@pytest.mark.django_db
+@pytest.mark.parametrize('freq, delta', (
+ ('MINUTELY', 1),
+ ('HOURLY', 1)
+))
+def test_past_week_rrule(job_template, freq, delta):
+ # see: https://github.com/ansible/awx/issues/8071
+ recent = (datetime.utcnow() - timedelta(days=3))
+ recent = recent.replace(hour=0, minute=0, second=0, microsecond=0)
+ recent_dt = recent.strftime('%Y%m%d')
+ rrule = f'DTSTART;TZID=America/New_York:{recent_dt}T000000 RRULE:FREQ={freq};INTERVAL={delta};COUNT=5' # noqa
+ sched = Schedule.objects.create(
+ name='example schedule',
+ rrule=rrule,
+ unified_job_template=job_template
+ )
+ first_event = sched.rrulestr(sched.rrule)[0]
+ assert first_event.replace(tzinfo=None) == recent
+
+
+@pytest.mark.django_db
+@pytest.mark.parametrize('freq, delta', (
+ ('MINUTELY', 1),
+ ('HOURLY', 1)
+))
+def test_really_old_dtstart(job_template, freq, delta):
+ # see: https://github.com/ansible/awx/issues/8071
+ # If an event is per-minute/per-hour and was created a *really long*
+ # time ago, we should just bump forward to start counting "in the last week"
+ rrule = f'DTSTART;TZID=America/New_York:20150101T000000 RRULE:FREQ={freq};INTERVAL={delta}' # noqa
+ sched = Schedule.objects.create(
+ name='example schedule',
+ rrule=rrule,
+ unified_job_template=job_template
+ )
+ last_week = (datetime.utcnow() - timedelta(days=7)).date()
+ first_event = sched.rrulestr(sched.rrule)[0]
+ assert last_week == first_event.date()
+
+ # the next few scheduled events should be the next minute/hour incremented
+ next_five_events = list(sched.rrulestr(sched.rrule).xafter(now(), count=5))
+
+ assert next_five_events[0] > now()
+ last = None
+ for event in next_five_events:
+ if last:
+ assert event == last + (
+ timedelta(minutes=1) if freq == 'MINUTELY' else timedelta(hours=1)
+ )
+ last = event
+
+
@pytest.mark.django_db
def test_repeats_forever(job_template):
s = Schedule(
diff --git a/awx/main/tests/functional/test_credential.py b/awx/main/tests/functional/test_credential.py
index 721bf5c043..684f9dd5a7 100644
--- a/awx/main/tests/functional/test_credential.py
+++ b/awx/main/tests/functional/test_credential.py
@@ -81,6 +81,7 @@ def test_default_cred_types():
'azure_rm',
'cloudforms',
'conjur',
+ 'galaxy_api_token',
'gce',
'github_token',
'gitlab_token',
diff --git a/awx/main/tests/functional/test_dispatch.py b/awx/main/tests/functional/test_dispatch.py
index caf54f0161..e92867d6a5 100644
--- a/awx/main/tests/functional/test_dispatch.py
+++ b/awx/main/tests/functional/test_dispatch.py
@@ -10,7 +10,7 @@ import pytest
from awx.main.models import Job, WorkflowJob, Instance
from awx.main.dispatch import reaper
-from awx.main.dispatch.pool import PoolWorker, WorkerPool, AutoscalePool
+from awx.main.dispatch.pool import StatefulPoolWorker, WorkerPool, AutoscalePool
from awx.main.dispatch.publish import task
from awx.main.dispatch.worker import BaseWorker, TaskWorker
@@ -80,7 +80,7 @@ class SlowResultWriter(BaseWorker):
class TestPoolWorker:
def setup_method(self, test_method):
- self.worker = PoolWorker(1000, self.tick, tuple())
+ self.worker = StatefulPoolWorker(1000, self.tick, tuple())
def tick(self):
self.worker.finished.put(self.worker.queue.get()['uuid'])
diff --git a/awx/main/tests/functional/test_galaxy_credential_migration.py b/awx/main/tests/functional/test_galaxy_credential_migration.py
new file mode 100644
index 0000000000..110628e19c
--- /dev/null
+++ b/awx/main/tests/functional/test_galaxy_credential_migration.py
@@ -0,0 +1,115 @@
+import importlib
+
+from django.conf import settings
+from django.contrib.contenttypes.models import ContentType
+import pytest
+
+from awx.main.models import Credential, Organization
+from awx.conf.models import Setting
+from awx.main.migrations import _galaxy as galaxy
+
+
+class FakeApps(object):
+ def get_model(self, app, model):
+ if app == 'contenttypes':
+ return ContentType
+ return getattr(importlib.import_module(f'awx.{app}.models'), model)
+
+
+apps = FakeApps()
+
+
+@pytest.mark.django_db
+def test_default_public_galaxy():
+ org = Organization.objects.create()
+ assert org.galaxy_credentials.count() == 0
+ galaxy.migrate_galaxy_settings(apps, None)
+ assert org.galaxy_credentials.count() == 1
+ creds = org.galaxy_credentials.all()
+ assert creds[0].name == 'Ansible Galaxy'
+ assert creds[0].inputs['url'] == 'https://galaxy.ansible.com/'
+
+
+@pytest.mark.django_db
+def test_public_galaxy_disabled():
+ Setting.objects.create(key='PUBLIC_GALAXY_ENABLED', value=False)
+ org = Organization.objects.create()
+ assert org.galaxy_credentials.count() == 0
+ galaxy.migrate_galaxy_settings(apps, None)
+ assert org.galaxy_credentials.count() == 0
+
+
+@pytest.mark.django_db
+def test_rh_automation_hub():
+ Setting.objects.create(key='PRIMARY_GALAXY_URL', value='https://cloud.redhat.com/api/automation-hub/')
+ Setting.objects.create(key='PRIMARY_GALAXY_TOKEN', value='secret123')
+ org = Organization.objects.create()
+ assert org.galaxy_credentials.count() == 0
+ galaxy.migrate_galaxy_settings(apps, None)
+ assert org.galaxy_credentials.count() == 2
+ assert org.galaxy_credentials.first().name == 'Ansible Automation Hub (https://cloud.redhat.com/api/automation-hub/)' # noqa
+
+
+@pytest.mark.django_db
+def test_multiple_galaxies():
+ for i in range(5):
+ Organization.objects.create(name=f'Org {i}')
+
+ Setting.objects.create(key='PRIMARY_GALAXY_URL', value='https://example.org/')
+ Setting.objects.create(key='PRIMARY_GALAXY_AUTH_URL', value='https://auth.example.org/')
+ Setting.objects.create(key='PRIMARY_GALAXY_USERNAME', value='user')
+ Setting.objects.create(key='PRIMARY_GALAXY_PASSWORD', value='pass')
+ Setting.objects.create(key='PRIMARY_GALAXY_TOKEN', value='secret123')
+
+ for org in Organization.objects.all():
+ assert org.galaxy_credentials.count() == 0
+
+ galaxy.migrate_galaxy_settings(apps, None)
+
+ for org in Organization.objects.all():
+ assert org.galaxy_credentials.count() == 2
+ creds = org.galaxy_credentials.all()
+ assert creds[0].name == 'Private Galaxy (https://example.org/)'
+ assert creds[0].inputs['url'] == 'https://example.org/'
+ assert creds[0].inputs['auth_url'] == 'https://auth.example.org/'
+ assert creds[0].inputs['token'].startswith('$encrypted$')
+ assert creds[0].get_input('token') == 'secret123'
+
+ assert creds[1].name == 'Ansible Galaxy'
+ assert creds[1].inputs['url'] == 'https://galaxy.ansible.com/'
+
+ public_galaxy_creds = Credential.objects.filter(name='Ansible Galaxy')
+ assert public_galaxy_creds.count() == 1
+ assert public_galaxy_creds.first().managed_by_tower is True
+
+
+@pytest.mark.django_db
+def test_fallback_galaxies():
+ org = Organization.objects.create()
+ assert org.galaxy_credentials.count() == 0
+ Setting.objects.create(key='PRIMARY_GALAXY_URL', value='https://example.org/')
+ Setting.objects.create(key='PRIMARY_GALAXY_AUTH_URL', value='https://auth.example.org/')
+ Setting.objects.create(key='PRIMARY_GALAXY_TOKEN', value='secret123')
+ try:
+ settings.FALLBACK_GALAXY_SERVERS = [{
+ 'id': 'abc123',
+ 'url': 'https://some-other-galaxy.example.org/',
+ 'auth_url': 'https://some-other-galaxy.sso.example.org/',
+ 'username': 'user',
+ 'password': 'pass',
+ 'token': 'fallback123',
+ }]
+ galaxy.migrate_galaxy_settings(apps, None)
+ finally:
+ settings.FALLBACK_GALAXY_SERVERS = []
+ assert org.galaxy_credentials.count() == 3
+ creds = org.galaxy_credentials.all()
+ assert creds[0].name == 'Private Galaxy (https://example.org/)'
+ assert creds[0].inputs['url'] == 'https://example.org/'
+ assert creds[1].name == 'Ansible Galaxy (https://some-other-galaxy.example.org/)'
+ assert creds[1].inputs['url'] == 'https://some-other-galaxy.example.org/'
+ assert creds[1].inputs['auth_url'] == 'https://some-other-galaxy.sso.example.org/'
+ assert creds[1].inputs['token'].startswith('$encrypted$')
+ assert creds[1].get_input('token') == 'fallback123'
+ assert creds[2].name == 'Ansible Galaxy'
+ assert creds[2].inputs['url'] == 'https://galaxy.ansible.com/'
diff --git a/awx/main/tests/functional/test_jobs.py b/awx/main/tests/functional/test_jobs.py
index 2bc10fa0df..b4754a6803 100644
--- a/awx/main/tests/functional/test_jobs.py
+++ b/awx/main/tests/functional/test_jobs.py
@@ -1,3 +1,4 @@
+import redis
import pytest
from unittest import mock
import json
@@ -25,7 +26,8 @@ def test_orphan_unified_job_creation(instance, inventory):
@mock.patch('awx.main.utils.common.get_mem_capacity', lambda: (8000,62))
def test_job_capacity_and_with_inactive_node():
i = Instance.objects.create(hostname='test-1')
- i.refresh_capacity()
+ with mock.patch.object(redis.client.Redis, 'ping', lambda self: True):
+ i.refresh_capacity()
assert i.capacity == 62
i.enabled = False
i.save()
@@ -35,6 +37,19 @@ def test_job_capacity_and_with_inactive_node():
assert i.capacity == 0
+@pytest.mark.django_db
+@mock.patch('awx.main.utils.common.get_cpu_capacity', lambda: (2,8))
+@mock.patch('awx.main.utils.common.get_mem_capacity', lambda: (8000,62))
+def test_job_capacity_with_redis_disabled():
+ i = Instance.objects.create(hostname='test-1')
+
+ def _raise(self):
+ raise redis.ConnectionError()
+ with mock.patch.object(redis.client.Redis, 'ping', _raise):
+ i.refresh_capacity()
+ assert i.capacity == 0
+
+
@pytest.mark.django_db
def test_job_type_name():
job = Job.objects.create()
diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py
index 5ce64894e6..b49af2efd0 100644
--- a/awx/main/tests/unit/test_tasks.py
+++ b/awx/main/tests/unit/test_tasks.py
@@ -25,6 +25,7 @@ from awx.main.models import (
Job,
JobTemplate,
Notification,
+ Organization,
Project,
ProjectUpdate,
UnifiedJob,
@@ -59,6 +60,19 @@ def patch_Job():
yield
+@pytest.fixture
+def patch_Organization():
+ _credentials = []
+ credentials_mock = mock.Mock(**{
+ 'all': lambda: _credentials,
+ 'add': _credentials.append,
+ 'exists': lambda: len(_credentials) > 0,
+ 'spec_set': ['all', 'add', 'exists'],
+ })
+ with mock.patch.object(Organization, 'galaxy_credentials', credentials_mock):
+ yield
+
+
@pytest.fixture
def job():
return Job(
@@ -131,7 +145,6 @@ def test_send_notifications_list(mock_notifications_filter, mock_job_get, mocker
('SECRET_KEY', 'SECRET'),
('VMWARE_PASSWORD', 'SECRET'),
('API_SECRET', 'SECRET'),
- ('ANSIBLE_GALAXY_SERVER_PRIMARY_GALAXY_PASSWORD', 'SECRET'),
('ANSIBLE_GALAXY_SERVER_PRIMARY_GALAXY_TOKEN', 'SECRET'),
])
def test_safe_env_filtering(key, value):
@@ -1780,10 +1793,108 @@ class TestJobCredentials(TestJobExecution):
assert env['FOO'] == 'BAR'
+@pytest.mark.usefixtures("patch_Organization")
+class TestProjectUpdateGalaxyCredentials(TestJobExecution):
+
+ @pytest.fixture
+ def project_update(self):
+ org = Organization(pk=1)
+ proj = Project(pk=1, organization=org)
+ project_update = ProjectUpdate(pk=1, project=proj, scm_type='git')
+ project_update.websocket_emit_status = mock.Mock()
+ return project_update
+
+ parametrize = {
+ 'test_galaxy_credentials_ignore_certs': [
+ dict(ignore=True),
+ dict(ignore=False),
+ ],
+ }
+
+ def test_galaxy_credentials_ignore_certs(self, private_data_dir, project_update, ignore):
+ settings.GALAXY_IGNORE_CERTS = ignore
+ task = tasks.RunProjectUpdate()
+ env = task.build_env(project_update, private_data_dir)
+ if ignore:
+ assert env['ANSIBLE_GALAXY_IGNORE'] is True
+ else:
+ assert 'ANSIBLE_GALAXY_IGNORE' not in env
+
+ def test_galaxy_credentials_empty(self, private_data_dir, project_update):
+
+ class RunProjectUpdate(tasks.RunProjectUpdate):
+ __vars__ = {}
+
+ def _write_extra_vars_file(self, private_data_dir, extra_vars, *kw):
+ self.__vars__ = extra_vars
+
+ task = RunProjectUpdate()
+ env = task.build_env(project_update, private_data_dir)
+ task.build_extra_vars_file(project_update, private_data_dir)
+ assert task.__vars__['roles_enabled'] is False
+ assert task.__vars__['collections_enabled'] is False
+ for k in env:
+ assert not k.startswith('ANSIBLE_GALAXY_SERVER')
+
+ def test_single_public_galaxy(self, private_data_dir, project_update):
+ class RunProjectUpdate(tasks.RunProjectUpdate):
+ __vars__ = {}
+
+ def _write_extra_vars_file(self, private_data_dir, extra_vars, *kw):
+ self.__vars__ = extra_vars
+
+ credential_type = CredentialType.defaults['galaxy_api_token']()
+ public_galaxy = Credential(pk=1, credential_type=credential_type, inputs={
+ 'url': 'https://galaxy.ansible.com/',
+ })
+ project_update.project.organization.galaxy_credentials.add(public_galaxy)
+ task = RunProjectUpdate()
+ env = task.build_env(project_update, private_data_dir)
+ task.build_extra_vars_file(project_update, private_data_dir)
+ assert task.__vars__['roles_enabled'] is True
+ assert task.__vars__['collections_enabled'] is True
+ assert sorted([
+ (k, v) for k, v in env.items()
+ if k.startswith('ANSIBLE_GALAXY')
+ ]) == [
+ ('ANSIBLE_GALAXY_SERVER_LIST', 'server0'),
+ ('ANSIBLE_GALAXY_SERVER_SERVER0_URL', 'https://galaxy.ansible.com/'),
+ ]
+
+ def test_multiple_galaxy_endpoints(self, private_data_dir, project_update):
+ credential_type = CredentialType.defaults['galaxy_api_token']()
+ public_galaxy = Credential(pk=1, credential_type=credential_type, inputs={
+ 'url': 'https://galaxy.ansible.com/',
+ })
+ rh = Credential(pk=2, credential_type=credential_type, inputs={
+ 'url': 'https://cloud.redhat.com/api/automation-hub/',
+ 'auth_url': 'https://sso.redhat.com/example/openid-connect/token/',
+ 'token': 'secret123'
+ })
+ project_update.project.organization.galaxy_credentials.add(public_galaxy)
+ project_update.project.organization.galaxy_credentials.add(rh)
+ task = tasks.RunProjectUpdate()
+ env = task.build_env(project_update, private_data_dir)
+ assert sorted([
+ (k, v) for k, v in env.items()
+ if k.startswith('ANSIBLE_GALAXY')
+ ]) == [
+ ('ANSIBLE_GALAXY_SERVER_LIST', 'server0,server1'),
+ ('ANSIBLE_GALAXY_SERVER_SERVER0_URL', 'https://galaxy.ansible.com/'),
+ ('ANSIBLE_GALAXY_SERVER_SERVER1_AUTH_URL', 'https://sso.redhat.com/example/openid-connect/token/'), # noqa
+ ('ANSIBLE_GALAXY_SERVER_SERVER1_TOKEN', 'secret123'),
+ ('ANSIBLE_GALAXY_SERVER_SERVER1_URL', 'https://cloud.redhat.com/api/automation-hub/'),
+ ]
+
+
+@pytest.mark.usefixtures("patch_Organization")
class TestProjectUpdateCredentials(TestJobExecution):
@pytest.fixture
def project_update(self):
- project_update = ProjectUpdate(pk=1, project=Project(pk=1))
+ project_update = ProjectUpdate(
+ pk=1,
+ project=Project(pk=1, organization=Organization(pk=1)),
+ )
project_update.websocket_emit_status = mock.Mock()
return project_update
diff --git a/awx/playbooks/scan_facts.yml b/awx/playbooks/scan_facts.yml
deleted file mode 100644
index 884760f717..0000000000
--- a/awx/playbooks/scan_facts.yml
+++ /dev/null
@@ -1,36 +0,0 @@
----
-- hosts: all
- vars:
- scan_use_checksum: false
- scan_use_recursive: false
- tasks:
-
- - name: "Scan packages (Unix/Linux)"
- scan_packages:
- os_family: '{{ ansible_os_family }}'
- when: ansible_os_family != "Windows"
- - name: "Scan services (Unix/Linux)"
- scan_services:
- when: ansible_os_family != "Windows"
- - name: "Scan files (Unix/Linux)"
- scan_files:
- paths: '{{ scan_file_paths }}'
- get_checksum: '{{ scan_use_checksum }}'
- recursive: '{{ scan_use_recursive }}'
- when: scan_file_paths is defined and ansible_os_family != "Windows"
- - name: "Scan Insights for Machine ID (Unix/Linux)"
- scan_insights:
- when: ansible_os_family != "Windows"
-
- - name: "Scan packages (Windows)"
- win_scan_packages:
- when: ansible_os_family == "Windows"
- - name: "Scan services (Windows)"
- win_scan_services:
- when: ansible_os_family == "Windows"
- - name: "Scan files (Windows)"
- win_scan_files:
- paths: '{{ scan_file_paths }}'
- get_checksum: '{{ scan_use_checksum }}'
- recursive: '{{ scan_use_recursive }}'
- when: scan_file_paths is defined and ansible_os_family == "Windows"
diff --git a/awx/plugins/library/scan_files.py b/awx/plugins/library/scan_files.py
deleted file mode 100644
index b3b07ad64a..0000000000
--- a/awx/plugins/library/scan_files.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import stat
-from ansible.module_utils.basic import * # noqa
-
-DOCUMENTATION = '''
----
-module: scan_files
-short_description: Return file state information as fact data for a directory tree
-description:
- - Return file state information recursively for a directory tree on the filesystem
-version_added: "1.9"
-options:
- path:
- description: The path containing files to be analyzed
- required: true
- default: null
- recursive:
- description: scan this directory and all subdirectories
- required: false
- default: no
- get_checksum:
- description: Checksum files that you can access
- required: false
- default: false
-requirements: [ ]
-author: Matthew Jones
-'''
-
-EXAMPLES = '''
-# Example fact output:
-# host | success >> {
-# "ansible_facts": {
-# "files": [
-# {
-# "atime": 1427313854.0755742,
-# "checksum": "cf7566e6149ad9af91e7589e0ea096a08de9c1e5",
-# "ctime": 1427129299.22948,
-# "dev": 51713,
-# "gid": 0,
-# "inode": 149601,
-# "isblk": false,
-# "ischr": false,
-# "isdir": false,
-# "isfifo": false,
-# "isgid": false,
-# "islnk": false,
-# "isreg": true,
-# "issock": false,
-# "isuid": false,
-# "mode": "0644",
-# "mtime": 1427112663.0321455,
-# "nlink": 1,
-# "path": "/var/log/dmesg.1.gz",
-# "rgrp": true,
-# "roth": true,
-# "rusr": true,
-# "size": 28,
-# "uid": 0,
-# "wgrp": false,
-# "woth": false,
-# "wusr": true,
-# "xgrp": false,
-# "xoth": false,
-# "xusr": false
-# },
-# {
-# "atime": 1427314385.1155744,
-# "checksum": "16fac7be61a6e4591a33ef4b729c5c3302307523",
-# "ctime": 1427384148.5755742,
-# "dev": 51713,
-# "gid": 43,
-# "inode": 149564,
-# "isblk": false,
-# "ischr": false,
-# "isdir": false,
-# "isfifo": false,
-# "isgid": false,
-# "islnk": false,
-# "isreg": true,
-# "issock": false,
-# "isuid": false,
-# "mode": "0664",
-# "mtime": 1427384148.5755742,
-# "nlink": 1,
-# "path": "/var/log/wtmp",
-# "rgrp": true,
-# "roth": true,
-# "rusr": true,
-# "size": 48768,
-# "uid": 0,
-# "wgrp": true,
-# "woth": false,
-# "wusr": true,
-# "xgrp": false,
-# "xoth": false,
-# "xusr": false
-# },
-'''
-
-
-def main():
- module = AnsibleModule( # noqa
- argument_spec = dict(paths=dict(required=True, type='list'),
- recursive=dict(required=False, default='no', type='bool'),
- get_checksum=dict(required=False, default='no', type='bool')))
- files = []
- paths = module.params.get('paths')
- for path in paths:
- path = os.path.expanduser(path)
- if not os.path.exists(path) or not os.path.isdir(path):
- module.fail_json(msg = "Given path must exist and be a directory")
-
- get_checksum = module.params.get('get_checksum')
- should_recurse = module.params.get('recursive')
- if not should_recurse:
- path_list = [os.path.join(path, subpath) for subpath in os.listdir(path)]
- else:
- path_list = [os.path.join(w_path, f) for w_path, w_names, w_file in os.walk(path) for f in w_file]
- for filepath in path_list:
- try:
- st = os.stat(filepath)
- except OSError:
- continue
-
- mode = st.st_mode
- d = {
- 'path' : filepath,
- 'mode' : "%04o" % stat.S_IMODE(mode),
- 'isdir' : stat.S_ISDIR(mode),
- 'ischr' : stat.S_ISCHR(mode),
- 'isblk' : stat.S_ISBLK(mode),
- 'isreg' : stat.S_ISREG(mode),
- 'isfifo' : stat.S_ISFIFO(mode),
- 'islnk' : stat.S_ISLNK(mode),
- 'issock' : stat.S_ISSOCK(mode),
- 'uid' : st.st_uid,
- 'gid' : st.st_gid,
- 'size' : st.st_size,
- 'inode' : st.st_ino,
- 'dev' : st.st_dev,
- 'nlink' : st.st_nlink,
- 'atime' : st.st_atime,
- 'mtime' : st.st_mtime,
- 'ctime' : st.st_ctime,
- 'wusr' : bool(mode & stat.S_IWUSR),
- 'rusr' : bool(mode & stat.S_IRUSR),
- 'xusr' : bool(mode & stat.S_IXUSR),
- 'wgrp' : bool(mode & stat.S_IWGRP),
- 'rgrp' : bool(mode & stat.S_IRGRP),
- 'xgrp' : bool(mode & stat.S_IXGRP),
- 'woth' : bool(mode & stat.S_IWOTH),
- 'roth' : bool(mode & stat.S_IROTH),
- 'xoth' : bool(mode & stat.S_IXOTH),
- 'isuid' : bool(mode & stat.S_ISUID),
- 'isgid' : bool(mode & stat.S_ISGID),
- }
- if get_checksum and stat.S_ISREG(mode) and os.access(filepath, os.R_OK):
- d['checksum'] = module.sha1(filepath)
- files.append(d)
- results = dict(ansible_facts=dict(files=files))
- module.exit_json(**results)
-
-
-main()
diff --git a/awx/plugins/library/scan_insights.py b/awx/plugins/library/scan_insights.py
deleted file mode 100755
index f7b7919bca..0000000000
--- a/awx/plugins/library/scan_insights.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-
-from ansible.module_utils.basic import * # noqa
-
-DOCUMENTATION = '''
----
-module: scan_insights
-short_description: Return insights id as fact data
-description:
- - Inspects the /etc/redhat-access-insights/machine-id file for insights id and returns the found id as fact data
-version_added: "2.3"
-options:
-requirements: [ ]
-author: Chris Meyers
-'''
-
-EXAMPLES = '''
-# Example fact output:
-# host | success >> {
-# "ansible_facts": {
-# "insights": {
-# "system_id": "4da7d1f8-14f3-4cdc-acd5-a3465a41f25d"
-# }, ... }
-'''
-
-
-INSIGHTS_SYSTEM_ID_FILE='/etc/redhat-access-insights/machine-id'
-
-
-def get_system_id(filname):
- system_id = None
- try:
- f = open(INSIGHTS_SYSTEM_ID_FILE, "r")
- except IOError:
- return None
- else:
- try:
- data = f.readline()
- system_id = str(data)
- except (IOError, ValueError):
- pass
- finally:
- f.close()
- if system_id:
- system_id = system_id.strip()
- return system_id
-
-
-def main():
- module = AnsibleModule( # noqa
- argument_spec = dict()
- )
-
- system_id = get_system_id(INSIGHTS_SYSTEM_ID_FILE)
-
- results = {
- 'ansible_facts': {
- 'insights': {
- 'system_id': system_id
- }
- }
- }
- module.exit_json(**results)
-
-
-main()
diff --git a/awx/plugins/library/scan_packages.py b/awx/plugins/library/scan_packages.py
deleted file mode 100755
index d0b544bb9f..0000000000
--- a/awx/plugins/library/scan_packages.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env python
-
-from ansible.module_utils.basic import * # noqa
-
-DOCUMENTATION = '''
----
-module: scan_packages
-short_description: Return installed packages information as fact data
-description:
- - Return information about installed packages as fact data
-version_added: "1.9"
-options:
-requirements: [ ]
-author: Matthew Jones
-'''
-
-EXAMPLES = '''
-# Example fact output:
-# host | success >> {
-# "ansible_facts": {
-# "packages": {
-# "libbz2-1.0": [
-# {
-# "version": "1.0.6-5",
-# "source": "apt",
-# "arch": "amd64",
-# "name": "libbz2-1.0"
-# }
-# ],
-# "patch": [
-# {
-# "version": "2.7.1-4ubuntu1",
-# "source": "apt",
-# "arch": "amd64",
-# "name": "patch"
-# }
-# ],
-# "gcc-4.8-base": [
-# {
-# "version": "4.8.2-19ubuntu1",
-# "source": "apt",
-# "arch": "amd64",
-# "name": "gcc-4.8-base"
-# },
-# {
-# "version": "4.9.2-19ubuntu1",
-# "source": "apt",
-# "arch": "amd64",
-# "name": "gcc-4.8-base"
-# }
-# ]
-# }
-'''
-
-
-def rpm_package_list():
- import rpm
- trans_set = rpm.TransactionSet()
- installed_packages = {}
- for package in trans_set.dbMatch():
- package_details = dict(name=package[rpm.RPMTAG_NAME],
- version=package[rpm.RPMTAG_VERSION],
- release=package[rpm.RPMTAG_RELEASE],
- epoch=package[rpm.RPMTAG_EPOCH],
- arch=package[rpm.RPMTAG_ARCH],
- source='rpm')
- if package_details['name'] not in installed_packages:
- installed_packages[package_details['name']] = [package_details]
- else:
- installed_packages[package_details['name']].append(package_details)
- return installed_packages
-
-
-def deb_package_list():
- import apt
- apt_cache = apt.Cache()
- installed_packages = {}
- apt_installed_packages = [pk for pk in apt_cache.keys() if apt_cache[pk].is_installed]
- for package in apt_installed_packages:
- ac_pkg = apt_cache[package].installed
- package_details = dict(name=package,
- version=ac_pkg.version,
- arch=ac_pkg.architecture,
- source='apt')
- if package_details['name'] not in installed_packages:
- installed_packages[package_details['name']] = [package_details]
- else:
- installed_packages[package_details['name']].append(package_details)
- return installed_packages
-
-
-def main():
- module = AnsibleModule( # noqa
- argument_spec = dict(os_family=dict(required=True))
- )
- ans_os = module.params['os_family']
- if ans_os in ('RedHat', 'Suse', 'openSUSE Leap'):
- packages = rpm_package_list()
- elif ans_os == 'Debian':
- packages = deb_package_list()
- else:
- packages = None
-
- if packages is not None:
- results = dict(ansible_facts=dict(packages=packages))
- else:
- results = dict(skipped=True, msg="Unsupported Distribution")
- module.exit_json(**results)
-
-
-main()
diff --git a/awx/plugins/library/scan_services.py b/awx/plugins/library/scan_services.py
deleted file mode 100644
index 5d8ccdbb74..0000000000
--- a/awx/plugins/library/scan_services.py
+++ /dev/null
@@ -1,190 +0,0 @@
-#!/usr/bin/env python
-
-import re
-from ansible.module_utils.basic import * # noqa
-
-DOCUMENTATION = '''
----
-module: scan_services
-short_description: Return service state information as fact data
-description:
- - Return service state information as fact data for various service management utilities
-version_added: "1.9"
-options:
-requirements: [ ]
-author: Matthew Jones
-'''
-
-EXAMPLES = '''
-- monit: scan_services
-# Example fact output:
-# host | success >> {
-# "ansible_facts": {
-# "services": {
-# "network": {
-# "source": "sysv",
-# "state": "running",
-# "name": "network"
-# },
-# "arp-ethers.service": {
-# "source": "systemd",
-# "state": "stopped",
-# "name": "arp-ethers.service"
-# }
-# }
-# }
-'''
-
-
-class BaseService(object):
-
- def __init__(self, module):
- self.module = module
- self.incomplete_warning = False
-
-
-class ServiceScanService(BaseService):
-
- def gather_services(self):
- services = {}
- service_path = self.module.get_bin_path("service")
- if service_path is None:
- return None
- initctl_path = self.module.get_bin_path("initctl")
- chkconfig_path = self.module.get_bin_path("chkconfig")
-
- # sysvinit
- if service_path is not None and chkconfig_path is None:
- rc, stdout, stderr = self.module.run_command("%s --status-all 2>&1 | grep -E \"\\[ (\\+|\\-) \\]\"" % service_path, use_unsafe_shell=True)
- for line in stdout.split("\n"):
- line_data = line.split()
- if len(line_data) < 4:
- continue # Skipping because we expected more data
- service_name = " ".join(line_data[3:])
- if line_data[1] == "+":
- service_state = "running"
- else:
- service_state = "stopped"
- services[service_name] = {"name": service_name, "state": service_state, "source": "sysv"}
-
- # Upstart
- if initctl_path is not None and chkconfig_path is None:
- p = re.compile(r'^\s?(?P.*)\s(?P\w+)\/(?P\w+)(\,\sprocess\s(?P[0-9]+))?\s*$')
- rc, stdout, stderr = self.module.run_command("%s list" % initctl_path)
- real_stdout = stdout.replace("\r","")
- for line in real_stdout.split("\n"):
- m = p.match(line)
- if not m:
- continue
- service_name = m.group('name')
- service_goal = m.group('goal')
- service_state = m.group('state')
- if m.group('pid'):
- pid = m.group('pid')
- else:
- pid = None # NOQA
- payload = {"name": service_name, "state": service_state, "goal": service_goal, "source": "upstart"}
- services[service_name] = payload
-
- # RH sysvinit
- elif chkconfig_path is not None:
- #print '%s --status-all | grep -E "is (running|stopped)"' % service_path
- p = re.compile(
- r'(?P.*?)\s+[0-9]:(?Pon|off)\s+[0-9]:(?Pon|off)\s+[0-9]:(?Pon|off)\s+'
- r'[0-9]:(?Pon|off)\s+[0-9]:(?Pon|off)\s+[0-9]:(?Pon|off)\s+[0-9]:(?Pon|off)')
- rc, stdout, stderr = self.module.run_command('%s' % chkconfig_path, use_unsafe_shell=True)
- # Check for special cases where stdout does not fit pattern
- match_any = False
- for line in stdout.split('\n'):
- if p.match(line):
- match_any = True
- if not match_any:
- p_simple = re.compile(r'(?P.*?)\s+(?Pon|off)')
- match_any = False
- for line in stdout.split('\n'):
- if p_simple.match(line):
- match_any = True
- if match_any:
- # Try extra flags " -l --allservices" needed for SLES11
- rc, stdout, stderr = self.module.run_command('%s -l --allservices' % chkconfig_path, use_unsafe_shell=True)
- elif '--list' in stderr:
- # Extra flag needed for RHEL5
- rc, stdout, stderr = self.module.run_command('%s --list' % chkconfig_path, use_unsafe_shell=True)
- for line in stdout.split('\n'):
- m = p.match(line)
- if m:
- service_name = m.group('service')
- service_state = 'stopped'
- if m.group('rl3') == 'on':
- rc, stdout, stderr = self.module.run_command('%s %s status' % (service_path, service_name), use_unsafe_shell=True)
- service_state = rc
- if rc in (0,):
- service_state = 'running'
- #elif rc in (1,3):
- else:
- if 'root' in stderr or 'permission' in stderr.lower() or 'not in sudoers' in stderr.lower():
- self.incomplete_warning = True
- continue
- else:
- service_state = 'stopped'
- service_data = {"name": service_name, "state": service_state, "source": "sysv"}
- services[service_name] = service_data
- return services
-
-
-class SystemctlScanService(BaseService):
-
- def systemd_enabled(self):
- # Check if init is the systemd command, using comm as cmdline could be symlink
- try:
- f = open('/proc/1/comm', 'r')
- except IOError:
- # If comm doesn't exist, old kernel, no systemd
- return False
- for line in f:
- if 'systemd' in line:
- return True
- return False
-
- def gather_services(self):
- services = {}
- if not self.systemd_enabled():
- return None
- systemctl_path = self.module.get_bin_path("systemctl", opt_dirs=["/usr/bin", "/usr/local/bin"])
- if systemctl_path is None:
- return None
- rc, stdout, stderr = self.module.run_command("%s list-unit-files --type=service | tail -n +2 | head -n -2" % systemctl_path, use_unsafe_shell=True)
- for line in stdout.split("\n"):
- line_data = line.split()
- if len(line_data) != 2:
- continue
- if line_data[1] == "enabled":
- state_val = "running"
- else:
- state_val = "stopped"
- services[line_data[0]] = {"name": line_data[0], "state": state_val, "source": "systemd"}
- return services
-
-
-def main():
- module = AnsibleModule(argument_spec = dict()) # noqa
- service_modules = (ServiceScanService, SystemctlScanService)
- all_services = {}
- incomplete_warning = False
- for svc_module in service_modules:
- svcmod = svc_module(module)
- svc = svcmod.gather_services()
- if svc is not None:
- all_services.update(svc)
- if svcmod.incomplete_warning:
- incomplete_warning = True
- if len(all_services) == 0:
- results = dict(skipped=True, msg="Failed to find any services. Sometimes this is due to insufficient privileges.")
- else:
- results = dict(ansible_facts=dict(services=all_services))
- if incomplete_warning:
- results['msg'] = "WARNING: Could not find status for all services. Sometimes this is due to insufficient privileges."
- module.exit_json(**results)
-
-
-main()
diff --git a/awx/plugins/library/win_scan_files.ps1 b/awx/plugins/library/win_scan_files.ps1
deleted file mode 100644
index 6d114dfcc8..0000000000
--- a/awx/plugins/library/win_scan_files.ps1
+++ /dev/null
@@ -1,102 +0,0 @@
-#!powershell
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see .
-
-# WANT_JSON
-# POWERSHELL_COMMON
-
-$params = Parse-Args $args $true;
-
-$paths = Get-Attr $params "paths" $FALSE;
-If ($paths -eq $FALSE)
-{
- Fail-Json (New-Object psobject) "missing required argument: paths";
-}
-
-$get_checksum = Get-Attr $params "get_checksum" $false | ConvertTo-Bool;
-$recursive = Get-Attr $params "recursive" $false | ConvertTo-Bool;
-
-function Date_To_Timestamp($start_date, $end_date)
-{
- If($start_date -and $end_date)
- {
- Write-Output (New-TimeSpan -Start $start_date -End $end_date).TotalSeconds
- }
-}
-
-$files = @()
-
-ForEach ($path In $paths)
-{
- "Path: " + $path
- ForEach ($file in Get-ChildItem $path -Recurse: $recursive)
- {
- "File: " + $file.FullName
- $fileinfo = New-Object psobject
- Set-Attr $fileinfo "path" $file.FullName
- $info = Get-Item $file.FullName;
- $iscontainer = Get-Attr $info "PSIsContainer" $null;
- $length = Get-Attr $info "Length" $null;
- $extension = Get-Attr $info "Extension" $null;
- $attributes = Get-Attr $info "Attributes" "";
- If ($info)
- {
- $accesscontrol = $info.GetAccessControl();
- }
- Else
- {
- $accesscontrol = $null;
- }
- $owner = Get-Attr $accesscontrol "Owner" $null;
- $creationtime = Get-Attr $info "CreationTime" $null;
- $lastaccesstime = Get-Attr $info "LastAccessTime" $null;
- $lastwritetime = Get-Attr $info "LastWriteTime" $null;
-
- $epoch_date = Get-Date -Date "01/01/1970"
- If ($iscontainer)
- {
- Set-Attr $fileinfo "isdir" $TRUE;
- }
- Else
- {
- Set-Attr $fileinfo "isdir" $FALSE;
- Set-Attr $fileinfo "size" $length;
- }
- Set-Attr $fileinfo "extension" $extension;
- Set-Attr $fileinfo "attributes" $attributes.ToString();
- # Set-Attr $fileinfo "owner" $getaccesscontrol.Owner;
- # Set-Attr $fileinfo "owner" $info.GetAccessControl().Owner;
- Set-Attr $fileinfo "owner" $owner;
- Set-Attr $fileinfo "creationtime" (Date_To_Timestamp $epoch_date $creationtime);
- Set-Attr $fileinfo "lastaccesstime" (Date_To_Timestamp $epoch_date $lastaccesstime);
- Set-Attr $fileinfo "lastwritetime" (Date_To_Timestamp $epoch_date $lastwritetime);
-
- If (($get_checksum) -and -not $fileinfo.isdir)
- {
- $hash = Get-FileChecksum($file.FullName);
- Set-Attr $fileinfo "checksum" $hash;
- }
-
- $files += $fileinfo
- }
-}
-
-$result = New-Object psobject @{
- ansible_facts = New-Object psobject @{
- files = $files
- }
-}
-
-Exit-Json $result;
diff --git a/awx/plugins/library/win_scan_packages.ps1 b/awx/plugins/library/win_scan_packages.ps1
deleted file mode 100644
index 2ab3fdbec6..0000000000
--- a/awx/plugins/library/win_scan_packages.ps1
+++ /dev/null
@@ -1,66 +0,0 @@
-#!powershell
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see .
-
-# WANT_JSON
-# POWERSHELL_COMMON
-
-$uninstall_native_path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-$uninstall_wow6432_path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
-
-if ([System.IntPtr]::Size -eq 4) {
-
- # This is a 32-bit Windows system, so we only check for 32-bit programs, which will be
- # at the native registry location.
-
- [PSObject []]$packages = Get-ChildItem -Path $uninstall_native_path |
- Get-ItemProperty |
- Select-Object -Property @{Name="name"; Expression={$_."DisplayName"}},
- @{Name="version"; Expression={$_."DisplayVersion"}},
- @{Name="publisher"; Expression={$_."Publisher"}},
- @{Name="arch"; Expression={ "Win32" }} |
- Where-Object { $_.name }
-
-} else {
-
- # This is a 64-bit Windows system, so we check for 64-bit programs in the native
- # registry location, and also for 32-bit programs under Wow6432Node.
-
- [PSObject []]$packages = Get-ChildItem -Path $uninstall_native_path |
- Get-ItemProperty |
- Select-Object -Property @{Name="name"; Expression={$_."DisplayName"}},
- @{Name="version"; Expression={$_."DisplayVersion"}},
- @{Name="publisher"; Expression={$_."Publisher"}},
- @{Name="arch"; Expression={ "Win64" }} |
- Where-Object { $_.name }
-
- $packages += Get-ChildItem -Path $uninstall_wow6432_path |
- Get-ItemProperty |
- Select-Object -Property @{Name="name"; Expression={$_."DisplayName"}},
- @{Name="version"; Expression={$_."DisplayVersion"}},
- @{Name="publisher"; Expression={$_."Publisher"}},
- @{Name="arch"; Expression={ "Win32" }} |
- Where-Object { $_.name }
-
-}
-
-$result = New-Object psobject @{
- ansible_facts = New-Object psobject @{
- packages = $packages
- }
- changed = $false
-}
-
-Exit-Json $result;
diff --git a/awx/plugins/library/win_scan_services.ps1 b/awx/plugins/library/win_scan_services.ps1
deleted file mode 100644
index 3de8ac4c9b..0000000000
--- a/awx/plugins/library/win_scan_services.ps1
+++ /dev/null
@@ -1,30 +0,0 @@
-#!powershell
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see .
-
-# WANT_JSON
-# POWERSHELL_COMMON
-
-$result = New-Object psobject @{
- ansible_facts = New-Object psobject @{
- services = Get-Service |
- Select-Object -Property @{Name="name"; Expression={$_."DisplayName"}},
- @{Name="win_svc_name"; Expression={$_."Name"}},
- @{Name="state"; Expression={$_."Status".ToString().ToLower()}}
- }
- changed = $false
-}
-
-Exit-Json $result;
diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py
index 5aa0b834ea..618f5282a4 100644
--- a/awx/settings/defaults.py
+++ b/awx/settings/defaults.py
@@ -197,12 +197,23 @@ LOCAL_STDOUT_EXPIRE_TIME = 2592000
# events into the database
JOB_EVENT_WORKERS = 4
+# The number of seconds (must be an integer) to buffer callback receiver bulk
+# writes in memory before flushing via JobEvent.objects.bulk_create()
+JOB_EVENT_BUFFER_SECONDS = 1
+
+# The interval at which callback receiver statistics should be
+# recorded
+JOB_EVENT_STATISTICS_INTERVAL = 5
+
# The maximum size of the job event worker queue before requests are blocked
JOB_EVENT_MAX_QUEUE_SIZE = 10000
# The number of job events to migrate per-transaction when moving from int -> bigint
JOB_EVENT_MIGRATION_CHUNK_SIZE = 1000000
+# The maximum allowed jobs to start on a given task manager cycle
+START_TASK_LIMIT = 100
+
# Disallow sending session cookies over insecure connections
SESSION_COOKIE_SECURE = True
@@ -477,6 +488,7 @@ SOCIAL_AUTH_SAML_PIPELINE = _SOCIAL_AUTH_PIPELINE_BASE + (
'awx.sso.pipeline.update_user_orgs',
'awx.sso.pipeline.update_user_teams',
)
+SAML_AUTO_CREATE_OBJECTS = True
SOCIAL_AUTH_LOGIN_URL = '/'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/sso/complete/'
@@ -567,28 +579,9 @@ AWX_COLLECTIONS_ENABLED = True
# Follow symlinks when scanning for playbooks
AWX_SHOW_PLAYBOOK_LINKS = False
-# Settings for primary galaxy server, should be set in the UI
-PRIMARY_GALAXY_URL = ''
-PRIMARY_GALAXY_USERNAME = ''
-PRIMARY_GALAXY_TOKEN = ''
-PRIMARY_GALAXY_PASSWORD = ''
-PRIMARY_GALAXY_AUTH_URL = ''
-
-# Settings for the public galaxy server(s).
-PUBLIC_GALAXY_ENABLED = True
-PUBLIC_GALAXY_SERVER = {
- 'id': 'galaxy',
- 'url': 'https://galaxy.ansible.com'
-}
-
# Applies to any galaxy server
GALAXY_IGNORE_CERTS = False
-# List of dicts of fallback (additional) Galaxy servers. If configured, these
-# will be higher precedence than public Galaxy, but lower than primary Galaxy.
-# Available options: 'id', 'url', 'username', 'password', 'token', 'auth_url'
-FALLBACK_GALAXY_SERVERS = []
-
# Enable bubblewrap support for running jobs (playbook runs only).
# Note: This setting may be overridden by database settings.
AWX_PROOT_ENABLED = True
@@ -789,7 +782,7 @@ ASGI_APPLICATION = "awx.main.routing.application"
CHANNEL_LAYERS = {
"default": {
- "BACKEND": "awx.main.consumers.ExpiringRedisChannelLayer",
+ "BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [BROKER_URL],
"capacity": 10000,
@@ -1002,6 +995,11 @@ LOGGING = {
'handlers': ['task_system', 'external_logger'],
'propagate': False
},
+ 'awx.main.analytics': {
+ 'handlers': ['task_system', 'external_logger'],
+ 'level': 'INFO',
+ 'propagate': False
+ },
'awx.main.scheduler': {
'handlers': ['task_system', 'external_logger'],
'propagate': False
diff --git a/awx/sso/conf.py b/awx/sso/conf.py
index c408d72b40..5f595517cc 100644
--- a/awx/sso/conf.py
+++ b/awx/sso/conf.py
@@ -515,6 +515,7 @@ register(
help_text=_('TACACS+ session timeout value in seconds, 0 disables timeout.'),
category=_('TACACS+'),
category_slug='tacacsplus',
+ unit=_('seconds'),
)
register(
@@ -575,7 +576,7 @@ register(
'SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS',
field_class=fields.StringListField,
default=[],
- label=_('Google OAuth2 Whitelisted Domains'),
+ label=_('Google OAuth2 Allowed Domains'),
help_text=_('Update this setting to restrict the domains who are allowed to '
'login using Google OAuth2.'),
category=_('Google OAuth2'),
@@ -919,6 +920,17 @@ def get_saml_entity_id():
return settings.TOWER_URL_BASE
+register(
+ 'SAML_AUTO_CREATE_OBJECTS',
+ field_class=fields.BooleanField,
+ default=True,
+ label=_('Automatically Create Organizations and Teams on SAML Login'),
+ help_text=_('When enabled (the default), mapped Organizations and Teams '
+ 'will be created automatically on successful SAML login.'),
+ category=_('SAML'),
+ category_slug='saml',
+)
+
register(
'SOCIAL_AUTH_SAML_CALLBACK_URL',
field_class=fields.CharField,
diff --git a/awx/sso/pipeline.py b/awx/sso/pipeline.py
index 6d7e05da90..3e73974474 100644
--- a/awx/sso/pipeline.py
+++ b/awx/sso/pipeline.py
@@ -10,6 +10,7 @@ import logging
from social_core.exceptions import AuthException
# Django
+from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext_lazy as _
from django.db.models import Q
@@ -80,11 +81,18 @@ def _update_m2m_from_expression(user, related, expr, remove=True):
def _update_org_from_attr(user, related, attr, remove, remove_admins, remove_auditors):
from awx.main.models import Organization
+ from django.conf import settings
org_ids = []
for org_name in attr:
- org = Organization.objects.get_or_create(name=org_name)[0]
+ try:
+ if settings.SAML_AUTO_CREATE_OBJECTS:
+ org = Organization.objects.get_or_create(name=org_name)[0]
+ else:
+ org = Organization.objects.get(name=org_name)
+ except ObjectDoesNotExist:
+ continue
org_ids.append(org.id)
getattr(org, related).members.add(user)
@@ -199,11 +207,24 @@ def update_user_teams_by_saml_attr(backend, details, user=None, *args, **kwargs)
if organization_alias:
organization_name = organization_alias
- org = Organization.objects.get_or_create(name=organization_name)[0]
+
+ try:
+ if settings.SAML_AUTO_CREATE_OBJECTS:
+ org = Organization.objects.get_or_create(name=organization_name)[0]
+ else:
+ org = Organization.objects.get(name=organization_name)
+ except ObjectDoesNotExist:
+ continue
if team_alias:
team_name = team_alias
- team = Team.objects.get_or_create(name=team_name, organization=org)[0]
+ try:
+ if settings.SAML_AUTO_CREATE_OBJECTS:
+ team = Team.objects.get_or_create(name=team_name, organization=org)[0]
+ else:
+ team = Team.objects.get(name=team_name, organization=org)
+ except ObjectDoesNotExist:
+ continue
team_ids.append(team.id)
team.member_role.members.add(user)
diff --git a/awx/sso/tests/functional/test_pipeline.py b/awx/sso/tests/functional/test_pipeline.py
index 06d5503db8..e691939752 100644
--- a/awx/sso/tests/functional/test_pipeline.py
+++ b/awx/sso/tests/functional/test_pipeline.py
@@ -174,8 +174,15 @@ class TestSAMLAttr():
return (o1, o2, o3)
@pytest.fixture
- def mock_settings(self):
+ def mock_settings(self, request):
+ fixture_args = request.node.get_closest_marker('fixture_args')
+ if fixture_args and 'autocreate' in fixture_args.kwargs:
+ autocreate = fixture_args.kwargs['autocreate']
+ else:
+ autocreate = True
+
class MockSettings():
+ SAML_AUTO_CREATE_OBJECTS = autocreate
SOCIAL_AUTH_SAML_ORGANIZATION_ATTR = {
'saml_attr': 'memberOf',
'saml_admin_attr': 'admins',
@@ -304,3 +311,41 @@ class TestSAMLAttr():
assert Team.objects.get(
name='Yellow_Alias', organization__name='Default4_Alias').member_role.members.count() == 1
+ @pytest.mark.fixture_args(autocreate=False)
+ def test_autocreate_disabled(self, users, kwargs, mock_settings):
+ kwargs['response']['attributes']['memberOf'] = ['Default1', 'Default2', 'Default3']
+ kwargs['response']['attributes']['groups'] = ['Blue', 'Red', 'Green']
+ with mock.patch('django.conf.settings', mock_settings):
+ for u in users:
+ update_user_orgs_by_saml_attr(None, None, u, **kwargs)
+ update_user_teams_by_saml_attr(None, None, u, **kwargs)
+ assert Organization.objects.count() == 0
+ assert Team.objects.count() == 0
+
+ # precreate everything
+ o1 = Organization.objects.create(name='Default1')
+ o2 = Organization.objects.create(name='Default2')
+ o3 = Organization.objects.create(name='Default3')
+ Team.objects.create(name='Blue', organization_id=o1.id)
+ Team.objects.create(name='Blue', organization_id=o2.id)
+ Team.objects.create(name='Blue', organization_id=o3.id)
+ Team.objects.create(name='Red', organization_id=o1.id)
+ Team.objects.create(name='Green', organization_id=o1.id)
+ Team.objects.create(name='Green', organization_id=o3.id)
+
+ for u in users:
+ update_user_orgs_by_saml_attr(None, None, u, **kwargs)
+ update_user_teams_by_saml_attr(None, None, u, **kwargs)
+
+ assert o1.member_role.members.count() == 3
+ assert o2.member_role.members.count() == 3
+ assert o3.member_role.members.count() == 3
+
+ assert Team.objects.get(name='Blue', organization__name='Default1').member_role.members.count() == 3
+ assert Team.objects.get(name='Blue', organization__name='Default2').member_role.members.count() == 3
+ assert Team.objects.get(name='Blue', organization__name='Default3').member_role.members.count() == 3
+
+ assert Team.objects.get(name='Red', organization__name='Default1').member_role.members.count() == 3
+
+ assert Team.objects.get(name='Green', organization__name='Default1').member_role.members.count() == 3
+ assert Team.objects.get(name='Green', organization__name='Default3').member_role.members.count() == 3
diff --git a/awx/ui/client/features/output/stream.service.js b/awx/ui/client/features/output/stream.service.js
index 11198e0752..c3cfa10622 100644
--- a/awx/ui/client/features/output/stream.service.js
+++ b/awx/ui/client/features/output/stream.service.js
@@ -119,6 +119,10 @@ function OutputStream ($q) {
this.counters.ready = ready;
this.counters.used = used;
this.counters.missing = missing;
+
+ if (!window.liveUpdates) {
+ this.counters.ready = event.counter;
+ }
};
this.bufferEmpty = threshold => {
@@ -141,6 +145,10 @@ function OutputStream ($q) {
const { total } = this.counters;
const readyCount = this.getReadyCount();
+ if (!window.liveUpdates) {
+ return true;
+ }
+
if (readyCount <= 0) {
return false;
}
diff --git a/awx/ui/client/lib/components/input/secret.partial.html b/awx/ui/client/lib/components/input/secret.partial.html
index 7c0f1e8e61..9f72965e7c 100644
--- a/awx/ui/client/lib/components/input/secret.partial.html
+++ b/awx/ui/client/lib/components/input/secret.partial.html
@@ -23,12 +23,12 @@
icon="external"
tag="state._tagValue"
remove-tag="state._onRemoveTag(state)"
- />
+ >
+ >
{
+ angular.forEach($cookies.getAll(), (val, name) => {
+ $cookies.remove(name);
+ });
+ $window.location.reload();
+ // this is used because $location only lets you navigate inside
+ // the "/#/" path, and these are API urls.
+ $window.location.href = link;
+ });
};
}];
diff --git a/awx/ui/client/src/organizations/add/organizations-add.controller.js b/awx/ui/client/src/organizations/add/organizations-add.controller.js
index cd6aea6cb9..4b86b0db74 100644
--- a/awx/ui/client/src/organizations/add/organizations-add.controller.js
+++ b/awx/ui/client/src/organizations/add/organizations-add.controller.js
@@ -4,11 +4,12 @@
* All Rights Reserved
*************************************************/
-export default ['$scope', '$rootScope', '$location', '$stateParams',
- 'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
- 'ProcessErrors', 'GetBasePath', 'Wait', 'CreateSelect2', '$state','InstanceGroupsService', 'ConfigData',
- function($scope, $rootScope, $location, $stateParams, OrganizationForm,
- GenerateForm, Rest, Alert, ProcessErrors, GetBasePath, Wait, CreateSelect2, $state, InstanceGroupsService, ConfigData) {
+export default ['$scope', '$rootScope', '$location', '$stateParams', 'OrganizationForm',
+ 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'Wait', 'CreateSelect2',
+ '$state','InstanceGroupsService', 'ConfigData', 'MultiCredentialService', 'defaultGalaxyCredential',
+ function($scope, $rootScope, $location, $stateParams, OrganizationForm,
+ GenerateForm, Rest, Alert, ProcessErrors, GetBasePath, Wait, CreateSelect2,
+ $state, InstanceGroupsService, ConfigData, MultiCredentialService, defaultGalaxyCredential) {
Rest.setUrl(GetBasePath('organizations'));
Rest.options()
@@ -37,6 +38,8 @@ export default ['$scope', '$rootScope', '$location', '$stateParams',
// apply form definition's default field values
GenerateForm.applyDefaults(form, $scope);
+
+ $scope.credentials = defaultGalaxyCredential || [];
}
// Save
@@ -57,18 +60,32 @@ export default ['$scope', '$rootScope', '$location', '$stateParams',
const organization_id = data.id,
instance_group_url = data.related.instance_groups;
- InstanceGroupsService.addInstanceGroups(instance_group_url, $scope.instance_groups)
+ MultiCredentialService
+ .saveRelatedSequentially({
+ related: {
+ credentials: data.related.galaxy_credentials
+ }
+ }, $scope.credentials)
.then(() => {
- Wait('stop');
- $rootScope.$broadcast("EditIndicatorChange", "organizations", organization_id);
- $state.go('organizations.edit', {organization_id: organization_id}, {reload: true});
- })
- .catch(({data, status}) => {
+ InstanceGroupsService.addInstanceGroups(instance_group_url, $scope.instance_groups)
+ .then(() => {
+ Wait('stop');
+ $rootScope.$broadcast("EditIndicatorChange", "organizations", organization_id);
+ $state.go('organizations.edit', {organization_id: organization_id}, {reload: true});
+ })
+ .catch(({data, status}) => {
+ ProcessErrors($scope, data, status, form, {
+ hdr: 'Error!',
+ msg: 'Failed to save instance groups. POST returned status: ' + status
+ });
+ });
+ }).catch(({data, status}) => {
ProcessErrors($scope, data, status, form, {
hdr: 'Error!',
- msg: 'Failed to save instance groups. POST returned status: ' + status
+ msg: 'Failed to save Galaxy credentials. POST returned status: ' + status
});
});
+
})
.catch(({data, status}) => {
let explanation = _.has(data, "name") ? data.name[0] : "";
diff --git a/awx/ui/client/src/organizations/edit/organizations-edit.controller.js b/awx/ui/client/src/organizations/edit/organizations-edit.controller.js
index 74397b02cc..9ffe8e859b 100644
--- a/awx/ui/client/src/organizations/edit/organizations-edit.controller.js
+++ b/awx/ui/client/src/organizations/edit/organizations-edit.controller.js
@@ -6,10 +6,12 @@
export default ['$scope', '$location', '$stateParams', 'isOrgAdmin', 'isNotificationAdmin',
'OrganizationForm', 'Rest', 'ProcessErrors', 'Prompt', 'i18n', 'isOrgAuditor',
- 'GetBasePath', 'Wait', '$state', 'ToggleNotification', 'CreateSelect2', 'InstanceGroupsService', 'InstanceGroupsData', 'ConfigData',
+ 'GetBasePath', 'Wait', '$state', 'ToggleNotification', 'CreateSelect2', 'InstanceGroupsService',
+ 'InstanceGroupsData', 'ConfigData', 'GalaxyCredentialsData', 'MultiCredentialService',
function($scope, $location, $stateParams, isOrgAdmin, isNotificationAdmin,
OrganizationForm, Rest, ProcessErrors, Prompt, i18n, isOrgAuditor,
- GetBasePath, Wait, $state, ToggleNotification, CreateSelect2, InstanceGroupsService, InstanceGroupsData, ConfigData) {
+ GetBasePath, Wait, $state, ToggleNotification, CreateSelect2, InstanceGroupsService,
+ InstanceGroupsData, ConfigData, GalaxyCredentialsData, MultiCredentialService) {
let form = OrganizationForm(),
defaultUrl = GetBasePath('organizations'),
@@ -29,6 +31,7 @@ export default ['$scope', '$location', '$stateParams', 'isOrgAdmin', 'isNotifica
});
$scope.instance_groups = InstanceGroupsData;
+ $scope.credentials = GalaxyCredentialsData;
const virtualEnvs = ConfigData.custom_virtualenvs || [];
$scope.custom_virtualenvs_visible = virtualEnvs.length > 1;
$scope.custom_virtualenvs_options = virtualEnvs.filter(
@@ -100,7 +103,14 @@ export default ['$scope', '$location', '$stateParams', 'isOrgAdmin', 'isNotifica
Rest.setUrl(defaultUrl + id + '/');
Rest.put(params)
.then(() => {
- InstanceGroupsService.editInstanceGroups(instance_group_url, $scope.instance_groups)
+ MultiCredentialService
+ .saveRelatedSequentially({
+ related: {
+ credentials: $scope.organization_obj.related.galaxy_credentials
+ }
+ }, $scope.credentials)
+ .then(() => {
+ InstanceGroupsService.editInstanceGroups(instance_group_url, $scope.instance_groups)
.then(() => {
Wait('stop');
$state.go($state.current, {}, { reload: true });
@@ -111,6 +121,12 @@ export default ['$scope', '$location', '$stateParams', 'isOrgAdmin', 'isNotifica
msg: 'Failed to update instance groups. POST returned status: ' + status
});
});
+ }).catch(({data, status}) => {
+ ProcessErrors($scope, data, status, form, {
+ hdr: 'Error!',
+ msg: 'Failed to save Galaxy credentials. POST returned status: ' + status
+ });
+ });
$scope.organization_name = $scope.name;
main = params;
})
diff --git a/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.directive.js b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.directive.js
new file mode 100644
index 0000000000..c91726a570
--- /dev/null
+++ b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.directive.js
@@ -0,0 +1,123 @@
+export default ['templateUrl', '$window', function(templateUrl, $window) {
+ return {
+ restrict: 'E',
+ scope: {
+ galaxyCredentials: '='
+ },
+ templateUrl: templateUrl('organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal'),
+
+ link: function(scope, element) {
+
+ $('#galaxy-credentials-modal').on('hidden.bs.modal', function () {
+ $('#galaxy-credentials-modal').off('hidden.bs.modal');
+ $(element).remove();
+ });
+
+ scope.showModal = function() {
+ $('#galaxy-credentials-modal').modal('show');
+ };
+
+ scope.destroyModal = function() {
+ $('#galaxy-credentials-modal').modal('hide');
+ };
+ },
+
+ controller: ['$scope', '$compile', 'QuerySet', 'GetBasePath','generateList', 'CredentialList', function($scope, $compile, qs, GetBasePath, GenerateList, CredentialList) {
+
+ function init() {
+
+ $scope.credential_queryset = {
+ order_by: 'name',
+ page_size: 5,
+ credential_type__kind: 'galaxy'
+ };
+
+ $scope.credential_default_params = {
+ order_by: 'name',
+ page_size: 5,
+ credential_type__kind: 'galaxy'
+ };
+
+ qs.search(GetBasePath('credentials'), $scope.credential_queryset)
+ .then(res => {
+ $scope.credential_dataset = res.data;
+ $scope.credentials = $scope.credential_dataset.results;
+
+ let credentialList = _.cloneDeep(CredentialList);
+
+ credentialList.listTitle = false;
+ credentialList.well = false;
+ credentialList.multiSelect = true;
+ credentialList.multiSelectPreview = {
+ selectedRows: 'credTags',
+ availableRows: 'credentials'
+ };
+ credentialList.fields.name.ngClick = "linkoutCredential(credential)";
+ credentialList.fields.name.columnClass = 'col-md-11 col-sm-11 col-xs-11';
+ delete credentialList.fields.consumed_capacity;
+ delete credentialList.fields.jobs_running;
+
+ let html = `${GenerateList.build({
+ list: credentialList,
+ input_type: 'galaxy-credentials-modal-body',
+ hideViewPerPage: true,
+ mode: 'lookup'
+ })}`;
+
+ $scope.list = credentialList;
+ $('#galaxy-credentials-modal-body').append($compile(html)($scope));
+
+ if ($scope.galaxyCredentials) {
+ $scope.galaxyCredentials = $scope.galaxyCredentials.map( (item) => {
+ item.isSelected = true;
+ if (!$scope.credTags) {
+ $scope.credTags = [];
+ }
+ $scope.credTags.push(item);
+ return item;
+ });
+ }
+
+ $scope.showModal();
+ });
+
+ $scope.$watch('credentials', function(){
+ angular.forEach($scope.credentials, function(credentialRow) {
+ angular.forEach($scope.credTags, function(selectedCredential){
+ if(selectedCredential.id === credentialRow.id) {
+ credentialRow.isSelected = true;
+ }
+ });
+ });
+ });
+ }
+
+ init();
+
+ $scope.$on("selectedOrDeselected", function(e, value) {
+ let item = value.value;
+ if (value.isSelected) {
+ if(!$scope.credTags) {
+ $scope.credTags = [];
+ }
+ $scope.credTags.push(item);
+ } else {
+ _.remove($scope.credTags, { id: item.id });
+ }
+ });
+
+ $scope.linkoutCredential = function(credential) {
+ $window.open('/#/credentials/' + credential.id,'_blank');
+ };
+
+ $scope.cancelForm = function() {
+ $scope.destroyModal();
+ };
+
+ $scope.saveForm = function() {
+ $scope.galaxyCredentials = $scope.credTags;
+ $scope.destroyModal();
+ };
+ }]
+ };
+}];
diff --git a/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html
new file mode 100644
index 0000000000..dbf481005e
--- /dev/null
+++ b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html
@@ -0,0 +1,22 @@
+
diff --git a/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-multiselect.controller.js b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-multiselect.controller.js
new file mode 100644
index 0000000000..548f528798
--- /dev/null
+++ b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-multiselect.controller.js
@@ -0,0 +1,14 @@
+export default ['$scope',
+ function($scope) {
+
+ $scope.galaxyCredentialsTags = [];
+
+ $scope.$watch('galaxyCredentials', function() {
+ $scope.galaxyCredentialsTags = $scope.galaxyCredentials;
+ }, true);
+
+ $scope.deleteTag = function(tag){
+ _.remove($scope.galaxyCredentials, {id: tag.id});
+ };
+ }
+];
\ No newline at end of file
diff --git a/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.block.less b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.block.less
new file mode 100644
index 0000000000..bbfef9de99
--- /dev/null
+++ b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.block.less
@@ -0,0 +1,15 @@
+#instance-groups-panel {
+ table {
+ overflow: hidden;
+ }
+ .List-header {
+ margin-bottom: 20px;
+ }
+ .isActive {
+ border-left: 10px solid @list-row-select-bord;
+ }
+ .instances-list,
+ .instance-jobs-list {
+ margin-top: 20px;
+ }
+}
diff --git a/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.directive.js b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.directive.js
new file mode 100644
index 0000000000..d966c5e519
--- /dev/null
+++ b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.directive.js
@@ -0,0 +1,19 @@
+import galaxyCredentialsMultiselectController from './galaxy-credentials-multiselect.controller';
+export default ['templateUrl', '$compile',
+ function(templateUrl, $compile) {
+ return {
+ scope: {
+ galaxyCredentials: '=',
+ fieldIsDisabled: '='
+ },
+ restrict: 'E',
+ templateUrl: templateUrl('organizations/galaxy-credentials-multiselect/galaxy-credentials'),
+ controller: galaxyCredentialsMultiselectController,
+ link: function(scope) {
+ scope.openInstanceGroupsModal = function() {
+ $('#content-container').append($compile(' ')(scope));
+ };
+ }
+ };
+ }
+];
diff --git a/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.partial.html b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.partial.html
new file mode 100644
index 0000000000..09202327b4
--- /dev/null
+++ b/awx/ui/client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.partial.html
@@ -0,0 +1,18 @@
+
diff --git a/awx/ui/client/src/organizations/main.js b/awx/ui/client/src/organizations/main.js
index 8540261ede..365f4e6e67 100644
--- a/awx/ui/client/src/organizations/main.js
+++ b/awx/ui/client/src/organizations/main.js
@@ -12,8 +12,10 @@ import organizationsLinkout from './linkout/main';
import OrganizationsLinkoutStates from './linkout/organizations-linkout.route';
import OrganizationForm from './organizations.form';
import OrganizationList from './organizations.list';
-import { N_ } from '../i18n';
+import galaxyCredentialsMultiselect from './galaxy-credentials-multiselect/galaxy-credentials.directive';
+import galaxyCredentialsModal from './galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.directive';
+import { N_ } from '../i18n';
export default
angular.module('Organizations', [
@@ -24,6 +26,8 @@ angular.module('Organizations', [
.controller('OrganizationsEdit', OrganizationsEdit)
.factory('OrganizationForm', OrganizationForm)
.factory('OrganizationList', OrganizationList)
+ .directive('galaxyCredentialsMultiselect', galaxyCredentialsMultiselect)
+ .directive('galaxyCredentialsModal', galaxyCredentialsModal)
.config(['$stateProvider', 'stateDefinitionsProvider', '$stateExtenderProvider',
function($stateProvider, stateDefinitionsProvider, $stateExtenderProvider) {
let stateExtender = $stateExtenderProvider.$get(),
@@ -67,7 +71,29 @@ angular.module('Organizations', [
});
});
- }]
+ }],
+ defaultGalaxyCredential: ['Rest', 'GetBasePath', 'ProcessErrors',
+ function(Rest, GetBasePath, ProcessErrors){
+ Rest.setUrl(GetBasePath('credentials'));
+ return Rest.get({
+ params: {
+ credential_type__kind: 'galaxy',
+ managed_by_tower: true
+ }
+ })
+ .then(({data}) => {
+ if (data.results.length > 0) {
+ return data.results;
+ }
+ })
+ .catch(({data, status}) => {
+ ProcessErrors(null, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to get default Galaxy credential. GET returned ' +
+ 'status: ' + status
+ });
+ });
+ }],
},
edit: {
ConfigData: ['ConfigService', 'ProcessErrors', (ConfigService, ProcessErrors) => {
@@ -81,6 +107,24 @@ angular.module('Organizations', [
});
});
}],
+ GalaxyCredentialsData: ['$stateParams', 'Rest', 'GetBasePath', 'ProcessErrors',
+ function($stateParams, Rest, GetBasePath, ProcessErrors){
+ let path = `${GetBasePath('organizations')}${$stateParams.organization_id}/galaxy_credentials/`;
+ Rest.setUrl(path);
+ return Rest.get()
+ .then(({data}) => {
+ if (data.results.length > 0) {
+ return data.results;
+ }
+ })
+ .catch(({data, status}) => {
+ ProcessErrors(null, data, status, null, {
+ hdr: 'Error!',
+ msg: 'Failed to get credentials. GET returned ' +
+ 'status: ' + status
+ });
+ });
+ }],
InstanceGroupsData: ['$stateParams', 'Rest', 'GetBasePath', 'ProcessErrors',
function($stateParams, Rest, GetBasePath, ProcessErrors){
let path = `${GetBasePath('organizations')}${$stateParams.organization_id}/instance_groups/`;
diff --git a/awx/ui/client/src/organizations/organizations.form.js b/awx/ui/client/src/organizations/organizations.form.js
index 19f6e87419..48446d4599 100644
--- a/awx/ui/client/src/organizations/organizations.form.js
+++ b/awx/ui/client/src/organizations/organizations.form.js
@@ -55,6 +55,15 @@ export default ['NotificationsList', 'i18n',
ngDisabled: '!(organization_obj.summary_fields.user_capabilities.edit || canAdd)',
ngShow: 'custom_virtualenvs_visible'
},
+ credential: {
+ label: i18n._('Galaxy Credentials'),
+ type: 'custom',
+ awPopOver: "" + i18n._("Select Galaxy credentials. The selection order sets the order in which Tower will download roles/collections using `ansible-galaxy`.") + "
",
+ dataTitle: i18n._('Galaxy Credentials'),
+ dataContainer: 'body',
+ dataPlacement: 'right',
+ control: ' ',
+ },
max_hosts: {
label: i18n._('Max Hosts'),
type: 'number',
@@ -69,7 +78,7 @@ export default ['NotificationsList', 'i18n',
awPopOver: "" + i18n._("The maximum number of hosts allowed to be managed by this organization. Value defaults to 0 which means no limit. Refer to the Ansible documentation for more details.") + "
",
ngDisabled: '!current_user.is_superuser',
ngShow: 'BRAND_NAME === "Tower"'
- }
+ },
},
buttons: { //for now always generates tags
diff --git a/awx/ui/client/src/shared/Modal.js b/awx/ui/client/src/shared/Modal.js
index 6e7c73ae8c..1bcdd48314 100644
--- a/awx/ui/client/src/shared/Modal.js
+++ b/awx/ui/client/src/shared/Modal.js
@@ -203,7 +203,7 @@ angular.module('ModalDialog', ['Utilities'])
* })
*
* Use to resize a textarea field contained on a modal. Has only been tested where the
- * form contains 1 textarea and the the textarea is at the bottom of the form/modal.
+ * form contains 1 textarea and the textarea is at the bottom of the form/modal.
*
**/
.factory('TextareaResize', ['ParseTypeChange', 'Wait', function(ParseTypeChange, Wait){
diff --git a/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js b/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js
index a7efb2e550..0665db8529 100644
--- a/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js
+++ b/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js
@@ -122,7 +122,7 @@
selected-id="webhookCredential.modalSelectedId"
on-ready="handleWebhookCredentialModalReady"
on-item-select="handleWebhookCredentialModalItemSelect"
- />
+ >
+ >
{
+ Rest.setUrl(related.credentials);
+ return Rest
+ .get()
+ .then(res => {
+ const { data: { results = [] } } = res;
+ const updatedCredentialIds = (credentials || []).map(({ id }) => id);
+ const currentCredentialIds = results.map(({ id }) => id);
+ const credentialIdsToAssociate = [];
+ const credentialIdsToDisassociate = [];
+ let disassociateRemainingIds = false;
+
+ currentCredentialIds.forEach((currentId, position) => {
+ if (!disassociateRemainingIds && updatedCredentialIds[position] !== currentId) {
+ disassociateRemainingIds = true;
+ }
+
+ if (disassociateRemainingIds) {
+ credentialIdsToDisassociate.push(currentId);
+ }
+ });
+
+ updatedCredentialIds.forEach(updatedId => {
+ if (credentialIdsToDisassociate.includes(updatedId)) {
+ credentialIdsToAssociate.push(updatedId);
+ } else if (!currentCredentialIds.includes(updatedId)) {
+ credentialIdsToAssociate.push(updatedId);
+ }
+ });
+
+ let disassociationPromise = Promise.resolve();
+ credentialIdsToDisassociate.forEach(id => {
+ disassociationPromise = disassociationPromise.then(() => disassociate({ related }, id));
+ });
+
+ return disassociationPromise
+ .then(() => {
+ let associationPromise = Promise.resolve();
+ credentialIdsToAssociate.forEach(id => {
+ associationPromise = associationPromise.then(() => associate({ related }, id));
+ });
+ return associationPromise;
+ });
+ });
+ };
+
this.getRelated = ({ related }, params = { permitted: [] }) => {
Rest.setUrl(related.credentials);
return Rest
diff --git a/awx/ui/client/src/templates/workflows/add-workflow/workflow-add.controller.js b/awx/ui/client/src/templates/workflows/add-workflow/workflow-add.controller.js
index fcd97a1338..8f7e8147d4 100644
--- a/awx/ui/client/src/templates/workflows/add-workflow/workflow-add.controller.js
+++ b/awx/ui/client/src/templates/workflows/add-workflow/workflow-add.controller.js
@@ -140,7 +140,7 @@ export default [
selected-id="webhookCredential.modalSelectedId"
on-ready="handleWebhookCredentialModalReady"
on-item-select="handleWebhookCredentialModalItemSelect"
- />
+ >
+ >
\n"
-" view cloudforms.ini in the Ansible Collections github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax."
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:242
+msgid "Override variables found in cloudforms.ini and used by the inventory update script. For an example variable configuration"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:217
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:177
msgid "Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:299
-msgid ""
-"Override variables found in foreman.ini and used by the inventory update script. For an example variable configuration\n"
-" \n"
-" view foreman.ini in the Ansible Collections github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax."
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:259
+msgid "Override variables found in foreman.ini and used by the inventory update script. For an example variable configuration"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:265
-msgid ""
-"Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration\n"
-" \n"
-" view openstack.yml in the Openstack github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax."
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:225
+msgid "Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:241
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:201
msgid "Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables"
msgstr ""
#: client/features/output/output.strings.js:83
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:350
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:355
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:340
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:345
msgid "Overwrite"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:361
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:366
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:351
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:356
msgid "Overwrite Variables"
msgstr ""
@@ -4513,7 +4450,7 @@ msgstr ""
msgid "Page"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:252
+#: client/src/notifications/notificationTemplates.form.js:236
msgid "Pagerduty subdomain"
msgstr ""
@@ -4608,7 +4545,7 @@ msgstr ""
#: client/src/credentials/credentials.form.js:438
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:104
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:101
-#: client/src/organizations/organizations.form.js:143
+#: client/src/organizations/organizations.form.js:152
#: client/src/projects/projects.form.js:278
#: client/src/teams/teams.form.js:128
#: client/src/templates/job_templates/job-template.form.js:532
@@ -4854,14 +4791,14 @@ msgstr ""
msgid "Please save before adding notifications."
msgstr ""
-#: client/src/organizations/organizations.form.js:95
+#: client/src/organizations/organizations.form.js:104
#: client/src/teams/teams.form.js:72
msgid "Please save before adding users."
msgstr ""
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:100
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:97
-#: client/src/organizations/organizations.form.js:135
+#: client/src/organizations/organizations.form.js:144
#: client/src/projects/projects.form.js:270
#: client/src/teams/teams.form.js:124
#: client/src/templates/job_templates/job-template.form.js:525
@@ -5109,16 +5046,6 @@ msgstr ""
msgid "Prompt on launch"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:253
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:266
-msgid "Provide a comma-separated list of filter expressions."
-msgstr ""
-
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:269
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:284
-msgid "Provide a comma-separated list of filter expressions. Hosts are imported when all of the filters match. Refer to Ansible Tower documentation for more detail."
-msgstr ""
-
#: client/src/inventories-hosts/hosts/host.form.js:49
#: client/src/inventories-hosts/inventories/related/groups/related/nested-hosts/group-nested-hosts.form.js:48
#: client/src/inventories-hosts/inventories/related/hosts/related-host.form.js:50
@@ -5138,15 +5065,10 @@ msgstr ""
msgid "Provide account information using Google Compute Engine JSON credentials file."
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:195
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:155
msgid "Provide environment variables to pass to the custom inventory script."
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:272
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:287
-msgid "Provide the named URL encoded name or id of the remote Tower inventory to be imported."
-msgstr ""
-
#: client/src/license/license.partial.html:128
msgid "Provide your Red Hat customer credentials and you can choose from a list of your available licenses. The credentials you use will be stored for future use in retrieving renewal or expanded licenses. You can update or remove them in SETTINGS > SYSTEM."
msgstr ""
@@ -5236,7 +5158,7 @@ msgid "RESULTS"
msgstr ""
#: client/features/templates/templates.strings.js:39
-#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:50
+#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:51
msgid "REVERT"
msgstr ""
@@ -5357,13 +5279,8 @@ msgstr ""
msgid "Refspec"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:246
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:258
-msgid "Region:"
-msgstr ""
-
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:130
-msgid "Regions"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:308
+msgid "Regular expression where only matching host names will be imported. The filter is applied as a post-processing step after any inventory plugin filters are applied."
msgstr ""
#: client/src/inventories-hosts/inventories/related/hosts/related-host.list.js:81
@@ -5448,6 +5365,10 @@ msgstr ""
msgid "Resources are missing from this template."
msgstr ""
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:318
+msgid "Retrieve the enabled state from the given dict of host variables. The enabled variable may be specified using dot notation, e.g: 'foo.bar'"
+msgstr ""
+
#: client/lib/services/base-string.service.js:111
msgid "Return"
msgstr ""
@@ -5475,7 +5396,7 @@ msgstr ""
#: client/src/configuration/forms/auth-form/sub-forms/auth-radius.form.js:34
#: client/src/configuration/forms/auth-form/sub-forms/auth-saml.form.js:121
#: client/src/configuration/forms/auth-form/sub-forms/auth-tacacs.form.js:47
-#: client/src/configuration/forms/jobs-form/configuration-jobs.form.js:129
+#: client/src/configuration/forms/jobs-form/configuration-jobs.form.js:110
#: client/src/configuration/forms/system-form/sub-forms/system-activity-stream.form.js:26
#: client/src/configuration/forms/system-form/sub-forms/system-logging.form.js:74
#: client/src/configuration/forms/system-form/sub-forms/system-misc.form.js:95
@@ -5497,7 +5418,7 @@ msgstr ""
#: client/src/credentials/credentials.form.js:461
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:130
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:127
-#: client/src/organizations/organizations.form.js:165
+#: client/src/organizations/organizations.form.js:174
#: client/src/projects/projects.form.js:301
#: client/src/teams/teams.form.js:109
#: client/src/teams/teams.form.js:148
@@ -5531,6 +5452,7 @@ msgstr ""
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory-host-filter/host-filter-modal/host-filter-modal.partial.html:17
#: client/src/inventories-hosts/shared/associate-groups/associate-groups.partial.html:17
#: client/src/inventories-hosts/shared/associate-hosts/associate-hosts.partial.html:17
+#: client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html:18
#: client/src/partials/survey-maker-modal.html:84
#: client/src/shared/instance-groups-multiselect/instance-groups-modal/instance-groups-modal.partial.html:18
msgid "SAVE"
@@ -5639,7 +5561,7 @@ msgstr ""
#: client/src/license/license.partial.html:260
#: client/src/templates/job_templates/add-job-template/job-template-add.controller.js:137
#: client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js:186
-#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:74
+#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:75
#: client/src/templates/workflows/add-workflow/workflow-add.controller.js:155
#: client/src/templates/workflows/edit-workflow/workflow-edit.controller.js:194
msgid "SELECT"
@@ -5699,7 +5621,7 @@ msgstr ""
msgid "SHOW"
msgstr ""
-#: client/src/login/loginModal/loginModal.partial.html:109
+#: client/src/login/loginModal/loginModal.partial.html:114
msgid "SIGN IN"
msgstr ""
@@ -5737,7 +5659,7 @@ msgstr ""
msgid "SSH key description"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:551
+#: client/src/notifications/notificationTemplates.form.js:523
msgid "SSL Connection"
msgstr ""
@@ -5841,7 +5763,7 @@ msgstr ""
#: client/lib/components/components.strings.js:72
#: client/src/activity-stream/streamDropdownNav/stream-dropdown-nav.directive.js:35
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:434
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:424
#: client/src/projects/projects.form.js:321
#: client/src/templates/job_templates/job-template.form.js:578
#: client/src/templates/workflows.form.js:333
@@ -5861,11 +5783,6 @@ msgstr ""
msgid "Secret Key"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:247
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:259
-msgid "Security Group:"
-msgstr ""
-
#: client/src/credentials/credentials.form.js:124
msgid "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."
msgstr ""
@@ -5876,6 +5793,14 @@ msgstr ""
msgid "Select"
msgstr ""
+#: client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html:5
+msgid "Select Galaxy Credentials"
+msgstr ""
+
+#: client/src/organizations/organizations.form.js:61
+msgid "Select Galaxy credentials. The selection order sets the order in which Tower will download roles/collections using `ansible-galaxy`."
+msgstr ""
+
#: client/src/shared/instance-groups-multiselect/instance-groups-modal/instance-groups-modal.partial.html:5
msgid "Select Instance Groups"
msgstr ""
@@ -6021,11 +5946,6 @@ msgstr ""
msgid "Select types"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:239
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:251
-msgid "Select which groups to create automatically."
-msgstr ""
-
#: client/src/license/license.partial.html:153
msgid "Selected"
msgstr ""
@@ -6193,8 +6113,8 @@ msgstr ""
msgid "Source Details"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:212
-#: client/src/notifications/notificationTemplates.form.js:213
+#: client/src/notifications/notificationTemplates.form.js:196
+#: client/src/notifications/notificationTemplates.form.js:197
msgid "Source Phone Number"
msgstr ""
@@ -6202,22 +6122,18 @@ msgstr ""
msgid "Source Project"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:135
-msgid "Source Regions"
-msgstr ""
-
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:208
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:215
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:232
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:239
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:256
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:263
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:273
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:280
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:290
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:297
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:307
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:314
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:168
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:175
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:192
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:199
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:216
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:223
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:233
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:240
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:250
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:257
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:267
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:274
msgid "Source Variables"
msgstr ""
@@ -6235,7 +6151,7 @@ msgstr ""
msgid "Sources"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:420
+#: client/src/notifications/notificationTemplates.form.js:392
msgid "Specify HTTP Headers in JSON format. Refer to the Ansible Tower documentation for example syntax."
msgstr ""
@@ -6243,11 +6159,11 @@ msgstr ""
msgid "Specify a method for %s operations. This is equivalent to specifying the %s parameter, where %s could be %s"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:574
+#: client/src/notifications/notificationTemplates.form.js:546
msgid "Specify a notification color. Acceptable colors are hex color code (example: #3af or #789abc) ."
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:375
+#: client/src/notifications/notificationTemplates.form.js:347
msgid "Specify a notification color. Acceptable colors are: yellow, green, red purple, gray or random."
msgstr ""
@@ -6255,15 +6171,10 @@ msgstr ""
msgid "Specify a scope for the token's access"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:432
+#: client/src/notifications/notificationTemplates.form.js:404
msgid "Specify an HTTP method for the webhook. Acceptable choices are: POST or PUT"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:268
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:283
-msgid "Specify which groups to create automatically. Group names will be created similar to the options selected. If blank, all groups above are created. Refer to Ansible Tower documentation for more detail."
-msgstr ""
-
#: client/features/output/output.strings.js:135
msgid "Standard Error"
msgstr ""
@@ -6282,11 +6193,11 @@ msgstr ""
msgid "Start Date"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:597
+#: client/src/notifications/notificationTemplates.form.js:569
msgid "Start Message"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:608
+#: client/src/notifications/notificationTemplates.form.js:580
msgid "Start Message Body"
msgstr ""
@@ -6352,11 +6263,11 @@ msgstr ""
msgid "Success"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:620
+#: client/src/notifications/notificationTemplates.form.js:592
msgid "Success Message"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:631
+#: client/src/notifications/notificationTemplates.form.js:603
msgid "Success Message Body"
msgstr ""
@@ -6498,32 +6409,22 @@ msgstr ""
msgid "TOTAL NODES"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:250
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:262
-msgid "Tag None:"
-msgstr ""
-
#: client/features/templates/templates.strings.js:55
#: client/src/templates/job_templates/job-template.form.js:212
msgid "Tags are useful when you have a large playbook, and you want to run a specific part of a play or task. Use commas to separate multiple tags. Refer to Ansible Tower documentation for details on the usage of tags."
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:330
+#: client/src/notifications/notificationTemplates.form.js:314
msgid "Tags for the Annotation"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:329
+#: client/src/notifications/notificationTemplates.form.js:313
msgid "Tags for the Annotation (optional)"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:248
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:260
-msgid "Tags:"
-msgstr ""
-
-#: client/src/notifications/notificationTemplates.form.js:392
-#: client/src/notifications/notificationTemplates.form.js:442
-#: client/src/notifications/notificationTemplates.form.js:481
+#: client/src/notifications/notificationTemplates.form.js:364
+#: client/src/notifications/notificationTemplates.form.js:414
+#: client/src/notifications/notificationTemplates.form.js:453
msgid "Target URL"
msgstr ""
@@ -6535,7 +6436,7 @@ msgstr ""
#: client/src/credentials/credentials.form.js:467
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:136
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:133
-#: client/src/organizations/organizations.form.js:171
+#: client/src/organizations/organizations.form.js:180
#: client/src/projects/projects.form.js:307
#: client/src/templates/workflows.form.js:317
msgid "Team Roles"
@@ -6625,7 +6526,7 @@ msgstr ""
msgid "The Project selected has a status of"
msgstr ""
-#: client/src/projects/edit/projects-edit.controller.js:331
+#: client/src/projects/edit/projects-edit.controller.js:339
msgid "The SCM update process is running."
msgstr ""
@@ -6653,7 +6554,7 @@ msgstr ""
msgid "The answer is shorter than the minimium length. Please make the answer longer."
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:287
+#: client/src/notifications/notificationTemplates.form.js:271
msgid "The base URL of the Grafana server - the /api/annotations endpoint will be added automatically to the base Grafana URL."
msgstr ""
@@ -6732,7 +6633,7 @@ msgstr ""
msgid "The maximum length you entered is not a valid number. Please enter a whole number."
msgstr ""
-#: client/src/organizations/organizations.form.js:69
+#: client/src/organizations/organizations.form.js:78
msgid "The maximum number of hosts allowed to be managed by this organization. Value defaults to 0 which means no limit. Refer to the Ansible documentation for more details."
msgstr ""
@@ -6867,6 +6768,10 @@ msgstr ""
msgid "This feature is currently in tech preview and is subject to change in a future release. Click here for documentation."
msgstr ""
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:328
+msgid "This field is ignored unless an Enabled Variable is set. If the enabled variable matches this value, the host will be enabled on import."
+msgstr ""
+
#: client/src/inventories-hosts/inventories/related/groups/list/groups-list.partial.html:25
msgid "This group contains at least one group or host"
msgstr ""
@@ -6953,7 +6858,7 @@ msgstr ""
msgid "Time in seconds to consider a project to be current. During job runs and callbacks the task system will evaluate the timestamp of the latest project update. If it is older than Cache Timeout, it is not considered current, and a new project update will be performed."
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:405
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:395
msgid "Time in seconds to consider an inventory sync to be current. During job runs and callbacks the task system will evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, and a new inventory sync will be performed."
msgstr ""
@@ -7043,8 +6948,8 @@ msgstr ""
msgid "UNLINK"
msgstr ""
-#: client/src/projects/add/projects-add.controller.js:182
-#: client/src/projects/edit/projects-edit.controller.js:303
+#: client/src/projects/add/projects-add.controller.js:190
+#: client/src/projects/edit/projects-edit.controller.js:311
msgid "URL popover text"
msgstr ""
@@ -7163,7 +7068,7 @@ msgstr ""
msgid "Update Not Found"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:344
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:334
msgid "Update Options"
msgstr ""
@@ -7181,7 +7086,7 @@ msgstr ""
msgid "Update failed. Click for details"
msgstr ""
-#: client/src/projects/edit/projects-edit.controller.js:331
+#: client/src/projects/edit/projects-edit.controller.js:339
msgid "Update in Progress"
msgstr ""
@@ -7190,13 +7095,13 @@ msgstr ""
msgid "Update missing. Click for details"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:372
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:377
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:362
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:367
msgid "Update on Launch"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:383
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:389
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:373
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:379
msgid "Update on Project Update"
msgstr ""
@@ -7244,7 +7149,7 @@ msgstr ""
msgid "Use TLS"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:586
+#: client/src/notifications/notificationTemplates.form.js:558
msgid "Use custom messages to change the content of notifications sent when a job starts, succeeds, or fails. Use curly braces to access information about the job: {{ job_friendly_name }}, {{ url }}, or attributes of the job such as {{ job.status }}. You may apply a number of possible variables in the message. Refer to the Ansible Tower documentation for more details."
msgstr ""
@@ -7261,8 +7166,8 @@ msgstr ""
#: client/src/credentials/credentials.form.js:456
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:125
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:122
-#: client/src/organizations/organizations.form.js:119
-#: client/src/organizations/organizations.form.js:160
+#: client/src/organizations/organizations.form.js:128
+#: client/src/organizations/organizations.form.js:169
#: client/src/projects/projects.form.js:296
#: client/src/teams/teams.form.js:96
#: client/src/templates/workflows.form.js:306
@@ -7285,8 +7190,8 @@ msgstr ""
#: client/src/credentials/factories/kind-change.factory.js:40
#: client/src/credentials/factories/kind-change.factory.js:73
#: client/src/credentials/factories/kind-change.factory.js:94
-#: client/src/notifications/notificationTemplates.form.js:453
-#: client/src/notifications/notificationTemplates.form.js:492
+#: client/src/notifications/notificationTemplates.form.js:425
+#: client/src/notifications/notificationTemplates.form.js:464
#: client/src/notifications/notificationTemplates.form.js:64
#: client/src/users/users.form.js:59
#: client/src/users/users.list.js:29
@@ -7308,7 +7213,7 @@ msgstr ""
#: client/lib/components/components.strings.js:80
#: client/src/access/add-rbac-resource/rbac-resource.partial.html:35
#: client/src/activity-stream/streamDropdownNav/stream-dropdown-nav.directive.js:38
-#: client/src/organizations/organizations.form.js:101
+#: client/src/organizations/organizations.form.js:110
#: client/src/teams/teams.form.js:78
msgid "Users"
msgstr ""
@@ -7346,11 +7251,6 @@ msgstr ""
msgid "VIEW PER PAGE"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:249
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:261
-msgid "VPC ID:"
-msgstr ""
-
#: client/src/license/license.partial.html:10
msgid "Valid License"
msgstr ""
@@ -7379,8 +7279,8 @@ msgstr ""
#: client/features/templates/templates.strings.js:60
#: client/src/inventories-hosts/inventories/adhoc/adhoc.form.js:82
#: client/src/inventories-hosts/inventories/adhoc/adhoc.form.js:91
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:330
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:337
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:290
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:297
#: client/src/templates/job_templates/job-template.form.js:189
#: client/src/templates/job_templates/job-template.form.js:196
msgid "Verbosity"
@@ -7421,10 +7321,10 @@ msgstr ""
msgid "View Insights Data"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:201
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:225
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:249
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:324
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:161
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:185
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:209
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:284
msgid "View JSON examples at"
msgstr ""
@@ -7458,10 +7358,10 @@ msgstr ""
msgid "View Survey"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:202
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:226
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:250
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:325
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:162
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:186
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:210
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:285
msgid "View YAML examples at"
msgstr ""
@@ -7537,11 +7437,6 @@ msgstr ""
msgid "View template"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:261
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:274
-msgid "View the"
-msgstr ""
-
#: client/features/output/output.strings.js:22
#: client/lib/components/components.strings.js:63
msgid "View the Credential"
@@ -7689,11 +7584,11 @@ msgstr ""
msgid "Welcome to Ansible {{BRAND_NAME}}! Please sign in."
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:365
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:355
msgid "When not checked, a merge will be performed, combining local variables with those found on the external source."
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:354
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:344
msgid "When not checked, local child hosts and groups not found on the external source will remain untouched by the inventory update process."
msgstr ""
@@ -7710,19 +7605,19 @@ msgstr ""
msgid "Workflow"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:666
+#: client/src/notifications/notificationTemplates.form.js:638
msgid "Workflow Approved Message"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:677
+#: client/src/notifications/notificationTemplates.form.js:649
msgid "Workflow Approved Message Body"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:689
+#: client/src/notifications/notificationTemplates.form.js:661
msgid "Workflow Denied Message"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:700
+#: client/src/notifications/notificationTemplates.form.js:672
msgid "Workflow Denied Message Body"
msgstr ""
@@ -7738,11 +7633,11 @@ msgstr ""
msgid "Workflow Job Templates"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:712
+#: client/src/notifications/notificationTemplates.form.js:684
msgid "Workflow Pending Approval Message"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:723
+#: client/src/notifications/notificationTemplates.form.js:695
msgid "Workflow Pending Approval Message Body"
msgstr ""
@@ -7757,11 +7652,11 @@ msgstr ""
msgid "Workflow Templates"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:735
+#: client/src/notifications/notificationTemplates.form.js:707
msgid "Workflow Timed Out Message"
msgstr ""
-#: client/src/notifications/notificationTemplates.form.js:746
+#: client/src/notifications/notificationTemplates.form.js:718
msgid "Workflow Timed Out Message Body"
msgstr ""
@@ -7779,10 +7674,10 @@ msgstr ""
msgid "YAML"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:199
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:223
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:247
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:322
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:159
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:183
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:207
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:282
msgid "YAML:"
msgstr ""
@@ -7913,11 +7808,6 @@ msgstr ""
msgid "failed"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:262
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:275
-msgid "for a complete list of supported filters."
-msgstr ""
-
#: client/src/inventories-hosts/inventories/related/hosts/related-groups-labels/relatedGroupsLabelsList.directive.js:82
msgid "from the"
msgstr ""
@@ -7969,11 +7859,6 @@ msgstr ""
msgid "of"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:254
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:267
-msgid "of the filters match."
-msgstr ""
-
#: client/src/scheduler/scheduler.strings.js:34
msgid "on"
msgstr ""
@@ -8033,11 +7918,6 @@ msgstr ""
msgid "successful"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:259
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:272
-msgid "test"
-msgstr ""
-
#: client/src/activity-stream/factories/build-description.factory.js:136
msgid "timed out"
msgstr ""
@@ -8048,10 +7928,6 @@ msgstr ""
msgid "to"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:138
-msgid "to include all regions. Only Hosts associated with the selected regions will be updated."
-msgstr ""
-
#: client/src/inventories-hosts/inventories/related/sources/factories/get-sync-status-msg.factory.js:17
msgid "to start it now."
msgstr ""
@@ -8076,15 +7952,27 @@ msgstr ""
msgid "v3 multi-domain%s - your domain name"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:318
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:278
msgid "view azure_rm.ini in the Ansible community.general github repo."
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:219
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:244
+msgid "view cloudforms.ini in the Ansible Collections github repo."
+msgstr ""
+
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:179
msgid "view ec2.ini in the community.aws repo."
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:243
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:261
+msgid "view foreman.ini in the Ansible Collections github repo."
+msgstr ""
+
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:227
+msgid "view openstack.yml in the Openstack github repo."
+msgstr ""
+
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:203
msgid "view vmware_inventory.ini in the vmware community repo."
msgstr ""
@@ -8092,16 +7980,6 @@ msgstr ""
msgid "waiting"
msgstr ""
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:254
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:267
-msgid "when"
-msgstr ""
-
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:240
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:252
-msgid "will create group names similar to the following examples based on the options selected:"
-msgstr ""
-
#: client/index.template.ejs:158
msgid "working..."
msgstr ""
diff --git a/awx/ui/po/ja.po b/awx/ui/po/ja.po
index e292156170..617c5c66ca 100644
--- a/awx/ui/po/ja.po
+++ b/awx/ui/po/ja.po
@@ -31,7 +31,7 @@ msgstr "(最初の 10 件に制限)"
msgid "(defaults to %s)"
msgstr "(%s にデフォルト設定)"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:396
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:386
msgid "(seconds)"
msgstr "(秒)"
@@ -218,16 +218,11 @@ msgstr "すべてのアクティビティー"
msgid "ALL GROUPS"
msgstr "すべてのグループ"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:254
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:267
-msgid "ANY"
-msgstr "任意"
-
#: client/src/credentials/credentials.form.js:198
msgid "API Key"
msgstr "API キー"
-#: client/src/notifications/notificationTemplates.form.js:263
+#: client/src/notifications/notificationTemplates.form.js:247
msgid "API Service/Integration Key"
msgstr "API サービス/統合キー"
@@ -235,10 +230,6 @@ msgstr "API サービス/統合キー"
msgid "API Token"
msgstr "API トークン"
-#: client/src/notifications/notificationTemplates.form.js:348
-msgid "API URL"
-msgstr "API URL"
-
#: client/features/users/tokens/tokens.strings.js:40
msgid "APPLICATION"
msgstr "アプリケーション"
@@ -295,11 +286,11 @@ msgstr "アクセスキー"
msgid "Access Token Expiration"
msgstr "アクセストークンの有効期限"
-#: client/src/notifications/notificationTemplates.form.js:241
+#: client/src/notifications/notificationTemplates.form.js:225
msgid "Account SID"
msgstr "アカウント SID"
-#: client/src/notifications/notificationTemplates.form.js:200
+#: client/src/notifications/notificationTemplates.form.js:184
msgid "Account Token"
msgstr "アカウントトークン"
@@ -328,8 +319,8 @@ msgstr "アクティビティーストリーム"
#: client/src/credentials/credentials.form.js:446
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:113
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:110
-#: client/src/organizations/organizations.form.js:108
-#: client/src/organizations/organizations.form.js:150
+#: client/src/organizations/organizations.form.js:117
+#: client/src/organizations/organizations.form.js:159
#: client/src/projects/projects.form.js:285
#: client/src/teams/teams.form.js:169
#: client/src/teams/teams.form.js:85
@@ -382,7 +373,7 @@ msgstr "ユーザーの追加"
msgid "Add Users"
msgstr "ユーザーの追加"
-#: client/src/organizations/organizations.form.js:109
+#: client/src/organizations/organizations.form.js:118
msgid "Add Users to this organization."
msgstr "ユーザーをこの組織に追加してください。"
@@ -426,7 +417,7 @@ msgstr "新規トークンの追加"
#: client/src/credentials/credentials.form.js:447
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:115
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:112
-#: client/src/organizations/organizations.form.js:151
+#: client/src/organizations/organizations.form.js:160
#: client/src/projects/projects.form.js:286
#: client/src/templates/job_templates/job-template.form.js:541
#: client/src/templates/workflows.form.js:296
@@ -453,7 +444,7 @@ msgstr "管理"
msgid "Admins"
msgstr "管理者"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:386
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:376
msgid "After every project update where the SCM revision changes, refresh the inventory from the selected source before executing job tasks. This is intended for static content, like the Ansible inventory .ini file format."
msgstr "SCM リビジョンが変更されるプロジェクトの毎回の更新後に、選択されたソースのインベントリーを更新してからジョブのタスクを実行します。これは、Ansible インベントリーの .ini ファイル形式のような静的コンテンツが対象であることが意図されています。"
@@ -463,7 +454,6 @@ msgstr "SCM リビジョンが変更されるプロジェクトの毎回の更
#: client/src/home/dashboard/graphs/dashboard-graphs.partial.html:49
#: client/src/home/dashboard/graphs/dashboard-graphs.partial.html:72
#: client/src/home/dashboard/graphs/dashboard-graphs.partial.html:80
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:138
msgid "All"
msgstr "すべて"
@@ -680,11 +670,6 @@ msgstr "承認"
msgid "Authorize Password"
msgstr "パスワードの承認"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:241
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:253
-msgid "Availability Zone:"
-msgstr "アベイラビリティーゾーン"
-
#: client/src/configuration/forms/auth-form/configuration-auth.controller.js:91
msgid "Azure AD"
msgstr "Azure AD"
@@ -742,12 +727,13 @@ msgstr "デフォルトでは、Tower は Tower の使用状況に関する解
#: client/src/inventories-hosts/shared/associate-groups/associate-groups.partial.html:16
#: client/src/inventories-hosts/shared/associate-hosts/associate-hosts.partial.html:16
#: client/src/license/license.partial.html:259
+#: client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html:17
#: client/src/partials/survey-maker-modal.html:17
#: client/src/partials/survey-maker-modal.html:82
#: client/src/shared/instance-groups-multiselect/instance-groups-modal/instance-groups-modal.partial.html:17
#: client/src/templates/job_templates/add-job-template/job-template-add.controller.js:131
#: client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js:180
-#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:68
+#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:69
#: client/src/templates/workflows/add-workflow/workflow-add.controller.js:149
#: client/src/templates/workflows/edit-workflow/workflow-edit.controller.js:188
msgid "CANCEL"
@@ -886,7 +872,7 @@ msgstr "認証情報"
msgid "CREDENTIAL TYPE"
msgstr "認証情報タイプ"
-#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:60
+#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:61
msgid "CREDENTIAL TYPE:"
msgstr "認証情報タイプ:"
@@ -908,8 +894,8 @@ msgstr "認証情報"
msgid "CREDENTIALS PERMISSIONS"
msgstr "認証情報のパーミッション"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:396
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:408
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:386
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:398
#: client/src/projects/projects.form.js:231
msgid "Cache Timeout"
msgstr "キャッシュタイムアウト"
@@ -1019,7 +1005,7 @@ msgstr "この場所を変更するには {{BRAND_NAME}} のデプロイ時に %
msgid "Changes"
msgstr "変更"
-#: client/src/notifications/notificationTemplates.form.js:460
+#: client/src/notifications/notificationTemplates.form.js:432
msgid "Channel"
msgstr "チャネル"
@@ -1060,7 +1046,7 @@ msgstr "回答タイプの選択"
msgid "Choose an answer type or format you want as the prompt for the user. Refer to the Ansible Tower Documentation for more additional information about each option."
msgstr "ユーザーのプロンプトが表示される際に、必要な回答タイプを選択します。それぞれのオプションの詳細については、Ansible Tower ドキュメントを参照してください。"
-#: client/src/notifications/notificationTemplates.form.js:560
+#: client/src/notifications/notificationTemplates.form.js:532
msgid "Choose an email option"
msgstr "メールオプションの選択"
@@ -1113,10 +1099,6 @@ msgstr "行をクリックしてこれを選択し、終了したら「終了」
msgid "Click on a row to select it, and click Finished when done. Use the %s button to create a new job template."
msgstr "行をクリックしてこれを選択し、終了したら「終了」をクリックします。%s ボタンをクリックして新規ジョブテンプレートを作成します。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:137
-msgid "Click on the regions field to see a list of regions for your cloud provider. You can select multiple regions, or choose"
-msgstr "リージョンフィールドをクリックして、クラウドプロバイダーの一覧を表示します。複数のリージョンを選択したり、以下を選択したりできます。"
-
#: client/src/organizations/linkout/controllers/organizations-projects.controller.js:277
msgid "Click the"
msgstr "次をクリックしてください:"
@@ -1137,7 +1119,7 @@ msgstr "クリックしてリンクを表示します"
msgid "Client ID"
msgstr "クライアント ID"
-#: client/src/notifications/notificationTemplates.form.js:274
+#: client/src/notifications/notificationTemplates.form.js:258
msgid "Client Identifier"
msgstr "クライアント識別子"
@@ -1149,6 +1131,7 @@ msgstr "クライアントシークレット"
#: client/src/inventories-hosts/inventories/insights/insights.partial.html:92
#: client/src/management-jobs/scheduler/schedulerForm.partial.html:618
#: client/src/management-jobs/scheduler/schedulerForm.partial.html:7
+#: client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html:8
#: client/src/organizations/linkout/addUsers/addUsers.partial.html:11
#: client/src/partials/survey-maker-modal.html:28
#: client/src/partials/survey-maker-modal.html:7
@@ -1241,6 +1224,10 @@ msgstr "コンテナーグループ"
msgid "Container Groups Help"
msgstr "コンテナーグループのヘルプ"
+#: client/src/login/authenticationServices/timer.factory.js:136
+msgid "Continue"
+msgstr "続行"
+
#: client/lib/components/components.strings.js:130
msgid "Continue workflow job?"
msgstr "ワークフロージョブを続行しますか?"
@@ -1250,7 +1237,7 @@ msgstr "ワークフロージョブを続行しますか?"
msgid "Control the level of output ansible will produce as the playbook executes."
msgstr "Playbook の実行時に Ansible が生成する出力のレベルを制御します。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:336
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:296
msgid "Control the level of output ansible will produce for inventory source update jobs."
msgstr "インベントリーソースの更新ジョブ用に Ansible が生成する出力のレベルを制御します。"
@@ -1406,11 +1393,13 @@ msgstr "作成日 (降順)"
#: client/src/projects/add/projects-add.controller.js:140
#: client/src/projects/add/projects-add.controller.js:153
#: client/src/projects/add/projects-add.controller.js:162
-#: client/src/projects/add/projects-add.controller.js:181
+#: client/src/projects/add/projects-add.controller.js:174
+#: client/src/projects/add/projects-add.controller.js:189
#: client/src/projects/edit/projects-edit.controller.js:263
#: client/src/projects/edit/projects-edit.controller.js:274
#: client/src/projects/edit/projects-edit.controller.js:283
-#: client/src/projects/edit/projects-edit.controller.js:302
+#: client/src/projects/edit/projects-edit.controller.js:295
+#: client/src/projects/edit/projects-edit.controller.js:310
msgid "Credential"
msgstr "認証情報"
@@ -1460,7 +1449,7 @@ msgstr "現在のイメージ:"
msgid "Currently following output as it arrives. Click to unfollow"
msgstr "現在、受信時の出力をフォローしています。クリックしてフォローを解除します"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:170
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:130
msgid "Custom Inventory Script"
msgstr "カスタムインベントリースクリプト"
@@ -1477,7 +1466,7 @@ msgstr "カスタムスクリプト"
msgid "Customize Pod Spec"
msgstr "Pod 仕様のカスタマイズ"
-#: client/src/notifications/notificationTemplates.form.js:577
+#: client/src/notifications/notificationTemplates.form.js:549
msgid "Customize messages…"
msgstr "メッセージのカスタマイズ…"
@@ -1496,7 +1485,7 @@ msgstr "ダッシュボード"
#: client/src/inventories-hosts/inventories/related/sources/list/sources-list.partial.html:24
#: client/src/inventory-scripts/list/list.controller.js:130
#: client/src/notifications/notification-templates-list/list.controller.js:235
-#: client/src/organizations/edit/organizations-edit.controller.js:164
+#: client/src/organizations/edit/organizations-edit.controller.js:180
#: client/src/organizations/linkout/controllers/organizations-admins.controller.js:69
#: client/src/organizations/linkout/controllers/organizations-users.controller.js:68
#: client/src/organizations/list/organizations-list.controller.js:202
@@ -1591,7 +1580,7 @@ msgstr "システムレベルの機能および関数の定義"
#: client/src/inventory-scripts/list/list.controller.js:126
#: client/src/notifications/notification-templates-list/list.controller.js:231
#: client/src/notifications/notificationTemplates.list.js:105
-#: client/src/organizations/edit/organizations-edit.controller.js:161
+#: client/src/organizations/edit/organizations-edit.controller.js:177
#: client/src/organizations/linkout/controllers/organizations-admins.controller.js:66
#: client/src/organizations/linkout/controllers/organizations-users.controller.js:65
#: client/src/organizations/list/organizations-list.controller.js:198
@@ -1731,11 +1720,6 @@ msgstr "この {{ resourceType }} を削除すると、以下のリソースが
msgid "Depending on the size of the repository this may significantly increase the amount of time required to complete an update."
msgstr "リポジトリーのサイズにより、更新の完了までに必要な時間が大幅に長くなる可能性があります。"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:261
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:274
-msgid "Describe Instances documentation"
-msgstr "インスタンスの概要ドキュメント"
-
#: client/features/applications/add-applications.controller.js:36
#: client/features/templates/templates.strings.js:17
#: client/features/users/tokens/users-tokens-add.controller.js:26
@@ -1767,18 +1751,16 @@ msgstr "説明"
#: client/src/notifications/notificationTemplates.form.js:156
#: client/src/notifications/notificationTemplates.form.js:160
-#: client/src/notifications/notificationTemplates.form.js:172
-#: client/src/notifications/notificationTemplates.form.js:176
msgid "Destination Channels"
msgstr "送信先チャネル"
-#: client/src/notifications/notificationTemplates.form.js:535
-#: client/src/notifications/notificationTemplates.form.js:539
+#: client/src/notifications/notificationTemplates.form.js:507
+#: client/src/notifications/notificationTemplates.form.js:511
msgid "Destination Channels or Users"
msgstr "送信先チャネルまたはユーザー"
-#: client/src/notifications/notificationTemplates.form.js:225
-#: client/src/notifications/notificationTemplates.form.js:226
+#: client/src/notifications/notificationTemplates.form.js:209
+#: client/src/notifications/notificationTemplates.form.js:210
msgid "Destination SMS Number"
msgstr "送信先 SMS 番号"
@@ -1791,10 +1773,10 @@ msgstr "送信先 SMS 番号"
msgid "Details"
msgstr "詳細"
-#: client/src/notifications/notificationTemplates.form.js:341
-#: client/src/notifications/notificationTemplates.form.js:403
-#: client/src/notifications/notificationTemplates.form.js:474
-#: client/src/notifications/notificationTemplates.form.js:506
+#: client/src/notifications/notificationTemplates.form.js:325
+#: client/src/notifications/notificationTemplates.form.js:375
+#: client/src/notifications/notificationTemplates.form.js:446
+#: client/src/notifications/notificationTemplates.form.js:478
msgid "Disable SSL Verification"
msgstr "SSL 検証の無効化"
@@ -1935,7 +1917,7 @@ msgstr "期限切れ"
msgid "EXTRA VARIABLES"
msgstr "追加の変数"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:375
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:365
msgid "Each time a job runs using this inventory, refresh the inventory from the selected source before executing job tasks."
msgstr "このインベントリーでジョブを実行する際は常に、選択されたソースのインベントリーを更新してからジョブのタスクを実行します。"
@@ -2070,8 +2052,8 @@ msgstr "経過時間"
msgid "Email"
msgstr "メール"
-#: client/src/notifications/notificationTemplates.form.js:558
-#: client/src/notifications/notificationTemplates.form.js:559
+#: client/src/notifications/notificationTemplates.form.js:530
+#: client/src/notifications/notificationTemplates.form.js:531
msgid "Email Options"
msgstr "メールオプション"
@@ -2125,6 +2107,16 @@ msgstr "このジョブテンプレートの Webhook を有効にします。"
msgid "Enable webhook for this workflow job template."
msgstr "このワークフローのジョブテンプレートの Webhook を有効にします。"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:324
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:326
+msgid "Enabled Value"
+msgstr "有効な値"
+
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:314
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:316
+msgid "Enabled Variable"
+msgstr "有効な変数"
+
#: client/src/templates/job_templates/job-template.form.js:335
msgid "Enables creation of a provisioning callback URL. Using the URL a host can contact {{BRAND_NAME}} and request a configuration update using this job template."
msgstr "プロビジョニングコールバック URL の作成を有効にします。ホストは、この URL を使用して {{BRAND_NAME}} に接続でき、このジョブテンプレートを使用して設定の更新を要求できます。"
@@ -2158,19 +2150,18 @@ msgstr "使用許諾契約書"
msgid "Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two."
msgstr "JSON または YAML 構文のいずれかを使用してインベントリー変数を入力します。ラジオボタンを使用して 2 つの間の切り替えを行います。"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:227
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:244
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:261
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:74
msgid "Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax."
msgstr "JSON または YAML 構文のいずれかを使用してインベントリー変数を入力します。ラジオボタンを使用してこれらの間で切り替えを行います。構文のサンプルについては Ansible Tower ドキュメントを参照してください。"
-#: client/src/notifications/notificationTemplates.form.js:335
+#: client/src/notifications/notificationTemplates.form.js:319
msgid "Enter one Annotation Tag per line, without commas."
msgstr "各行に、コンマなしでアノテーションタグを 1 つ入力してください。"
-#: client/src/notifications/notificationTemplates.form.js:175
-msgid "Enter one HipChat channel per line. The pound symbol (#) is not required."
-msgstr "各行に 1 つの HipChat チャンネルを入力します。シャープ記号 (#) は不要です。"
-
-#: client/src/notifications/notificationTemplates.form.js:538
+#: client/src/notifications/notificationTemplates.form.js:510
msgid "Enter one IRC channel or username per line. The pound symbol (#) for channels, and the at (@) symbol for users, are not required."
msgstr "各行に 1 つの IRC チャンネルまたはユーザー名を入力します。チャンネルのシャープ記号 (#) およびユーザーのアットマーク (@) 記号は不要です。"
@@ -2182,7 +2173,7 @@ msgstr "各行に 1 つの Slack チャンネルを入力します。チャン
msgid "Enter one email address per line to create a recipient list for this type of notification."
msgstr "各行に 1 つのメールアドレスを入力し、この通知タイプの受信者リストを作成します。"
-#: client/src/notifications/notificationTemplates.form.js:229
+#: client/src/notifications/notificationTemplates.form.js:213
msgid "Enter one phone number per line to specify where to route SMS messages."
msgstr "各行に 1 つの電話番号を入力し、SMS メッセージのルート先を指定します。"
@@ -2201,14 +2192,14 @@ msgstr "Red Hat Satellite 6 Server に対応する %sURL を入力します (%s
msgid "Enter the hostname or IP address which corresponds to your VMware vCenter."
msgstr "VMware vCenter に対応するホスト名または IP アドレスを入力します。"
-#: client/src/notifications/notificationTemplates.form.js:215
+#: client/src/notifications/notificationTemplates.form.js:199
msgid "Enter the number associated with the \"Messaging Service\" in Twilio in the format +18005550199."
msgstr "Twilio の \"メッセージングサービス\" に関連付けられた番号を入力します (形式: +18005550199)。 "
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:196
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:220
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:244
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:319
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:156
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:180
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:204
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:279
msgid "Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two."
msgstr "JSON または YAML 構文のいずれかを使用して変数を入力します。ラジオボタンを使用してこれら 2 つの間の切り替えを行います。"
@@ -2216,8 +2207,8 @@ msgstr "JSON または YAML 構文のいずれかを使用して変数を入力
msgid "Environment"
msgstr "環境"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:186
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:193
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:146
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:153
msgid "Environment Variables"
msgstr "環境変数"
@@ -2233,11 +2224,11 @@ msgstr "エラーの詳細"
msgid "Error Fetching Licenses"
msgstr "ライセンスの取得エラー"
-#: client/src/notifications/notificationTemplates.form.js:643
+#: client/src/notifications/notificationTemplates.form.js:615
msgid "Error Message"
msgstr "エラーメッセージ"
-#: client/src/notifications/notificationTemplates.form.js:654
+#: client/src/notifications/notificationTemplates.form.js:626
msgid "Error Message Body"
msgstr "エラーメッセージボディー"
@@ -2265,13 +2256,13 @@ msgstr "エラーメッセージボディー"
#: client/src/inventories-hosts/inventories/related/sources/list/sources-list.controller.js:153
#: client/src/job-submission/job-submission-factories/launchjob.factory.js:203
#: client/src/job-submission/job-submission-factories/launchjob.factory.js:222
-#: client/src/login/loginModal/loginModal.controller.js:143
+#: client/src/login/loginModal/loginModal.controller.js:144
#: client/src/management-jobs/card/card.controller.js:122
#: client/src/management-jobs/card/card.controller.js:28
#: client/src/management-jobs/card/card.controller.js:58
-#: client/src/organizations/main.js:111
-#: client/src/organizations/main.js:124
-#: client/src/organizations/main.js:139
+#: client/src/organizations/main.js:155
+#: client/src/organizations/main.js:168
+#: client/src/organizations/main.js:183
#: client/src/projects/add/projects-add.controller.js:120
#: client/src/projects/edit/projects-edit.controller.js:154
#: client/src/projects/edit/projects-edit.controller.js:220
@@ -2334,6 +2325,11 @@ msgstr "GIT SCM のサンプル URL には以下が含まれます:"
msgid "Example URLs for Mercurial SCM include:"
msgstr "Mercurial SCM のサンプル URL には以下が含まれます:"
+#: client/src/projects/add/projects-add.controller.js:175
+#: client/src/projects/edit/projects-edit.controller.js:296
+msgid "Example URLs for Remote Archive SCM include:"
+msgstr "リモートアーカイブ SCM のサンプル URL には以下が含まれます:"
+
#: client/src/projects/add/projects-add.controller.js:154
#: client/src/projects/edit/projects-edit.controller.js:275
msgid "Example URLs for Subversion SCM include:"
@@ -2524,7 +2520,7 @@ msgstr "ダッシュボードの新規ジョブを取得できませんでした
msgid "Failed to get new templates for dashboard:"
msgstr "ダッシュボードの新規テンプレートを取得できませんでした:"
-#: client/src/organizations/main.js:140
+#: client/src/organizations/main.js:184
msgid "Failed to get organizations for which this user is a notification admin. GET returned"
msgstr "このユーザーが通知管理者の組織を取得できませんでした。GET で以下が返されました"
@@ -2564,7 +2560,7 @@ msgid "Failed to get workflow job template. GET returned status:"
msgstr "ワークフロージョブテンプレートの取得に失敗しました。GET で返されたステータス:"
#: client/src/app.js:229
-#: client/src/login/loginModal/loginModal.controller.js:144
+#: client/src/login/loginModal/loginModal.controller.js:145
msgid "Failed to get workflow jobs pending approval. GET returned status:"
msgstr "ワークフロージョブの保留中の承認取得に失敗しました。GET で返されたステータス:"
@@ -2606,11 +2602,11 @@ msgstr "検索結果の更新に失敗しました。"
msgid "Failed updating job %s with variables. POST returned: %d"
msgstr "変数でジョブ %s を更新できませんでした。POST で返されたステータス: %d"
-#: client/src/organizations/main.js:112
+#: client/src/organizations/main.js:156
msgid "Failed while checking to see if user is a notification administrator of this organization. GET returned"
msgstr "ユーザーがこの組織の通知管理者かどうかを確認中に失敗しました。GET で以下が返されました"
-#: client/src/organizations/main.js:125
+#: client/src/organizations/main.js:169
msgid "Failed while checking to see if user is an administrator of this organization. GET returned"
msgstr "ユーザーがこの組織の管理者かどうかを確認中に失敗しました。GET で以下が返されました"
@@ -2654,7 +2650,7 @@ msgstr "名"
msgid "First Run"
msgstr "初回実行日時"
-#: client/src/organizations/organizations.form.js:124
+#: client/src/organizations/organizations.form.js:133
msgid "First name"
msgstr "名"
@@ -2729,6 +2725,11 @@ msgstr "通知 へ移動:"
msgid "GROUPS"
msgstr "グループ"
+#: client/src/organizations/organizations.form.js:59
+#: client/src/organizations/organizations.form.js:62
+msgid "Galaxy Credentials"
+msgstr "Galaxy 認証情報"
+
#: client/src/shared/form-generator.js:801
msgid "Generate field"
msgstr "フィールドの生成"
@@ -2803,11 +2804,11 @@ msgstr "リストの前のページに移動"
msgid "Google OAuth2"
msgstr "Google OAuth2"
-#: client/src/notifications/notificationTemplates.form.js:300
+#: client/src/notifications/notificationTemplates.form.js:284
msgid "Grafana API Key"
msgstr "Grafana API キー"
-#: client/src/notifications/notificationTemplates.form.js:285
+#: client/src/notifications/notificationTemplates.form.js:269
msgid "Grafana URL"
msgstr "Grafana URL"
@@ -2866,13 +2867,13 @@ msgstr "ヒント: 以下のフィールドに非公開ファイルをドラッ
msgid "HOSTS"
msgstr "ホスト"
-#: client/src/notifications/notificationTemplates.form.js:410
-#: client/src/notifications/notificationTemplates.form.js:411
+#: client/src/notifications/notificationTemplates.form.js:382
+#: client/src/notifications/notificationTemplates.form.js:383
msgid "HTTP Headers"
msgstr "HTTP ヘッダー"
-#: client/src/notifications/notificationTemplates.form.js:427
-#: client/src/notifications/notificationTemplates.form.js:428
+#: client/src/notifications/notificationTemplates.form.js:399
+#: client/src/notifications/notificationTemplates.form.js:400
msgid "HTTP Method"
msgstr "HTTP メソッド"
@@ -2913,6 +2914,11 @@ msgstr "ホスト設定キー"
msgid "Host Enabled"
msgstr "有効なホスト"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:304
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:306
+msgid "Host Filter"
+msgstr "ホストフィルター"
+
#: client/features/output/output.strings.js:66
msgid "Host Limit Error"
msgstr "ホスト制限エラー"
@@ -2974,20 +2980,15 @@ msgstr "残りのホスト"
msgid "Hosts Used"
msgstr "使用されたホスト"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:254
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:267
-msgid "Hosts are imported to"
-msgstr "ホストのインポート先"
-
#: client/features/output/output.strings.js:129
msgid "ID"
msgstr "ID"
-#: client/src/notifications/notificationTemplates.form.js:313
+#: client/src/notifications/notificationTemplates.form.js:297
msgid "ID of the Dashboard (optional)"
msgstr "ダッシュボード ID (オプション)"
-#: client/src/notifications/notificationTemplates.form.js:321
+#: client/src/notifications/notificationTemplates.form.js:305
msgid "ID of the Panel (optional)"
msgstr "パネル ID (オプション)"
@@ -3036,11 +3037,11 @@ msgstr "インベントリースクリプト"
msgid "INVENTORY SCRIPTS"
msgstr "インベントリースクリプト"
-#: client/src/notifications/notificationTemplates.form.js:524
+#: client/src/notifications/notificationTemplates.form.js:496
msgid "IRC Nick"
msgstr "IRC ニック"
-#: client/src/notifications/notificationTemplates.form.js:513
+#: client/src/notifications/notificationTemplates.form.js:485
msgid "IRC Server Address"
msgstr "IRC サーバーアドレス"
@@ -3064,8 +3065,8 @@ msgstr "問題: {{report.rule.description}}"
msgid "ITEMS"
msgstr "項目"
-#: client/src/notifications/notificationTemplates.form.js:467
-#: client/src/notifications/notificationTemplates.form.js:499
+#: client/src/notifications/notificationTemplates.form.js:439
+#: client/src/notifications/notificationTemplates.form.js:471
msgid "Icon URL"
msgstr "アイコン URL"
@@ -3073,16 +3074,11 @@ msgstr "アイコン URL"
msgid "Idle Session"
msgstr "アイドル状態のセッション"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:251
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:263
-msgid "If blank, all groups above are created except"
-msgstr "空白の場合には、以下を除く上のすべてのグループが作成されます。"
-
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:364
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:354
msgid "If checked, all variables for child groups and hosts will be removed and replaced by those found on the external source."
msgstr "チェックが付けられている場合、子グループおよびホストのすべての変数が削除され、外部ソースにあるものによって置き換えられます。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:353
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:343
msgid "If checked, any hosts and groups that were previously present on the external source but are now removed will be removed from the Tower inventory. Hosts and groups that were not managed by the inventory source will be promoted to the next manually created group or if there is no manually created group to promote them into, they will be left in the \"all\" default group for the inventory."
msgstr "チェックが付けられている場合、以前は外部ソースにあり、現在は削除されているホストおよびグループが Tower インベントリーから削除されます。インベントリーソースで管理されていなかったホストおよびグループは次に手動で作成されるグループにプロモートされるか、またはプロモート先となる手動で作成されたグループがない場合は、それらはインベントリーの「すべて」のデフォルトグループに残ります。"
@@ -3119,11 +3115,6 @@ msgstr "組織が指定されない場合、認証情報はそれを作成する
msgid "If you are ready to upgrade, please contact us by clicking the button below"
msgstr "アップグレードの準備ができましたら、以下のボタンをクリックしてお問い合わせください。"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:242
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:254
-msgid "Image ID:"
-msgstr "イメージ ID:"
-
#: client/src/inventories-hosts/hosts/host.form.js:34
#: client/src/inventories-hosts/hosts/host.list.js:35
#: client/src/inventories-hosts/inventories/related/groups/related/nested-hosts/group-nested-hosts.form.js:33
@@ -3158,11 +3149,6 @@ msgstr "Insights"
msgid "Insights Credential"
msgstr "Insights 認証情報"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:144
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:147
-msgid "Instance Filters"
-msgstr "インスタンスフィルター"
-
#: client/features/output/output.strings.js:67
#: client/src/instance-groups/instance-groups.strings.js:43
msgid "Instance Group"
@@ -3188,21 +3174,6 @@ msgstr "インスタンスグループ"
msgid "Instance Groups Help"
msgstr "インスタンスグループのヘルプ"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:251
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:263
-msgid "Instance ID"
-msgstr "インスタンス ID"
-
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:243
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:255
-msgid "Instance ID:"
-msgstr "インスタンス ID:"
-
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:244
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:256
-msgid "Instance Type:"
-msgstr "インスタンスタイプ:"
-
#: client/lib/components/components.strings.js:85
#: client/src/instance-groups/instance-groups.strings.js:20
msgid "Instances"
@@ -3359,10 +3330,10 @@ msgstr "ジョブ"
msgid "JSON"
msgstr "JSON"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:197
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:221
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:245
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:320
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:157
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:181
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:205
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:280
msgid "JSON:"
msgstr "JSON:"
@@ -3441,11 +3412,6 @@ msgstr "キー"
msgid "Key"
msgstr "キー"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:245
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:257
-msgid "Key Name:"
-msgstr "キー名:"
-
#: client/src/credential-types/credential-types.list.js:31
#: client/src/credentials/credentials.list.js:33
msgid "Kind"
@@ -3551,7 +3517,7 @@ msgstr "最終使用日時 (降順)"
msgid "Last logged in:"
msgstr "最終ログイン:"
-#: client/src/organizations/organizations.form.js:128
+#: client/src/organizations/organizations.form.js:137
msgid "Last name"
msgstr "姓"
@@ -3630,21 +3596,6 @@ msgstr "ライセンスタイプ"
msgid "Limit"
msgstr "制限"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:255
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:268
-msgid "Limit to hosts having a tag:"
-msgstr "タグを持つホストに制限:"
-
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:257
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:270
-msgid "Limit to hosts using either key pair:"
-msgstr "いずれかのキーペアを使用するホストに制限:"
-
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:259
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:272
-msgid "Limit to hosts where the Name tag begins with"
-msgstr "名前タグの開始点となるホストに制限"
-
#: client/src/scheduler/scheduler.strings.js:51
msgid "Limited to first 10"
msgstr "最初の 10 件に制限"
@@ -3760,8 +3711,8 @@ msgstr "手動プロジェクトに SCM 更新は不要です"
msgid "Max 512 characters per label."
msgstr "最大 512 文字 (ラベルあたり)"
-#: client/src/organizations/organizations.form.js:59
-#: client/src/organizations/organizations.form.js:66
+#: client/src/organizations/organizations.form.js:68
+#: client/src/organizations/organizations.form.js:75
msgid "Max Hosts"
msgstr "最大ホスト数"
@@ -3947,7 +3898,7 @@ msgstr "何も選択されていません"
msgid "NOTE: This field assumes the remote name is \"origin\"."
msgstr "注: このフィールドは、リモート名が \"origin\" であることが前提です。"
-#: client/src/login/loginModal/loginModal.partial.html:101
+#: client/src/login/loginModal/loginModal.partial.html:102
msgid "NOTICE"
msgstr "通知"
@@ -3962,7 +3913,7 @@ msgstr "通知テンプレート"
#: client/lib/components/components.strings.js:131
#: client/src/inventories-hosts/inventories/related/sources/edit/sources-notifications.route.js:9
-#: client/src/management-jobs/notifications/notification.route.js:46
+#: client/src/management-jobs/notifications/notification.route.js:59
#: client/src/notifications/main.js:44
#: client/src/notifications/main.js:95
#: client/src/notifications/notification-templates-list/add-notifications-action.partial.html:2
@@ -4239,10 +4190,10 @@ msgstr "インベントリーの同期に設定されていません。"
msgid "Note that only hosts directly in this group can be disassociated. Hosts in sub-groups must be disassociated directly from the sub-group level that they belong."
msgstr "このグループに直接含まれるホストのみの関連付けを解除できることに注意してください。サブグループのホストの関連付けの解除については、それらのホストが属するサブグループのレベルで直接実行する必要があります。"
-#: client/src/notifications/notificationTemplates.form.js:371
-#: client/src/notifications/notificationTemplates.form.js:372
-#: client/src/notifications/notificationTemplates.form.js:568
-#: client/src/notifications/notificationTemplates.form.js:569
+#: client/src/notifications/notificationTemplates.form.js:343
+#: client/src/notifications/notificationTemplates.form.js:344
+#: client/src/notifications/notificationTemplates.form.js:540
+#: client/src/notifications/notificationTemplates.form.js:541
msgid "Notification Color"
msgstr "通知の色"
@@ -4250,7 +4201,7 @@ msgstr "通知の色"
msgid "Notification Failed."
msgstr "通知に失敗しました。"
-#: client/src/notifications/notificationTemplates.form.js:360
+#: client/src/notifications/notificationTemplates.form.js:332
msgid "Notification Label"
msgstr "通知レベル"
@@ -4268,7 +4219,7 @@ msgstr "通知がタイムアウトしました。"
msgid "Notifications"
msgstr "通知"
-#: client/src/notifications/notificationTemplates.form.js:385
+#: client/src/notifications/notificationTemplates.form.js:357
msgid "Notify Channel"
msgstr "通知チャネル"
@@ -4304,7 +4255,7 @@ msgstr "組織"
#: client/src/activity-stream/get-target-title.factory.js:29
#: client/src/organizations/list/organizations-list.partial.html:6
-#: client/src/organizations/main.js:51
+#: client/src/organizations/main.js:55
msgid "ORGANIZATIONS"
msgstr "組織"
@@ -4331,10 +4282,9 @@ msgstr "障害発生時"
msgid "On Success"
msgstr "成功時"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:156
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:161
-msgid "Only Group By"
-msgstr "グループ化のみ"
+#: client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials.partial.html:3
+msgid "Open Galaxy credentials"
+msgstr "Galaxy 認証情報を開く"
#: client/src/templates/job_templates/multi-credential/multi-credential.partial.html:4
msgid "Open credential lookup"
@@ -4420,49 +4370,38 @@ msgstr "他のプロンプト"
msgid "Others (Cloud Providers)"
msgstr "その他 (クラウドプロバイダー)"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:316
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:276
msgid "Override variables found in azure_rm.ini and used by the inventory update script. For a detailed description of these variables"
msgstr "azure_rm.ini にあり、インベントリー更新スクリプトで使用される変数を上書きします。これらの変数の詳細な説明については、次を参照してください。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:282
-msgid ""
-"Override variables found in cloudforms.ini and used by the inventory update script. For an example variable configuration\n"
-" \n"
-" view cloudforms.ini in the Ansible Collections github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax."
-msgstr "cloudforms.ini にあり、インベントリー更新スクリプトで使用される変数を上書きします。たとえば、変数の設定\n"
-" \n"
-" は Ansible Collections github リポジトリーで cloudforms.ini を表示します。 JSON または YAML 構文のいずれかを使用してインベントリー変数を入力します。ラジオボタンを使用してこの 2 つの間の切り替えを行います。構文のサンプルについては、Ansible Tower ドキュメントを参照してください。"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:242
+msgid "Override variables found in cloudforms.ini and used by the inventory update script. For an example variable configuration"
+msgstr "cloudforms.ini にあり、インベントリー更新スクリプトが使用する変数を上書きします。変数の設定例については次を参照してください。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:217
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:177
msgid "Override variables found in ec2.ini and used by the inventory update script. For a detailed description of these variables"
msgstr "ec2.ini にあり、インベントリー更新スクリプトで使用される変数を上書きします。これらの変数の詳細な説明については、次を参照してください。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:299
-msgid ""
-"Override variables found in foreman.ini and used by the inventory update script. For an example variable configuration\n"
-" \n"
-" view foreman.ini in the Ansible Collections github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax."
-msgstr "foreman.ini にあり、インベントリー更新スクリプトで使用される変数を上書きします。たとえば、変数の設定 は Ansible Collections github リポジトリーで foreman.ini を表示します。 JSON または YAML 構文のいずれかを使用してインベントリー変数を入力します。ラジオボタンを使用してこの 2 つの間の切り替えを行います。構文のサンプルについては、Ansible Tower ドキュメントを参照してください。"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:259
+msgid "Override variables found in foreman.ini and used by the inventory update script. For an example variable configuration"
+msgstr "foreman.ini にあり、インベントリー更新スクリプトが使用する変数を上書きします。変数の設定例については次を参照してください。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:265
-msgid ""
-"Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration\n"
-" \n"
-" view openstack.yml in the Openstack github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax."
-msgstr "openstack.yml にあり、インベントリー更新スクリプトで使用される変数を上書きします。たとえば、変数の設定 は Openstack github リポジトリーで openstack.yml を表示します。 JSON または YAML 構文のいずれかを使用してインベントリー変数を入力します。ラジオボタンを使用して 2 つの間の切り替えを行います。構文のサンプルについては、Ansible Tower ドキュメントを参照してください。"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:225
+msgid "Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration"
+msgstr "openstack.yml にあり、インベントリー更新スクリプトが使用する変数を上書きします。変数の設定例については次を参照してください。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:241
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:201
msgid "Override variables found in vmware.ini and used by the inventory update script. For a detailed description of these variables"
msgstr "vmware.ini にあり、インベントリー更新スクリプトで使用される変数を上書きします。これらの変数の詳細な説明については、次を参照してください。"
#: client/features/output/output.strings.js:83
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:350
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:355
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:340
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:345
msgid "Overwrite"
msgstr "上書き"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:361
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:366
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:351
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:356
msgid "Overwrite Variables"
msgstr "変数の上書き"
@@ -4543,7 +4482,7 @@ msgstr "PUT"
msgid "Page"
msgstr "ページ"
-#: client/src/notifications/notificationTemplates.form.js:252
+#: client/src/notifications/notificationTemplates.form.js:236
msgid "Pagerduty subdomain"
msgstr "Pagerduty サブドメイン"
@@ -4638,7 +4577,7 @@ msgstr "パーミッションのエラー"
#: client/src/credentials/credentials.form.js:438
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:104
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:101
-#: client/src/organizations/organizations.form.js:143
+#: client/src/organizations/organizations.form.js:152
#: client/src/projects/projects.form.js:278
#: client/src/teams/teams.form.js:128
#: client/src/templates/job_templates/job-template.form.js:532
@@ -4884,14 +4823,14 @@ msgstr "Survey をこのワークフローに追加する前に保存してく
msgid "Please save before adding notifications."
msgstr "通知を追加する前に保存してください。"
-#: client/src/organizations/organizations.form.js:95
+#: client/src/organizations/organizations.form.js:104
#: client/src/teams/teams.form.js:72
msgid "Please save before adding users."
msgstr "ユーザーを追加する前に保存してください。"
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:100
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:97
-#: client/src/organizations/organizations.form.js:135
+#: client/src/organizations/organizations.form.js:144
#: client/src/projects/projects.form.js:270
#: client/src/teams/teams.form.js:124
#: client/src/templates/job_templates/job-template.form.js:525
@@ -5139,16 +5078,6 @@ msgstr "プロンプト"
msgid "Prompt on launch"
msgstr "起動プロンプト"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:253
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:266
-msgid "Provide a comma-separated list of filter expressions."
-msgstr "フィルター式のカンマ区切りリストを指定します。"
-
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:269
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:284
-msgid "Provide a comma-separated list of filter expressions. Hosts are imported when all of the filters match. Refer to Ansible Tower documentation for more detail."
-msgstr "カンマ区切りのフィルター式の一覧を提供します。ホストは、フィルターのすべてが一致する場合にインポートされます。詳細については、Ansible Tower ドキュメントを参照してください。"
-
#: client/src/inventories-hosts/hosts/host.form.js:49
#: client/src/inventories-hosts/inventories/related/groups/related/nested-hosts/group-nested-hosts.form.js:48
#: client/src/inventories-hosts/inventories/related/hosts/related-host.form.js:50
@@ -5168,15 +5097,10 @@ msgstr "ワークフローからの影響を受けるホストまたはワーク
msgid "Provide account information using Google Compute Engine JSON credentials file."
msgstr "Google Compute Engine JSON 認証情報ファイルを使用してアカウント情報を指定します。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:195
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:155
msgid "Provide environment variables to pass to the custom inventory script."
msgstr "カスタムインベントリースクリプトに渡す環境変数を指定します。"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:272
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:287
-msgid "Provide the named URL encoded name or id of the remote Tower inventory to be imported."
-msgstr "インポートされるリモート Tower インベントリーの名前付き URL のエンコードされた名前または ID を指定します。"
-
#: client/src/license/license.partial.html:128
msgid "Provide your Red Hat customer credentials and you can choose from a list of your available licenses. The credentials you use will be stored for future use in retrieving renewal or expanded licenses. You can update or remove them in SETTINGS > SYSTEM."
msgstr "Red Hat の顧客認証情報を指定して、利用可能なライセンス一覧から選択してください。使用した認証情報は、今後、ライセンスの更新や延長情報を取得する時に利用できるように保存されます。設定 > システムでこの情報は更新または削除できます。"
@@ -5266,7 +5190,7 @@ msgid "RESULTS"
msgstr "結果"
#: client/features/templates/templates.strings.js:39
-#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:50
+#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:51
msgid "REVERT"
msgstr "元に戻す"
@@ -5387,14 +5311,9 @@ msgstr "ページの更新"
msgid "Refspec"
msgstr "Refspec"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:246
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:258
-msgid "Region:"
-msgstr "リージョン:"
-
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:130
-msgid "Regions"
-msgstr "リージョン"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:308
+msgid "Regular expression where only matching host names will be imported. The filter is applied as a post-processing step after any inventory plugin filters are applied."
+msgstr "一致するホスト名のみがインポートされる正規表現。このフィルターは、インベントリープラグインフィルターが適用された後、後処理ステップとして適用されます。"
#: client/src/inventories-hosts/inventories/related/hosts/related-host.list.js:81
msgid "Related Groups"
@@ -5478,6 +5397,10 @@ msgstr "リソース"
msgid "Resources are missing from this template."
msgstr "リソースがこのテンプレートにありません。"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:318
+msgid "Retrieve the enabled state from the given dict of host variables. The enabled variable may be specified using dot notation, e.g: 'foo.bar'"
+msgstr "ホスト変数の指定された辞書から有効な状態を取得します。有効な変数は、ドット表記を使用して指定できます (例: 「foo.bar」)。"
+
#: client/lib/services/base-string.service.js:111
msgid "Return"
msgstr "戻る"
@@ -5505,7 +5428,7 @@ msgstr "戻す"
#: client/src/configuration/forms/auth-form/sub-forms/auth-radius.form.js:34
#: client/src/configuration/forms/auth-form/sub-forms/auth-saml.form.js:121
#: client/src/configuration/forms/auth-form/sub-forms/auth-tacacs.form.js:47
-#: client/src/configuration/forms/jobs-form/configuration-jobs.form.js:129
+#: client/src/configuration/forms/jobs-form/configuration-jobs.form.js:110
#: client/src/configuration/forms/system-form/sub-forms/system-activity-stream.form.js:26
#: client/src/configuration/forms/system-form/sub-forms/system-logging.form.js:74
#: client/src/configuration/forms/system-form/sub-forms/system-misc.form.js:95
@@ -5527,7 +5450,7 @@ msgstr "リビジョン #"
#: client/src/credentials/credentials.form.js:461
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:130
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:127
-#: client/src/organizations/organizations.form.js:165
+#: client/src/organizations/organizations.form.js:174
#: client/src/projects/projects.form.js:301
#: client/src/teams/teams.form.js:109
#: client/src/teams/teams.form.js:148
@@ -5561,6 +5484,7 @@ msgstr "SAML"
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory-host-filter/host-filter-modal/host-filter-modal.partial.html:17
#: client/src/inventories-hosts/shared/associate-groups/associate-groups.partial.html:17
#: client/src/inventories-hosts/shared/associate-hosts/associate-hosts.partial.html:17
+#: client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html:18
#: client/src/partials/survey-maker-modal.html:84
#: client/src/shared/instance-groups-multiselect/instance-groups-modal/instance-groups-modal.partial.html:18
msgid "SAVE"
@@ -5669,7 +5593,7 @@ msgstr "検索"
#: client/src/license/license.partial.html:260
#: client/src/templates/job_templates/add-job-template/job-template-add.controller.js:137
#: client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js:186
-#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:74
+#: client/src/templates/job_templates/multi-credential/multi-credential-modal.partial.html:75
#: client/src/templates/workflows/add-workflow/workflow-add.controller.js:155
#: client/src/templates/workflows/edit-workflow/workflow-edit.controller.js:194
msgid "SELECT"
@@ -5729,7 +5653,7 @@ msgstr "設定"
msgid "SHOW"
msgstr "表示"
-#: client/src/login/loginModal/loginModal.partial.html:109
+#: client/src/login/loginModal/loginModal.partial.html:114
msgid "SIGN IN"
msgstr "サインイン"
@@ -5767,7 +5691,7 @@ msgstr "SSH パスワード"
msgid "SSH key description"
msgstr "SSH キーの説明"
-#: client/src/notifications/notificationTemplates.form.js:551
+#: client/src/notifications/notificationTemplates.form.js:523
msgid "SSL Connection"
msgstr "SSL 接続"
@@ -5871,7 +5795,7 @@ msgstr "スケジュール名"
#: client/lib/components/components.strings.js:72
#: client/src/activity-stream/streamDropdownNav/stream-dropdown-nav.directive.js:35
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:434
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:424
#: client/src/projects/projects.form.js:321
#: client/src/templates/job_templates/job-template.form.js:578
#: client/src/templates/workflows.form.js:333
@@ -5891,11 +5815,6 @@ msgstr "検索"
msgid "Secret Key"
msgstr "シークレットキー"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:247
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:259
-msgid "Security Group:"
-msgstr "セキュリティーグループ:"
-
#: client/src/credentials/credentials.form.js:124
msgid "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."
msgstr "セキュリティートークンサービス (STS) は、AWS Identity and Access Management (IAM) ユーザーの一時的な、権限の制限された認証情報を要求できる web サービスです。"
@@ -5906,6 +5825,14 @@ msgstr "セキュリティートークンサービス (STS) は、AWS Identity a
msgid "Select"
msgstr "選択"
+#: client/src/organizations/galaxy-credentials-multiselect/galaxy-credentials-modal/galaxy-credentials-modal.partial.html:5
+msgid "Select Galaxy Credentials"
+msgstr "Galaxy 認証情報を選択します"
+
+#: client/src/organizations/organizations.form.js:61
+msgid "Select Galaxy credentials. The selection order sets the order in which Tower will download roles/collections using `ansible-galaxy`."
+msgstr "Galaxy 認証情報を選択します。選択したこの順序は、Tower が「ansible-galaxy」を使用してロール/コレクションをダウンロードする順序を設定します。"
+
#: client/src/shared/instance-groups-multiselect/instance-groups-modal/instance-groups-modal.partial.html:5
msgid "Select Instance Groups"
msgstr "インスタンスグループの選択"
@@ -6051,11 +5978,6 @@ msgstr "このジョブで実行する Playbook が含まれるプロジェク
msgid "Select types"
msgstr "タイプの選択"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:239
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:251
-msgid "Select which groups to create automatically."
-msgstr "自動作成するグループを選択します。"
-
#: client/src/license/license.partial.html:153
msgid "Selected"
msgstr "選択済み"
@@ -6223,8 +6145,8 @@ msgstr "ソース認証情報"
msgid "Source Details"
msgstr "ソース詳細"
-#: client/src/notifications/notificationTemplates.form.js:212
-#: client/src/notifications/notificationTemplates.form.js:213
+#: client/src/notifications/notificationTemplates.form.js:196
+#: client/src/notifications/notificationTemplates.form.js:197
msgid "Source Phone Number"
msgstr "発信元の電話番号"
@@ -6232,22 +6154,18 @@ msgstr "発信元の電話番号"
msgid "Source Project"
msgstr "ソースプロジェクト"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:135
-msgid "Source Regions"
-msgstr "ソースリージョン"
-
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:208
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:215
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:232
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:239
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:256
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:263
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:273
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:280
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:290
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:297
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:307
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:314
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:168
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:175
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:192
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:199
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:216
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:223
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:233
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:240
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:250
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:257
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:267
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:274
msgid "Source Variables"
msgstr "ソース変数"
@@ -6265,7 +6183,7 @@ msgstr "ソースワークフロー"
msgid "Sources"
msgstr "ソース"
-#: client/src/notifications/notificationTemplates.form.js:420
+#: client/src/notifications/notificationTemplates.form.js:392
msgid "Specify HTTP Headers in JSON format. Refer to the Ansible Tower documentation for example syntax."
msgstr "JSON 形式で HTTP ヘッダーを指定します。構文のサンプルについては Ansible Tower ドキュメントを参照してください。"
@@ -6273,11 +6191,11 @@ msgstr "JSON 形式で HTTP ヘッダーを指定します。構文のサンプ
msgid "Specify a method for %s operations. This is equivalent to specifying the %s parameter, where %s could be %s"
msgstr "%s 操作のメソッドを指定します。これは %s を指定することに相当します。%s は %s にすることができます。"
-#: client/src/notifications/notificationTemplates.form.js:574
+#: client/src/notifications/notificationTemplates.form.js:546
msgid "Specify a notification color. Acceptable colors are hex color code (example: #3af or #789abc) ."
msgstr "通知の色を指定します。使用できる色: 16 進数の色コード (例: #3af または #789abc) "
-#: client/src/notifications/notificationTemplates.form.js:375
+#: client/src/notifications/notificationTemplates.form.js:347
msgid "Specify a notification color. Acceptable colors are: yellow, green, red purple, gray or random."
msgstr "通知の色を指定します。使用できる色: 黄、緑、赤紫、灰色、またはランダム"
@@ -6285,15 +6203,10 @@ msgstr "通知の色を指定します。使用できる色: 黄、緑、赤紫
msgid "Specify a scope for the token's access"
msgstr "トークンのアクセスのスコープを指定します"
-#: client/src/notifications/notificationTemplates.form.js:432
+#: client/src/notifications/notificationTemplates.form.js:404
msgid "Specify an HTTP method for the webhook. Acceptable choices are: POST or PUT"
msgstr "Webhook の HTTP メソッドを指定します。許容できる選択肢は、POST か PUT です。"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:268
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:283
-msgid "Specify which groups to create automatically. Group names will be created similar to the options selected. If blank, all groups above are created. Refer to Ansible Tower documentation for more detail."
-msgstr "自動作成するグループを指定します。選択したオプションと同様のグループ名が作成されます。空白の場合は、上のすべてのグループが作成されます。詳細については、Ansible Tower ドキュメントを参照してください。"
-
#: client/features/output/output.strings.js:135
msgid "Standard Error"
msgstr "標準エラー"
@@ -6312,11 +6225,11 @@ msgstr "開始"
msgid "Start Date"
msgstr "開始日"
-#: client/src/notifications/notificationTemplates.form.js:597
+#: client/src/notifications/notificationTemplates.form.js:569
msgid "Start Message"
msgstr "開始メッセージ"
-#: client/src/notifications/notificationTemplates.form.js:608
+#: client/src/notifications/notificationTemplates.form.js:580
msgid "Start Message Body"
msgstr "開始メッセージのボディー"
@@ -6382,11 +6295,11 @@ msgstr "サブスクリプション ID は、ユーザー名にマップされ
msgid "Success"
msgstr "成功"
-#: client/src/notifications/notificationTemplates.form.js:620
+#: client/src/notifications/notificationTemplates.form.js:592
msgid "Success Message"
msgstr "成功メッセージ"
-#: client/src/notifications/notificationTemplates.form.js:631
+#: client/src/notifications/notificationTemplates.form.js:603
msgid "Success Message Body"
msgstr "成功メッセージボディー"
@@ -6528,32 +6441,22 @@ msgstr "トークン"
msgid "TOTAL NODES"
msgstr "ノードの合計"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:250
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:262
-msgid "Tag None:"
-msgstr "タグ None:"
-
#: client/features/templates/templates.strings.js:55
#: client/src/templates/job_templates/job-template.form.js:212
msgid "Tags are useful when you have a large playbook, and you want to run a specific part of a play or task. Use commas to separate multiple tags. Refer to Ansible Tower documentation for details on the usage of tags."
msgstr "タグは、Playbook のサイズが大きい場合にプレイまたはタスクの特定の部分を実行する必要がある場合に役立ちます。カンマを使って複数のタグを区切ります。タグの使用方法の詳細については、Ansible Tower ドキュメントを参照してください。"
-#: client/src/notifications/notificationTemplates.form.js:330
+#: client/src/notifications/notificationTemplates.form.js:314
msgid "Tags for the Annotation"
msgstr "アノテーションのタグ"
-#: client/src/notifications/notificationTemplates.form.js:329
+#: client/src/notifications/notificationTemplates.form.js:313
msgid "Tags for the Annotation (optional)"
msgstr "アノテーションのタグ (オプション)"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:248
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:260
-msgid "Tags:"
-msgstr "タグ:"
-
-#: client/src/notifications/notificationTemplates.form.js:392
-#: client/src/notifications/notificationTemplates.form.js:442
-#: client/src/notifications/notificationTemplates.form.js:481
+#: client/src/notifications/notificationTemplates.form.js:364
+#: client/src/notifications/notificationTemplates.form.js:414
+#: client/src/notifications/notificationTemplates.form.js:453
msgid "Target URL"
msgstr "ターゲット URL"
@@ -6565,7 +6468,7 @@ msgstr "タスク"
#: client/src/credentials/credentials.form.js:467
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:136
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:133
-#: client/src/organizations/organizations.form.js:171
+#: client/src/organizations/organizations.form.js:180
#: client/src/projects/projects.form.js:307
#: client/src/templates/workflows.form.js:317
msgid "Team Roles"
@@ -6655,7 +6558,7 @@ msgstr "プロジェクト ID は GCE によって割り当てられる識別情
msgid "The Project selected has a status of"
msgstr "選択されたプロジェクトのステータス"
-#: client/src/projects/edit/projects-edit.controller.js:331
+#: client/src/projects/edit/projects-edit.controller.js:339
msgid "The SCM update process is running."
msgstr "SCM 更新プロセスが実行中です。"
@@ -6683,7 +6586,7 @@ msgstr "回答が最大文字数を超えています。回答を短くしてく
msgid "The answer is shorter than the minimium length. Please make the answer longer."
msgstr "回答が最小文字数より短くなっています。回答を長くしてください。"
-#: client/src/notifications/notificationTemplates.form.js:287
+#: client/src/notifications/notificationTemplates.form.js:271
msgid "The base URL of the Grafana server - the /api/annotations endpoint will be added automatically to the base Grafana URL."
msgstr "Grafana サーバーのベース URL。/api/annotations エンドポイントは、ベース Grafana URL に自動的に追加されます。"
@@ -6762,7 +6665,7 @@ msgstr "最大長の値が小さすぎます。設定した最大長よりも大
msgid "The maximum length you entered is not a valid number. Please enter a whole number."
msgstr "入力した最大長の数字が無効です。整数を入力してください"
-#: client/src/organizations/organizations.form.js:69
+#: client/src/organizations/organizations.form.js:78
msgid "The maximum number of hosts allowed to be managed by this organization. Value defaults to 0 which means no limit. Refer to the Ansible documentation for more details."
msgstr "この組織で管理可能な最大ホスト数。デフォルト値は 0 で、管理可能な数に制限がありません。詳細は、Ansible ドキュメントを参照してください。"
@@ -6897,6 +6800,10 @@ msgstr "この認証情報タイプは現在 1 つ以上の認証情報で使用
msgid "This feature is currently in tech preview and is subject to change in a future release. Click here for documentation."
msgstr "この機能は現在テクノロジープレビュー機能となっており、今後のリリースで変更される可能性があります。こちらをクリックしてドキュメントを確認してください。"
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:328
+msgid "This field is ignored unless an Enabled Variable is set. If the enabled variable matches this value, the host will be enabled on import."
+msgstr "有効な変数が設定されていない限り、このフィールドは無視されます。有効な変数がこの値と一致すると、インポート時にこのホストが有効になります。"
+
#: client/src/inventories-hosts/inventories/related/groups/list/groups-list.partial.html:25
msgid "This group contains at least one group or host"
msgstr "このグループには、少なくとも 1 つのグループまたはホストが含まれています。"
@@ -6983,7 +6890,7 @@ msgstr "残りの時間"
msgid "Time in seconds to consider a project to be current. During job runs and callbacks the task system will evaluate the timestamp of the latest project update. If it is older than Cache Timeout, it is not considered current, and a new project update will be performed."
msgstr "プロジェクトが最新であることを判別するための時間 (秒単位) です。ジョブ実行およびコールバック時に、タスクシステムは最新のプロジェクト更新のタイムスタンプを評価します。これがキャッシュタイムアウトよりも古い場合には、最新とは見なされず、新規のプロジェクト更新が実行されます。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:405
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:395
msgid "Time in seconds to consider an inventory sync to be current. During job runs and callbacks the task system will evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, and a new inventory sync will be performed."
msgstr "インベントリーの同期が最新の状態であることを判別するために使用される時間 (秒単位) です。ジョブの実行およびコールバック時に、タスクシステムは最新の同期のタイムスタンプを評価します。これがキャッシュタイムアウトよりも古い場合は最新とは見なされず、インベントリーの同期が新たに実行されます。"
@@ -7073,8 +6980,8 @@ msgstr "タイプの詳細"
msgid "UNLINK"
msgstr "リンクの削除"
-#: client/src/projects/add/projects-add.controller.js:182
-#: client/src/projects/edit/projects-edit.controller.js:303
+#: client/src/projects/add/projects-add.controller.js:190
+#: client/src/projects/edit/projects-edit.controller.js:311
msgid "URL popover text"
msgstr "URL ポップオーバーテキスト"
@@ -7193,7 +7100,7 @@ msgstr "サポートされない入力タイプ"
msgid "Update Not Found"
msgstr "更新が見つかりません"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:344
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:334
msgid "Update Options"
msgstr "オプションの更新"
@@ -7211,7 +7118,7 @@ msgstr "更新が取り消されました。クリックして詳細を確認し
msgid "Update failed. Click for details"
msgstr "更新に失敗しました。クリックして詳細を確認してください。"
-#: client/src/projects/edit/projects-edit.controller.js:331
+#: client/src/projects/edit/projects-edit.controller.js:339
msgid "Update in Progress"
msgstr "更新が進行中です"
@@ -7220,13 +7127,13 @@ msgstr "更新が進行中です"
msgid "Update missing. Click for details"
msgstr "更新がありません。クリックして詳細を確認してください。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:372
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:377
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:362
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:367
msgid "Update on Launch"
msgstr "起動時の更新"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:383
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:389
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:373
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:379
msgid "Update on Project Update"
msgstr "プロジェクト更新時の更新"
@@ -7274,7 +7181,7 @@ msgstr "SSL の使用"
msgid "Use TLS"
msgstr "TLS の使用"
-#: client/src/notifications/notificationTemplates.form.js:586
+#: client/src/notifications/notificationTemplates.form.js:558
msgid "Use custom messages to change the content of notifications sent when a job starts, succeeds, or fails. Use curly braces to access information about the job: {{ job_friendly_name }}, {{ url }}, or attributes of the job such as {{ job.status }}. You may apply a number of possible variables in the message. Refer to the Ansible Tower documentation for more details."
msgstr "カスタムメッセージを使用して、ジョブの開始時、成功時、または失敗時に送信する通知内容を変更します。中括弧を使用して、ジョブの情報 ({{ job_friendly_name }}, {{ url }}) またはジョブの属性 ({{ job.status }}) にアクセスします。メッセージには、使用可能な変数を複数適用できます。詳細は、Ansible Tower ドキュメント を参照してください。"
@@ -7291,8 +7198,8 @@ msgstr "Git、Subversion (svn)、または Mercurial (hg) などのリモート
#: client/src/credentials/credentials.form.js:456
#: client/src/inventories-hosts/inventories/smart-inventory/smart-inventory.form.js:125
#: client/src/inventories-hosts/inventories/standard-inventory/inventory.form.js:122
-#: client/src/organizations/organizations.form.js:119
-#: client/src/organizations/organizations.form.js:160
+#: client/src/organizations/organizations.form.js:128
+#: client/src/organizations/organizations.form.js:169
#: client/src/projects/projects.form.js:296
#: client/src/teams/teams.form.js:96
#: client/src/templates/workflows.form.js:306
@@ -7315,8 +7222,8 @@ msgstr "ユーザータイプ"
#: client/src/credentials/factories/kind-change.factory.js:40
#: client/src/credentials/factories/kind-change.factory.js:73
#: client/src/credentials/factories/kind-change.factory.js:94
-#: client/src/notifications/notificationTemplates.form.js:453
-#: client/src/notifications/notificationTemplates.form.js:492
+#: client/src/notifications/notificationTemplates.form.js:425
+#: client/src/notifications/notificationTemplates.form.js:464
#: client/src/notifications/notificationTemplates.form.js:64
#: client/src/users/users.form.js:59
#: client/src/users/users.list.js:29
@@ -7338,7 +7245,7 @@ msgstr "指定されたクラウドまたはインフラストラクチャープ
#: client/lib/components/components.strings.js:80
#: client/src/access/add-rbac-resource/rbac-resource.partial.html:35
#: client/src/activity-stream/streamDropdownNav/stream-dropdown-nav.directive.js:38
-#: client/src/organizations/organizations.form.js:101
+#: client/src/organizations/organizations.form.js:110
#: client/src/teams/teams.form.js:78
msgid "Users"
msgstr "ユーザー"
@@ -7376,11 +7283,6 @@ msgstr "詳細を表示"
msgid "VIEW PER PAGE"
msgstr "ページ別のビュー"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:249
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:261
-msgid "VPC ID:"
-msgstr "VPC ID:"
-
#: client/src/license/license.partial.html:10
msgid "Valid License"
msgstr "有効なライセンス"
@@ -7409,8 +7311,8 @@ msgstr "Vault パスワード"
#: client/features/templates/templates.strings.js:60
#: client/src/inventories-hosts/inventories/adhoc/adhoc.form.js:82
#: client/src/inventories-hosts/inventories/adhoc/adhoc.form.js:91
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:330
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:337
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:290
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:297
#: client/src/templates/job_templates/job-template.form.js:189
#: client/src/templates/job_templates/job-template.form.js:196
msgid "Verbosity"
@@ -7451,10 +7353,10 @@ msgstr "Insights の表示"
msgid "View Insights Data"
msgstr "Insights データの表示"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:201
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:225
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:249
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:324
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:161
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:185
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:209
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:284
msgid "View JSON examples at"
msgstr "JSON サンプルの表示: "
@@ -7488,10 +7390,10 @@ msgstr "プロジェクトのチェックアウト結果を表示"
msgid "View Survey"
msgstr "Survey の表示"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:202
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:226
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:250
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:325
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:162
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:186
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:210
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:285
msgid "View YAML examples at"
msgstr "YAML サンプルの表示: "
@@ -7567,11 +7469,6 @@ msgstr "チームの表示"
msgid "View template"
msgstr "テンプレートの表示"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:261
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:274
-msgid "View the"
-msgstr "次の表示:"
-
#: client/features/output/output.strings.js:22
#: client/lib/components/components.strings.js:63
msgid "View the Credential"
@@ -7719,11 +7616,11 @@ msgstr "Ansible Tower へようこそ! ライセンスを取得するために
msgid "Welcome to Ansible {{BRAND_NAME}}! Please sign in."
msgstr "Ansible {{BRAND_NAME}} へようこそ! サインインしてください。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:365
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:355
msgid "When not checked, a merge will be performed, combining local variables with those found on the external source."
msgstr "チェックが付けられていない場合、ローカル変数と外部ソースにあるものを組み合わせるマージが実行されます。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:354
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:344
msgid "When not checked, local child hosts and groups not found on the external source will remain untouched by the inventory update process."
msgstr "チェックが付けられていない場合、外部ソースにないローカルの子ホストおよびグループは、インベントリーの更新プロセスによって処理されないままになります。"
@@ -7740,19 +7637,19 @@ msgstr "このプロジェクトがジョブテンプレートで使用されて
msgid "Workflow"
msgstr "ワークフロー"
-#: client/src/notifications/notificationTemplates.form.js:666
+#: client/src/notifications/notificationTemplates.form.js:638
msgid "Workflow Approved Message"
msgstr "ワークフロー承認メッセージ"
-#: client/src/notifications/notificationTemplates.form.js:677
+#: client/src/notifications/notificationTemplates.form.js:649
msgid "Workflow Approved Message Body"
msgstr "ワークフロー承認メッセージのボディー"
-#: client/src/notifications/notificationTemplates.form.js:689
+#: client/src/notifications/notificationTemplates.form.js:661
msgid "Workflow Denied Message"
msgstr "ワークフロー拒否メッセージ"
-#: client/src/notifications/notificationTemplates.form.js:700
+#: client/src/notifications/notificationTemplates.form.js:672
msgid "Workflow Denied Message Body"
msgstr "ワークフロー拒否メッセージのボディー"
@@ -7768,11 +7665,11 @@ msgstr "ワークフロージョブテンプレートのノード"
msgid "Workflow Job Templates"
msgstr "ワークフロージョブテンプレート"
-#: client/src/notifications/notificationTemplates.form.js:712
+#: client/src/notifications/notificationTemplates.form.js:684
msgid "Workflow Pending Approval Message"
msgstr "ワークフロー承認待ちメッセージ"
-#: client/src/notifications/notificationTemplates.form.js:723
+#: client/src/notifications/notificationTemplates.form.js:695
msgid "Workflow Pending Approval Message Body"
msgstr "ワークフロー承認待ちメッセージのボディー"
@@ -7787,11 +7684,11 @@ msgstr "ワークフローテンプレート"
msgid "Workflow Templates"
msgstr "ワークフローテンプレート"
-#: client/src/notifications/notificationTemplates.form.js:735
+#: client/src/notifications/notificationTemplates.form.js:707
msgid "Workflow Timed Out Message"
msgstr "ワークフローのタイムアウトメッセージ"
-#: client/src/notifications/notificationTemplates.form.js:746
+#: client/src/notifications/notificationTemplates.form.js:718
msgid "Workflow Timed Out Message Body"
msgstr "ワークフローのタイムアウトメッセージのボディー"
@@ -7809,10 +7706,10 @@ msgstr "書き込み"
msgid "YAML"
msgstr "YAML"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:199
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:223
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:247
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:322
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:159
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:183
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:207
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:282
msgid "YAML:"
msgstr "YAML:"
@@ -7943,11 +7840,6 @@ msgstr "エラー"
msgid "failed"
msgstr "失敗"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:262
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:275
-msgid "for a complete list of supported filters."
-msgstr "サポートされるフィルターの詳細の一覧"
-
#: client/src/inventories-hosts/inventories/related/hosts/related-groups-labels/relatedGroupsLabelsList.directive.js:82
msgid "from the"
msgstr " 削除元:"
@@ -7999,11 +7891,6 @@ msgstr "新規"
msgid "of"
msgstr " /"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:254
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:267
-msgid "of the filters match."
-msgstr "フィルターの一致:"
-
#: client/src/scheduler/scheduler.strings.js:34
msgid "on"
msgstr "オン"
@@ -8063,11 +7950,6 @@ msgstr "同期が失敗しているソースです。クリックして詳細を
msgid "successful"
msgstr "成功"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:259
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:272
-msgid "test"
-msgstr "test (テスト)"
-
#: client/src/activity-stream/factories/build-description.factory.js:136
msgid "timed out"
msgstr "タイムアウト"
@@ -8078,10 +7960,6 @@ msgstr "タイムアウト"
msgid "to"
msgstr " 〜 "
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:138
-msgid "to include all regions. Only Hosts associated with the selected regions will be updated."
-msgstr "すべてのリージョンが含まれます。選択したリージョンに関連付けられたホストのみが更新されます。"
-
#: client/src/inventories-hosts/inventories/related/sources/factories/get-sync-status-msg.factory.js:17
msgid "to start it now."
msgstr "すぐに開始します。"
@@ -8106,32 +7984,34 @@ msgstr "v3 デフォルト%s - 「デフォルト」に設定"
msgid "v3 multi-domain%s - your domain name"
msgstr "v3 マルチドメイン%s - ドメイン名"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:318
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:278
msgid "view azure_rm.ini in the Ansible community.general github repo."
-msgstr "Ansible community.general github リポジトリーで azure_rm.ini を表示します。"
+msgstr "Ansible community.general github リポジトリーの azure_rm.ini を表示します。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:219
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:244
+msgid "view cloudforms.ini in the Ansible Collections github repo."
+msgstr "Ansible Collections github リポジトリーのcloudforms.ini を表示します。"
+
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:179
msgid "view ec2.ini in the community.aws repo."
-msgstr "community.awsリポジトリーで ec2.ini を表示します。"
+msgstr "community.aws リポジトリーの ec2.ini を表示します。"
-#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:243
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:261
+msgid "view foreman.ini in the Ansible Collections github repo."
+msgstr "Ansible Collections github リポジトリーの foreman.ini を表示します。"
+
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:227
+msgid "view openstack.yml in the Openstack github repo."
+msgstr "Openstack github リポジトリーの openstack.yml を表示します。"
+
+#: client/src/inventories-hosts/inventories/related/sources/sources.form.js:203
msgid "view vmware_inventory.ini in the vmware community repo."
-msgstr "vmware コミュニティーリポジトリーで vmware_inventory.ini を表示します。"
+msgstr "vmware コミュニティーリポジトリーの vmware_inventory.ini を表示します。"
#: client/features/jobs/jobs.strings.js:24
msgid "waiting"
msgstr "待機中"
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:254
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:267
-msgid "when"
-msgstr "日付"
-
-#: client/src/inventories-hosts/inventories/related/sources/add/sources-add.controller.js:240
-#: client/src/inventories-hosts/inventories/related/sources/edit/sources-edit.controller.js:252
-msgid "will create group names similar to the following examples based on the options selected:"
-msgstr "選択されたオプションに基づいて以下のサンプルと同様のグループ名が作成されます。"
-
#: client/index.template.ejs:158
msgid "working..."
msgstr "実行中..."
diff --git a/awx/ui/test/spec/inventories/insights/data/insights-data.js b/awx/ui/test/spec/inventories/insights/data/insights-data.js
index 0d36f8af6a..91b8fa0503 100644
--- a/awx/ui/test/spec/inventories/insights/data/insights-data.js
+++ b/awx/ui/test/spec/inventories/insights/data/insights-data.js
@@ -152,7 +152,7 @@ export default {
"date": "2017-05-25T14:01:19.000Z",
"rule": {
"summary_html": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally only have read-only access to and thus increase their privileges on the system.
\n",
- "generic_html": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.
\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild.
\nRed Hat recommends that you update the kernel package or apply mitigations.
\n",
+ "generic_html": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.
\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild.
\nRed Hat recommends that you update the kernel package or apply mitigations.
\n",
"more_info_html": "\n",
"severity": "WARN",
"ansible": true,
@@ -163,7 +163,7 @@ export default {
"plugin": "CVE_2016_5195_kernel",
"description": "Kernel vulnerable to privilege escalation via permission bypass (CVE-2016-5195)",
"summary": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally only have read-only access to and thus increase their privileges on the system.",
- "generic": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.\n\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild. \n\nRed Hat recommends that you update the kernel package or apply mitigations.",
+ "generic": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.\n\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild. \n\nRed Hat recommends that you update the kernel package or apply mitigations.",
"reason": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally have read-only access to and thus increase their privileges on the system.
\nThis host is affected because it is running kernel 3.10.0-123.el7 .
\nThere is currently no mitigation applied and your system is vulnerable.
\n",
"type": null,
"more_info": "* For more information about the flaw see [CVE-2016-5195](https://access.redhat.com/security/cve/CVE-2016-5195)\n* To learn how to upgrade packages, see \"[What is yum and how do I use it?](https://access.redhat.com/solutions/9934)\"\n* The Customer Portal page for the [Red Hat Security Team](https://access.redhat.com/security/) contains more information about policies, procedures, and alerts for Red Hat Products.\n* The Security Team also maintains a frequently updated blog at [securityblog.redhat.com](https://securityblog.redhat.com).",
diff --git a/awx/ui/test/spec/inventories/insights/data/medium.insights-data.js b/awx/ui/test/spec/inventories/insights/data/medium.insights-data.js
index 0e251f8d74..9f62d41022 100644
--- a/awx/ui/test/spec/inventories/insights/data/medium.insights-data.js
+++ b/awx/ui/test/spec/inventories/insights/data/medium.insights-data.js
@@ -95,7 +95,7 @@ export default [
"date": "2017-05-25T14:01:19.000Z",
"rule": {
"summary_html": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally only have read-only access to and thus increase their privileges on the system.
\n",
- "generic_html": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.
\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild.
\nRed Hat recommends that you update the kernel package or apply mitigations.
\n",
+ "generic_html": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.
\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild.
\nRed Hat recommends that you update the kernel package or apply mitigations.
\n",
"more_info_html": "\n",
"severity": "WARN",
"ansible": true,
@@ -106,7 +106,7 @@ export default [
"plugin": "CVE_2016_5195_kernel",
"description": "Kernel vulnerable to privilege escalation via permission bypass (CVE-2016-5195)",
"summary": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally only have read-only access to and thus increase their privileges on the system.",
- "generic": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.\n\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild. \n\nRed Hat recommends that you update the kernel package or apply mitigations.",
+ "generic": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.\n\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild. \n\nRed Hat recommends that you update the kernel package or apply mitigations.",
"reason": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally have read-only access to and thus increase their privileges on the system.
\nThis host is affected because it is running kernel 3.10.0-123.el7 .
\nThere is currently no mitigation applied and your system is vulnerable.
\n",
"type": null,
"more_info": "* For more information about the flaw see [CVE-2016-5195](https://access.redhat.com/security/cve/CVE-2016-5195)\n* To learn how to upgrade packages, see \"[What is yum and how do I use it?](https://access.redhat.com/solutions/9934)\"\n* The Customer Portal page for the [Red Hat Security Team](https://access.redhat.com/security/) contains more information about policies, procedures, and alerts for Red Hat Products.\n* The Security Team also maintains a frequently updated blog at [securityblog.redhat.com](https://securityblog.redhat.com).",
diff --git a/awx/ui/test/spec/inventories/insights/data/solvable.insights-data.js b/awx/ui/test/spec/inventories/insights/data/solvable.insights-data.js
index 5e563e9912..97a5ec25f8 100644
--- a/awx/ui/test/spec/inventories/insights/data/solvable.insights-data.js
+++ b/awx/ui/test/spec/inventories/insights/data/solvable.insights-data.js
@@ -13,7 +13,7 @@ export default [
"date": "2017-05-25T14:01:19.000Z",
"rule": {
"summary_html": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally only have read-only access to and thus increase their privileges on the system.
\n",
- "generic_html": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.
\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild.
\nRed Hat recommends that you update the kernel package or apply mitigations.
\n",
+ "generic_html": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.
\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild.
\nRed Hat recommends that you update the kernel package or apply mitigations.
\n",
"more_info_html": "\n",
"severity": "WARN",
"ansible": true,
@@ -24,7 +24,7 @@ export default [
"plugin": "CVE_2016_5195_kernel",
"description": "Kernel vulnerable to privilege escalation via permission bypass (CVE-2016-5195)",
"summary": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally only have read-only access to and thus increase their privileges on the system.",
- "generic": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.\n\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild. \n\nRed Hat recommends that you update the kernel package or apply mitigations.",
+ "generic": "A race condition was found in the way Linux kernel's memory subsystem handled breakage of the read only shared mappings COW situation on write access. An unprivileged local user could use this flaw to write to files they should normally have read-only access to, and thus increase their privileges on the system.\n\nA process that is able to mmap a file is able to race Copy on Write (COW) page creation (within get_user_pages) with madvise(MADV_DONTNEED) kernel system calls. This would allow modified pages to bypass the page protection mechanism and modify the mapped file. The vulnerability could be abused by allowing an attacker to modify existing setuid files with instructions to elevate permissions. This attack has been found in the wild. \n\nRed Hat recommends that you update the kernel package or apply mitigations.",
"reason": "A flaw was found in the Linux kernel's memory subsystem. An unprivileged local user could use this flaw to write to files they would normally have read-only access to and thus increase their privileges on the system.
\nThis host is affected because it is running kernel 3.10.0-123.el7 .
\nThere is currently no mitigation applied and your system is vulnerable.
\n",
"type": null,
"more_info": "* For more information about the flaw see [CVE-2016-5195](https://access.redhat.com/security/cve/CVE-2016-5195)\n* To learn how to upgrade packages, see \"[What is yum and how do I use it?](https://access.redhat.com/solutions/9934)\"\n* The Customer Portal page for the [Red Hat Security Team](https://access.redhat.com/security/) contains more information about policies, procedures, and alerts for Red Hat Products.\n* The Security Team also maintains a frequently updated blog at [securityblog.redhat.com](https://securityblog.redhat.com).",
diff --git a/awx/ui/test/unit/components/stream.unit.js b/awx/ui/test/unit/components/stream.unit.js
index c4343d59b7..5d979592be 100644
--- a/awx/ui/test/unit/components/stream.unit.js
+++ b/awx/ui/test/unit/components/stream.unit.js
@@ -51,7 +51,13 @@ describe('Output | StreamService', () => {
});
describe('isReadyToRender', () => {
- it("it's never ready to render unless the result of getReadyCount is greater than 0", () => {
+ it("it's never ready to render when live updates are enabled unless the result of getReadyCount is greater than 0", () => {
+ delete window.liveUpdates;
+ Object.defineProperty(window, 'liveUpdates', {
+ value: true,
+ writable: false
+ });
+
const params = [
[-1, false],
[0, false],
diff --git a/awx/ui_next/package-lock.json b/awx/ui_next/package-lock.json
index 04fc14aa73..3fa12a9cac 100644
--- a/awx/ui_next/package-lock.json
+++ b/awx/ui_next/package-lock.json
@@ -2849,19 +2849,19 @@
}
},
"@lingui/babel-plugin-extract-messages": {
- "version": "2.9.1",
- "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-2.9.1.tgz",
- "integrity": "sha512-ZguvJK/ByupNgmmxvlO43DewGTMVtPsolA/Uxm24YTLg0jf7cu/GRaqYxYt+SojWHuo2/mn6dzDJZPFcK1A2og==",
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-2.9.2.tgz",
+ "integrity": "sha512-nkRufTupyWjRpzX5ZXB1qMKWT9B+gAuMXYD4blZ/HHCJlEOXeds9W5bugVd3N8Ts5m4o9iRoqeaCuVcH7sJ8Wg==",
"dev": true,
"requires": {
- "@lingui/conf": "2.9.1",
+ "@lingui/conf": "2.9.2",
"babel-generator": "^6.26.1"
}
},
"@lingui/babel-plugin-transform-js": {
- "version": "2.9.1",
- "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-transform-js/-/babel-plugin-transform-js-2.9.1.tgz",
- "integrity": "sha512-m1RAKUKffyxfWQ2Y0KfGHhYofdHdM+0aSsi2kgcebqzsuE8Hwuy+r4GZr593cSIqBu6Ugb6/WKoAUGUoEF9ZHw==",
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-transform-js/-/babel-plugin-transform-js-2.9.2.tgz",
+ "integrity": "sha512-yWoyhOfjRa9744TbVb/WN1OWxZYFLuXcWH5aVCu/sZ2b1YpsGCtfhplc5lRVWN8QcsfpjYmFiPqzU6swE5OFdQ==",
"dev": true
},
"@lingui/babel-plugin-transform-react": {
@@ -2871,15 +2871,15 @@
"dev": true
},
"@lingui/cli": {
- "version": "2.9.1",
- "resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-2.9.1.tgz",
- "integrity": "sha512-Ruzg4UxZzqnJDMpdGE04G8NnXFRAd5nH5dZ7rAYBurSddlLEqE3DVrxMToYC1BfCpbmWznHguPwusljrCUkMeg==",
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-2.9.2.tgz",
+ "integrity": "sha512-j46vUe8hSgvsm3j2V4sPLxOdd2HacacGC5E+bWx4wHEhd/yxV4nwPfWpuC7wLoBwM/y2bcF8Q2V7ahEznKSO6A==",
"dev": true,
"requires": {
- "@lingui/babel-plugin-extract-messages": "2.9.1",
- "@lingui/babel-plugin-transform-js": "2.9.1",
- "@lingui/babel-plugin-transform-react": "2.9.1",
- "@lingui/conf": "2.9.1",
+ "@lingui/babel-plugin-extract-messages": "2.9.2",
+ "@lingui/babel-plugin-transform-js": "2.9.2",
+ "@lingui/babel-plugin-transform-react": "2.9.2",
+ "@lingui/conf": "2.9.2",
"babel-generator": "^6.26.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-runtime": "^6.26.0",
@@ -2896,13 +2896,18 @@
"make-plural": "^4.1.1",
"messageformat-parser": "^2.0.0",
"mkdirp": "^0.5.1",
- "opencollective": "^1.0.3",
"ora": "^3.4.0",
"pofile": "^1.0.11",
"pseudolocale": "^1.1.0",
"ramda": "^0.26.1"
},
"dependencies": {
+ "@lingui/babel-plugin-transform-react": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-transform-react/-/babel-plugin-transform-react-2.9.2.tgz",
+ "integrity": "sha512-bxvrepiS6J9vZqRtpRiAgBIASQscjvu7aFmPqH4Y6001TDXrYuyhhNRt1BI3k2E6C2SckHh5vRtSpsqpjEiY3A==",
+ "dev": true
+ },
"ansi-escapes": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
@@ -3015,9 +3020,9 @@
}
},
"@lingui/conf": {
- "version": "2.9.1",
- "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-2.9.1.tgz",
- "integrity": "sha512-33mEShmFemYy5tH+fgvAH+mNaO9MbOyDM1lt+frx/ozXBMbGsPrEReDFGtCY2CGEITn5Q9SGJbcRscnfQ2DubQ==",
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-2.9.2.tgz",
+ "integrity": "sha512-xHfH+zLhM7PaMawqeK1G+Pq+reVPYR8eU7XixH4VRHWK8n/itTb4fRl24xc5IUgeXJx+NX1qCzBYVz0i13xlVg==",
"dev": true,
"requires": {
"chalk": "^2.3.0",
@@ -3025,46 +3030,6 @@
"jest-regex-util": "^24.3.0",
"jest-validate": "^24.8.0",
"pkg-conf": "^3.1.0"
- },
- "dependencies": {
- "cosmiconfig": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
- "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
- "dev": true,
- "requires": {
- "import-fresh": "^2.0.0",
- "is-directory": "^0.3.1",
- "js-yaml": "^3.13.1",
- "parse-json": "^4.0.0"
- }
- },
- "import-fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
- "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
- "dev": true,
- "requires": {
- "caller-path": "^2.0.0",
- "resolve-from": "^3.0.0"
- }
- },
- "parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
- "dev": true,
- "requires": {
- "error-ex": "^1.3.1",
- "json-parse-better-errors": "^1.0.1"
- }
- },
- "resolve-from": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
- "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
- "dev": true
- }
}
},
"@lingui/core": {
@@ -4299,12 +4264,6 @@
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
"dev": true
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
}
}
},
@@ -4516,25 +4475,6 @@
"integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==",
"dev": true
},
- "babel-polyfill": {
- "version": "6.23.0",
- "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz",
- "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=",
- "dev": true,
- "requires": {
- "babel-runtime": "^6.22.0",
- "core-js": "^2.4.0",
- "regenerator-runtime": "^0.10.0"
- },
- "dependencies": {
- "regenerator-runtime": {
- "version": "0.10.5",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
- "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
- "dev": true
- }
- }
- },
"babel-preset-jest": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz",
@@ -4993,7 +4933,8 @@
"brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
- "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+ "dev": true
},
"browser-process-hrtime": {
"version": "1.0.0",
@@ -5581,9 +5522,9 @@
}
},
"cli-spinners": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz",
- "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==",
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz",
+ "integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA==",
"dev": true
},
"cli-table": {
@@ -7199,6 +7140,7 @@
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+ "dev": true,
"requires": {
"bn.js": "^4.4.0",
"brorand": "^1.0.1",
@@ -7212,7 +7154,8 @@
"bn.js": {
"version": "4.11.9",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
- "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw=="
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
}
}
},
@@ -7234,15 +7177,6 @@
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
"dev": true
},
- "encoding": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
- "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
- "dev": true,
- "requires": {
- "iconv-lite": "~0.4.13"
- }
- },
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -9117,6 +9051,7 @@
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
"requires": {
"inherits": "^2.0.3",
"minimalistic-assert": "^1.0.1"
@@ -9151,6 +9086,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
"integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dev": true,
"requires": {
"hash.js": "^1.0.3",
"minimalistic-assert": "^1.0.0",
@@ -9567,7 +9503,8 @@
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -11458,12 +11395,14 @@
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
- "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
},
"minimalistic-crypto-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
- "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+ "dev": true
},
"minimatch": {
"version": "3.0.4",
@@ -11732,20 +11671,10 @@
"tslib": "^1.10.0"
}
},
- "node-fetch": {
- "version": "1.6.3",
- "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz",
- "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=",
- "dev": true,
- "requires": {
- "encoding": "^0.1.11",
- "is-stream": "^1.0.1"
- }
- },
"node-forge": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
- "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
+ "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
"dev": true
},
"node-int64": {
@@ -12180,213 +12109,6 @@
}
}
},
- "opencollective": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/opencollective/-/opencollective-1.0.3.tgz",
- "integrity": "sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE=",
- "dev": true,
- "requires": {
- "babel-polyfill": "6.23.0",
- "chalk": "1.1.3",
- "inquirer": "3.0.6",
- "minimist": "1.2.0",
- "node-fetch": "1.6.3",
- "opn": "4.0.2"
- },
- "dependencies": {
- "ansi-escapes": {
- "version": "1.4.0",
- "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
- "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
- "dev": true
- },
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "dev": true,
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- }
- },
- "chardet": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
- "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
- "dev": true
- },
- "cli-cursor": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
- "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
- "dev": true,
- "requires": {
- "restore-cursor": "^2.0.0"
- }
- },
- "external-editor": {
- "version": "2.2.0",
- "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
- "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
- "dev": true,
- "requires": {
- "chardet": "^0.4.0",
- "iconv-lite": "^0.4.17",
- "tmp": "^0.0.33"
- }
- },
- "figures": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
- "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
- "dev": true,
- "requires": {
- "escape-string-regexp": "^1.0.5"
- }
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "inquirer": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz",
- "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=",
- "dev": true,
- "requires": {
- "ansi-escapes": "^1.1.0",
- "chalk": "^1.0.0",
- "cli-cursor": "^2.1.0",
- "cli-width": "^2.0.0",
- "external-editor": "^2.0.1",
- "figures": "^2.0.0",
- "lodash": "^4.3.0",
- "mute-stream": "0.0.7",
- "run-async": "^2.2.0",
- "rx": "^4.1.0",
- "string-width": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "through": "^2.3.6"
- }
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "mimic-fn": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
- "dev": true
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
- "mute-stream": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
- "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
- "dev": true
- },
- "onetime": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
- "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
- "dev": true,
- "requires": {
- "mimic-fn": "^1.0.0"
- }
- },
- "opn": {
- "version": "4.0.2",
- "resolved": "http://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
- "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=",
- "dev": true,
- "requires": {
- "object-assign": "^4.0.1",
- "pinkie-promise": "^2.0.0"
- }
- },
- "restore-cursor": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
- "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
- "dev": true,
- "requires": {
- "onetime": "^2.0.0",
- "signal-exit": "^3.0.2"
- }
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true
- }
- }
- },
"opn": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
@@ -12822,16 +12544,6 @@
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
- "parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
- "dev": true,
- "requires": {
- "error-ex": "^1.3.1",
- "json-parse-better-errors": "^1.0.1"
- }
- },
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
@@ -15440,12 +15152,6 @@
"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
"integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q="
},
- "rx": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
- "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
- "dev": true
- },
"rxjs": {
"version": "6.5.5",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
@@ -15581,12 +15287,12 @@
"dev": true
},
"selfsigned": {
- "version": "1.10.7",
- "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz",
- "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==",
+ "version": "1.10.8",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz",
+ "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==",
"dev": true,
"requires": {
- "node-forge": "0.9.0"
+ "node-forge": "^0.10.0"
}
},
"semver": {
diff --git a/awx/ui_next/package.json b/awx/ui_next/package.json
index 2fc0e84108..e270d0ba22 100644
--- a/awx/ui_next/package.json
+++ b/awx/ui_next/package.json
@@ -30,7 +30,7 @@
},
"devDependencies": {
"@babel/polyfill": "^7.8.7",
- "@lingui/cli": "^2.9.1",
+ "@lingui/cli": "^2.9.2",
"@lingui/macro": "^2.9.1",
"@nteract/mockument": "^1.0.4",
"babel-core": "^7.0.0-bridge.0",
diff --git a/awx/ui_next/src/api/index.js b/awx/ui_next/src/api/index.js
index c7dab6f76b..dd0f4a811c 100644
--- a/awx/ui_next/src/api/index.js
+++ b/awx/ui_next/src/api/index.js
@@ -17,12 +17,14 @@ import Jobs from './models/Jobs';
import Labels from './models/Labels';
import Me from './models/Me';
import NotificationTemplates from './models/NotificationTemplates';
+import Notifications from './models/Notifications';
import Organizations from './models/Organizations';
import ProjectUpdates from './models/ProjectUpdates';
import Projects from './models/Projects';
import Roles from './models/Roles';
import Root from './models/Root';
import Schedules from './models/Schedules';
+import Settings from './models/Settings';
import SystemJobs from './models/SystemJobs';
import Teams from './models/Teams';
import Tokens from './models/Tokens';
@@ -53,12 +55,14 @@ const JobsAPI = new Jobs();
const LabelsAPI = new Labels();
const MeAPI = new Me();
const NotificationTemplatesAPI = new NotificationTemplates();
+const NotificationsAPI = new Notifications();
const OrganizationsAPI = new Organizations();
const ProjectUpdatesAPI = new ProjectUpdates();
const ProjectsAPI = new Projects();
const RolesAPI = new Roles();
const RootAPI = new Root();
const SchedulesAPI = new Schedules();
+const SettingsAPI = new Settings();
const SystemJobsAPI = new SystemJobs();
const TeamsAPI = new Teams();
const TokensAPI = new Tokens();
@@ -90,12 +94,14 @@ export {
LabelsAPI,
MeAPI,
NotificationTemplatesAPI,
+ NotificationsAPI,
OrganizationsAPI,
ProjectUpdatesAPI,
ProjectsAPI,
RolesAPI,
RootAPI,
SchedulesAPI,
+ SettingsAPI,
SystemJobsAPI,
TeamsAPI,
TokensAPI,
diff --git a/awx/ui_next/src/api/models/Groups.js b/awx/ui_next/src/api/models/Groups.js
index ea506cc303..0e76edca8c 100644
--- a/awx/ui_next/src/api/models/Groups.js
+++ b/awx/ui_next/src/api/models/Groups.js
@@ -12,7 +12,9 @@ class Groups extends Base {
}
associateHost(id, hostId) {
- return this.http.post(`${this.baseUrl}${id}/hosts/`, { id: hostId });
+ return this.http.post(`${this.baseUrl}${id}/hosts/`, {
+ id: hostId,
+ });
}
createHost(id, data) {
@@ -20,7 +22,9 @@ class Groups extends Base {
}
readAllHosts(id, params) {
- return this.http.get(`${this.baseUrl}${id}/all_hosts/`, { params });
+ return this.http.get(`${this.baseUrl}${id}/all_hosts/`, {
+ params,
+ });
}
disassociateHost(id, host) {
@@ -29,6 +33,10 @@ class Groups extends Base {
disassociate: true,
});
}
+
+ readChildren(id, params) {
+ return this.http.get(`${this.baseUrl}${id}/children/`, params);
+ }
}
export default Groups;
diff --git a/awx/ui_next/src/api/models/Inventories.js b/awx/ui_next/src/api/models/Inventories.js
index 077a534d27..c9d774e002 100644
--- a/awx/ui_next/src/api/models/Inventories.js
+++ b/awx/ui_next/src/api/models/Inventories.js
@@ -99,6 +99,17 @@ class Inventories extends InstanceGroupsMixin(Base) {
`${this.baseUrl}${inventoryId}/update_inventory_sources/`
);
}
+
+ readAdHocOptions(inventoryId) {
+ return this.http.options(`${this.baseUrl}${inventoryId}/ad_hoc_commands/`);
+ }
+
+ launchAdHocCommands(inventoryId, values) {
+ return this.http.post(
+ `${this.baseUrl}${inventoryId}/ad_hoc_commands/`,
+ values
+ );
+ }
}
export default Inventories;
diff --git a/awx/ui_next/src/api/models/JobTemplates.js b/awx/ui_next/src/api/models/JobTemplates.js
index 4f631cec2a..44281f1511 100644
--- a/awx/ui_next/src/api/models/JobTemplates.js
+++ b/awx/ui_next/src/api/models/JobTemplates.js
@@ -24,6 +24,10 @@ class JobTemplates extends SchedulesMixin(
return this.http.post(`${this.baseUrl}${id}/launch/`, data);
}
+ readTemplateOptions(id) {
+ return this.http.options(`${this.baseUrl}${id}/`);
+ }
+
readLaunch(id) {
return this.http.get(`${this.baseUrl}${id}/launch/`);
}
diff --git a/awx/ui_next/src/api/models/Jobs.js b/awx/ui_next/src/api/models/Jobs.js
index 06b929c0ba..9c43509f9e 100644
--- a/awx/ui_next/src/api/models/Jobs.js
+++ b/awx/ui_next/src/api/models/Jobs.js
@@ -1,13 +1,29 @@
import Base from '../Base';
import RelaunchMixin from '../mixins/Relaunch.mixin';
-const BASE_URLS = {
- playbook: '/jobs/',
- project: '/project_updates/',
- system: '/system_jobs/',
- inventory: '/inventory_updates/',
- command: '/ad_hoc_commands/',
- workflow: '/workflow_jobs/',
+const getBaseURL = type => {
+ switch (type) {
+ case 'playbook':
+ case 'job':
+ return '/jobs/';
+ case 'project':
+ case 'project_update':
+ return '/project_updates/';
+ case 'system':
+ case 'system_job':
+ return '/system_jobs/';
+ case 'inventory':
+ case 'inventory_update':
+ return '/inventory_updates/';
+ case 'command':
+ case 'ad_hoc_command':
+ return '/ad_hoc_commands/';
+ case 'workflow':
+ case 'workflow_job':
+ return '/workflow_jobs/';
+ default:
+ throw new Error('Unable to find matching job type');
+ }
};
class Jobs extends RelaunchMixin(Base) {
@@ -16,16 +32,20 @@ class Jobs extends RelaunchMixin(Base) {
this.baseUrl = '/api/v2/jobs/';
}
+ cancel(id, type) {
+ return this.http.post(`/api/v2${getBaseURL(type)}${id}/cancel/`);
+ }
+
readDetail(id, type) {
- return this.http.get(`/api/v2${BASE_URLS[type]}${id}/`);
+ return this.http.get(`/api/v2${getBaseURL(type)}${id}/`);
}
readEvents(id, type = 'playbook', params = {}) {
let endpoint;
if (type === 'playbook') {
- endpoint = `/api/v2${BASE_URLS[type]}${id}/job_events/`;
+ endpoint = `/api/v2${getBaseURL(type)}${id}/job_events/`;
} else {
- endpoint = `/api/v2${BASE_URLS[type]}${id}/events/`;
+ endpoint = `/api/v2${getBaseURL(type)}${id}/events/`;
}
return this.http.get(endpoint, { params });
}
diff --git a/awx/ui_next/src/api/models/Notifications.js b/awx/ui_next/src/api/models/Notifications.js
new file mode 100644
index 0000000000..68405c0986
--- /dev/null
+++ b/awx/ui_next/src/api/models/Notifications.js
@@ -0,0 +1,10 @@
+import Base from '../Base';
+
+class Notifications extends Base {
+ constructor(http) {
+ super(http);
+ this.baseUrl = '/api/v2/notifications/';
+ }
+}
+
+export default Notifications;
diff --git a/awx/ui_next/src/api/models/Roles.js b/awx/ui_next/src/api/models/Roles.js
index 5846d9fa79..3f89c8eb5f 100644
--- a/awx/ui_next/src/api/models/Roles.js
+++ b/awx/ui_next/src/api/models/Roles.js
@@ -7,14 +7,14 @@ class Roles extends Base {
}
disassociateUserRole(roleId, userId) {
- return this.http.post(`${this.baseUrl}/${roleId}/users/`, {
+ return this.http.post(`${this.baseUrl}${roleId}/users/`, {
disassociate: true,
id: userId,
});
}
disassociateTeamRole(roleId, teamId) {
- return this.http.post(`${this.baseUrl}/${roleId}/teams/`, {
+ return this.http.post(`${this.baseUrl}${roleId}/teams/`, {
disassociate: true,
id: teamId,
});
diff --git a/awx/ui_next/src/api/models/Settings.js b/awx/ui_next/src/api/models/Settings.js
new file mode 100644
index 0000000000..cf8de70530
--- /dev/null
+++ b/awx/ui_next/src/api/models/Settings.js
@@ -0,0 +1,26 @@
+import Base from '../Base';
+
+class Settings extends Base {
+ constructor(http) {
+ super(http);
+ this.baseUrl = '/api/v2/settings/';
+ }
+
+ readAllOptions() {
+ return this.http.options(`${this.baseUrl}all/`);
+ }
+
+ updateAll(data) {
+ return this.http.patch(`${this.baseUrl}all/`, data);
+ }
+
+ readCategory(category) {
+ return this.http.get(`${this.baseUrl}${category}/`);
+ }
+
+ readCategoryOptions(category) {
+ return this.http.options(`${this.baseUrl}${category}/`);
+ }
+}
+
+export default Settings;
diff --git a/awx/ui_next/src/api/models/WorkflowJobTemplates.js b/awx/ui_next/src/api/models/WorkflowJobTemplates.js
index 7c582cd57f..db84e26f7b 100644
--- a/awx/ui_next/src/api/models/WorkflowJobTemplates.js
+++ b/awx/ui_next/src/api/models/WorkflowJobTemplates.js
@@ -12,6 +12,10 @@ class WorkflowJobTemplates extends SchedulesMixin(NotificationsMixin(Base)) {
return this.http.get(`${this.baseUrl}${id}/webhook_key/`);
}
+ readWorkflowJobTemplateOptions(id) {
+ return this.http.options(`${this.baseUrl}${id}/`);
+ }
+
updateWebhookKey(id) {
return this.http.post(`${this.baseUrl}${id}/webhook_key/`);
}
diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCommands.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCommands.jsx
new file mode 100644
index 0000000000..927ad09f78
--- /dev/null
+++ b/awx/ui_next/src/components/AdHocCommands/AdHocCommands.jsx
@@ -0,0 +1,102 @@
+import React, { useCallback } from 'react';
+import { useHistory } from 'react-router-dom';
+import { withI18n } from '@lingui/react';
+import { t } from '@lingui/macro';
+import PropTypes from 'prop-types';
+
+import useRequest, { useDismissableError } from '../../util/useRequest';
+import { InventoriesAPI } from '../../api';
+
+import AlertModal from '../AlertModal';
+import ErrorDetail from '../ErrorDetail';
+import AdHocCommandsWizard from './AdHocCommandsWizard';
+import ContentLoading from '../ContentLoading';
+
+function AdHocCommands({
+ onClose,
+ adHocItems,
+ itemId,
+ i18n,
+ moduleOptions,
+ credentialTypeId,
+}) {
+ const history = useHistory();
+ const verbosityOptions = [
+ { value: '0', key: '0', label: i18n._(t`0 (Normal)`) },
+ { value: '1', key: '1', label: i18n._(t`1 (Verbose)`) },
+ { value: '2', key: '2', label: i18n._(t`2 (More Verbose)`) },
+ { value: '3', key: '3', label: i18n._(t`3 (Debug)`) },
+ { value: '4', key: '4', label: i18n._(t`4 (Connection Debug)`) },
+ ];
+
+ const {
+ isloading: isLaunchLoading,
+ error,
+ request: launchAdHocCommands,
+ } = useRequest(
+ useCallback(
+ async values => {
+ const { data } = await InventoriesAPI.launchAdHocCommands(
+ itemId,
+ values
+ );
+ history.push(`/jobs/command/${data.id}/output`);
+ },
+
+ [itemId, history]
+ )
+ );
+
+ const { dismissError } = useDismissableError(error);
+
+ const handleSubmit = async values => {
+ const { credential, ...remainingValues } = values;
+ const newCredential = credential[0].id;
+
+ const manipulatedValues = {
+ credential: newCredential,
+ ...remainingValues,
+ };
+ await launchAdHocCommands(manipulatedValues);
+ };
+
+ if (isLaunchLoading) {
+ return ;
+ }
+
+ if (error) {
+ return (
+ {
+ dismissError();
+ }}
+ >
+ <>
+ {i18n._(t`Failed to launch job.`)}
+
+ >
+
+ );
+ }
+ return (
+ dismissError()}
+ />
+ );
+}
+
+AdHocCommands.propTypes = {
+ adHocItems: PropTypes.arrayOf(PropTypes.object).isRequired,
+ itemId: PropTypes.number.isRequired,
+};
+
+export default withI18n()(AdHocCommands);
diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCommands.test.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCommands.test.jsx
new file mode 100644
index 0000000000..f83009b46a
--- /dev/null
+++ b/awx/ui_next/src/components/AdHocCommands/AdHocCommands.test.jsx
@@ -0,0 +1,240 @@
+import React from 'react';
+import { act } from 'react-dom/test-utils';
+import {
+ mountWithContexts,
+ waitForElement,
+} from '../../../testUtils/enzymeHelpers';
+import { CredentialTypesAPI, InventoriesAPI, CredentialsAPI } from '../../api';
+import AdHocCommands from './AdHocCommands';
+
+jest.mock('../../api/models/CredentialTypes');
+jest.mock('../../api/models/Inventories');
+jest.mock('../../api/models/Credentials');
+
+const credentials = [
+ { id: 1, kind: 'cloud', name: 'Cred 1', url: 'www.google.com' },
+ { id: 2, kind: 'ssh', name: 'Cred 2', url: 'www.google.com' },
+ { id: 3, kind: 'Ansible', name: 'Cred 3', url: 'www.google.com' },
+ { id: 4, kind: 'Machine', name: 'Cred 4', url: 'www.google.com' },
+ { id: 5, kind: 'Machine', name: 'Cred 5', url: 'www.google.com' },
+];
+const moduleOptions = [
+ ['command', 'command'],
+ ['shell', 'shell'],
+];
+const adHocItems = [
+ {
+ name: 'Inventory 1 Org 0',
+ },
+ { name: 'Inventory 2 Org 0' },
+];
+
+describe(' ', () => {
+ let wrapper;
+ afterEach(() => {
+ wrapper.unmount();
+ jest.clearAllMocks();
+ });
+
+ test('mounts successfully', async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+ {}}
+ itemId={1}
+ credentialTypeId={1}
+ adHocItems={adHocItems}
+ moduleOptions={moduleOptions}
+ />
+ );
+ });
+ expect(wrapper.find('AdHocCommands').length).toBe(1);
+ });
+
+ test('should submit properly', async () => {
+ InventoriesAPI.launchAdHocCommands.mockResolvedValue({ data: { id: 1 } });
+ CredentialsAPI.read.mockResolvedValue({
+ data: {
+ results: credentials,
+ count: 5,
+ },
+ });
+ await act(async () => {
+ wrapper = mountWithContexts(
+ {}}
+ itemId={1}
+ credentialTypeId={1}
+ adHocItems={adHocItems}
+ moduleOptions={moduleOptions}
+ />
+ );
+ });
+
+ wrapper.update();
+
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(true);
+
+ expect(
+ wrapper
+ .find('WizardNavItem[content="Machine credential"]')
+ .prop('isDisabled')
+ ).toBe(true);
+
+ await act(async () => {
+ wrapper.find('AnsibleSelect[name="module_name"]').prop('onChange')(
+ {},
+ 'command'
+ );
+ wrapper.find('input#module_args').simulate('change', {
+ target: { value: 'foo', name: 'module_args' },
+ });
+ wrapper.find('AnsibleSelect[name="verbosity"]').prop('onChange')({}, 1);
+ });
+
+ wrapper.update();
+
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(
+ false
+ );
+ await act(async () =>
+ wrapper.find('Button[type="submit"]').prop('onClick')()
+ );
+ await waitForElement(wrapper, 'ContentEmpty', el => el.length === 0);
+ // second step of wizard
+
+ await act(async () => {
+ wrapper
+ .find('input[aria-labelledby="check-action-item-4"]')
+ .simulate('change', { target: { checked: true } });
+ });
+
+ wrapper.update();
+
+ expect(
+ wrapper.find('CheckboxListItem[label="Cred 4"]').prop('isSelected')
+ ).toBe(true);
+
+ await act(async () =>
+ wrapper.find('Button[type="submit"]').prop('onClick')()
+ );
+
+ expect(InventoriesAPI.launchAdHocCommands).toBeCalledWith(1, {
+ module_args: 'foo',
+ diff_mode: false,
+ credential: 4,
+ job_type: 'run',
+ become_enabled: '',
+ extra_vars: '---',
+ forks: 0,
+ limit: 'Inventory 1 Org 0, Inventory 2 Org 0',
+ module_name: 'command',
+ verbosity: 1,
+ });
+ });
+
+ test('should throw error on submission properly', async () => {
+ InventoriesAPI.launchAdHocCommands.mockRejectedValue(
+ new Error({
+ response: {
+ config: {
+ method: 'post',
+ url: '/api/v2/inventories/1/ad_hoc_commands',
+ },
+ data: 'An error occurred',
+ status: 403,
+ },
+ })
+ );
+ InventoriesAPI.readAdHocOptions.mockResolvedValue({
+ data: {
+ actions: {
+ GET: {
+ module_name: {
+ choices: [
+ ['command', 'command'],
+ ['foo', 'foo'],
+ ],
+ },
+ verbosity: { choices: [[1], [2]] },
+ },
+ },
+ },
+ });
+ CredentialTypesAPI.read.mockResolvedValue({
+ data: { results: [{ id: 1 }] },
+ });
+ CredentialsAPI.read.mockResolvedValue({
+ data: {
+ results: credentials,
+ count: 5,
+ },
+ });
+ await act(async () => {
+ wrapper = mountWithContexts(
+ {}}
+ credentialTypeId={1}
+ itemId={1}
+ adHocItems={adHocItems}
+ moduleOptions={moduleOptions}
+ />
+ );
+ });
+
+ wrapper.update();
+
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(true);
+ expect(
+ wrapper
+ .find('WizardNavItem[content="Machine credential"]')
+ .prop('isDisabled')
+ ).toBe(true);
+
+ await act(async () => {
+ wrapper.find('AnsibleSelect[name="module_name"]').prop('onChange')(
+ {},
+ 'command'
+ );
+ wrapper.find('input#module_args').simulate('change', {
+ target: { value: 'foo', name: 'module_args' },
+ });
+ wrapper.find('AnsibleSelect[name="verbosity"]').prop('onChange')({}, 1);
+ });
+
+ wrapper.update();
+
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(
+ false
+ );
+
+ await act(async () =>
+ wrapper.find('Button[type="submit"]').prop('onClick')()
+ );
+
+ await waitForElement(wrapper, 'ContentEmpty', el => el.length === 0);
+
+ // second step of wizard
+
+ await act(async () => {
+ wrapper
+ .find('input[aria-labelledby="check-action-item-4"]')
+ .simulate('change', { target: { checked: true } });
+ });
+
+ wrapper.update();
+
+ expect(
+ wrapper.find('CheckboxListItem[label="Cred 4"]').prop('isSelected')
+ ).toBe(true);
+
+ await act(async () =>
+ wrapper.find('Button[type="submit"]').prop('onClick')()
+ );
+
+ await waitForElement(wrapper, 'ErrorDetail', el => el.length > 0);
+ });
+});
diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.jsx
new file mode 100644
index 0000000000..83eee59d88
--- /dev/null
+++ b/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.jsx
@@ -0,0 +1,142 @@
+import React, { useState } from 'react';
+import { withI18n } from '@lingui/react';
+import { t } from '@lingui/macro';
+import { ExclamationCircleIcon as PFExclamationCircleIcon } from '@patternfly/react-icons';
+import { Tooltip } from '@patternfly/react-core';
+import { withFormik, useFormikContext } from 'formik';
+import PropTypes from 'prop-types';
+
+import styled from 'styled-components';
+import Wizard from '../Wizard';
+import AdHocCredentialStep from './AdHocCredentialStep';
+import AdHocDetailsStep from './AdHocDetailsStep';
+
+const AlertText = styled.div`
+ color: var(--pf-global--danger-color--200);
+ font-weight: var(--pf-global--FontWeight--bold);
+`;
+
+const ExclamationCircleIcon = styled(PFExclamationCircleIcon)`
+ margin-left: 10px;
+ color: var(--pf-global--danger-color--100);
+`;
+
+function AdHocCommandsWizard({
+ onLaunch,
+ i18n,
+ moduleOptions,
+ verbosityOptions,
+ onCloseWizard,
+ credentialTypeId,
+}) {
+ const [currentStepId, setCurrentStepId] = useState(1);
+ const [enableLaunch, setEnableLaunch] = useState(false);
+
+ const { values, errors, touched } = useFormikContext();
+
+ const enabledNextOnDetailsStep = () => {
+ if (!values.module_name) {
+ return false;
+ }
+
+ if (values.module_name === 'shell' || values.module_name === 'command') {
+ if (values.module_args) {
+ return true;
+ // eslint-disable-next-line no-else-return
+ } else {
+ return false;
+ }
+ }
+ return undefined; // makes the linter happy;
+ };
+ const hasDetailsStepError = errors.module_args && touched.module_args;
+
+ const steps = [
+ {
+ id: 1,
+ key: 1,
+ name: hasDetailsStepError ? (
+
+ {i18n._(t`Details`)}
+
+
+
+
+ ) : (
+ i18n._(t`Details`)
+ ),
+ component: (
+
+ ),
+ enableNext: enabledNextOnDetailsStep(),
+ nextButtonText: i18n._(t`Next`),
+ },
+ {
+ id: 2,
+ key: 2,
+ name: i18n._(t`Machine credential`),
+ component: (
+ setEnableLaunch(true)}
+ />
+ ),
+ enableNext: enableLaunch && Object.values(errors).length === 0,
+ nextButtonText: i18n._(t`Launch`),
+ canJumpTo: currentStepId >= 2,
+ },
+ ];
+
+ const currentStep = steps.find(step => step.id === currentStepId);
+
+ return (
+ setCurrentStepId(step.id)}
+ onClose={() => onCloseWizard()}
+ onSave={() => {
+ onLaunch(values);
+ }}
+ steps={steps}
+ title={i18n._(t`Run command`)}
+ nextButtonText={currentStep.nextButtonText || undefined}
+ backButtonText={i18n._(t`Back`)}
+ cancelButtonText={i18n._(t`Cancel`)}
+ />
+ );
+}
+
+const FormikApp = withFormik({
+ mapPropsToValues({ adHocItems, verbosityOptions }) {
+ const adHocItemStrings = adHocItems.map(item => item.name).join(', ');
+ return {
+ limit: adHocItemStrings || 'all',
+ credential: [],
+ module_args: '',
+ verbosity: verbosityOptions[0].value,
+ forks: 0,
+ diff_mode: false,
+ become_enabled: '',
+ module_name: '',
+ extra_vars: '---',
+ job_type: 'run',
+ };
+ },
+})(AdHocCommandsWizard);
+
+FormikApp.propTypes = {
+ onLaunch: PropTypes.func.isRequired,
+ moduleOptions: PropTypes.arrayOf(PropTypes.object).isRequired,
+ verbosityOptions: PropTypes.arrayOf(PropTypes.object).isRequired,
+ onCloseWizard: PropTypes.func.isRequired,
+ credentialTypeId: PropTypes.number.isRequired,
+};
+export default withI18n()(FormikApp);
diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.test.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.test.jsx
new file mode 100644
index 0000000000..d38aa28bbc
--- /dev/null
+++ b/awx/ui_next/src/components/AdHocCommands/AdHocCommandsWizard.test.jsx
@@ -0,0 +1,203 @@
+import React from 'react';
+import { act } from 'react-dom/test-utils';
+import {
+ mountWithContexts,
+ waitForElement,
+} from '../../../testUtils/enzymeHelpers';
+import { CredentialsAPI } from '../../api';
+import AdHocCommandsWizard from './AdHocCommandsWizard';
+
+jest.mock('../../api/models/CredentialTypes');
+jest.mock('../../api/models/Inventories');
+jest.mock('../../api/models/Credentials');
+const verbosityOptions = [
+ { value: '0', key: '0', label: '0 (Normal)' },
+ { value: '1', key: '1', label: '1 (Verbose)' },
+ { value: '2', key: '2', label: '2 (More Verbose)' },
+ { value: '3', key: '3', label: '3 (Debug)' },
+ { value: '4', key: '4', label: '4 (Connection Debug)' },
+];
+const adHocItems = [
+ { name: 'Inventory 1' },
+ { name: 'Inventory 2' },
+ { name: 'inventory 3' },
+];
+describe(' ', () => {
+ let wrapper;
+ const onLaunch = jest.fn();
+ beforeEach(async () => {
+ await act(async () => {
+ wrapper = mountWithContexts(
+ {}}
+ credentialTypeId={1}
+ />
+ );
+ });
+ });
+ afterEach(() => {
+ jest.clearAllMocks();
+ wrapper.unmount();
+ });
+
+ test('should mount properly', async () => {
+ expect(wrapper.find('AdHocCommandsWizard').length).toBe(1);
+ });
+
+ test('next and nav item should be disabled', async () => {
+ await waitForElement(wrapper, 'WizardNavItem', el => el.length > 0);
+ expect(
+ wrapper.find('WizardNavItem[content="Details"]').prop('isCurrent')
+ ).toBe(true);
+ expect(
+ wrapper.find('WizardNavItem[content="Details"]').prop('isDisabled')
+ ).toBe(false);
+ expect(
+ wrapper
+ .find('WizardNavItem[content="Machine credential"]')
+ .prop('isDisabled')
+ ).toBe(true);
+ expect(
+ wrapper
+ .find('WizardNavItem[content="Machine credential"]')
+ .prop('isCurrent')
+ ).toBe(false);
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(true);
+ });
+
+ test('next button should become active, and should navigate to the next step', async () => {
+ await waitForElement(wrapper, 'WizardNavItem', el => el.length > 0);
+
+ await act(async () => {
+ wrapper.find('AnsibleSelect[name="module_name"]').prop('onChange')(
+ {},
+ 'command'
+ );
+ wrapper.find('input#module_args').simulate('change', {
+ target: { value: 'foo', name: 'module_args' },
+ });
+ wrapper.find('AnsibleSelect[name="verbosity"]').prop('onChange')({}, 1);
+ });
+ wrapper.update();
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(
+ false
+ );
+ await act(async () =>
+ wrapper.find('Button[type="submit"]').prop('onClick')()
+ );
+
+ wrapper.update();
+ });
+ test('launch button should become active', async () => {
+ CredentialsAPI.read.mockResolvedValue({
+ data: {
+ results: [
+ { id: 1, name: 'Cred 1', url: '' },
+ { id: 2, name: 'Cred2', url: '' },
+ ],
+ count: 2,
+ },
+ });
+ await waitForElement(wrapper, 'WizardNavItem', el => el.length > 0);
+
+ await act(async () => {
+ wrapper.find('AnsibleSelect[name="module_name"]').prop('onChange')(
+ {},
+ 'command'
+ );
+ wrapper.find('input#module_args').simulate('change', {
+ target: { value: 'foo', name: 'module_args' },
+ });
+ wrapper.find('AnsibleSelect[name="verbosity"]').prop('onChange')({}, 1);
+ });
+ wrapper.update();
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(
+ false
+ );
+ await act(async () =>
+ wrapper.find('Button[type="submit"]').prop('onClick')()
+ );
+
+ wrapper.update();
+ await waitForElement(wrapper, 'OptionsList', el => el.length > 0);
+ expect(wrapper.find('CheckboxListItem').length).toBe(2);
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(true);
+
+ await act(async () => {
+ wrapper
+ .find('input[aria-labelledby="check-action-item-1"]')
+ .simulate('change', { target: { checked: true } });
+ });
+
+ wrapper.update();
+
+ expect(
+ wrapper.find('CheckboxListItem[label="Cred 1"]').prop('isSelected')
+ ).toBe(true);
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(
+ false
+ );
+
+ await act(async () =>
+ wrapper.find('Button[type="submit"]').prop('onClick')()
+ );
+
+ expect(onLaunch).toHaveBeenCalled();
+ });
+ test('should show error in navigation bar', async () => {
+ await waitForElement(wrapper, 'WizardNavItem', el => el.length > 0);
+
+ await act(async () => {
+ wrapper.find('AnsibleSelect[name="module_name"]').prop('onChange')(
+ {},
+ 'command'
+ );
+ wrapper.find('input#module_args').simulate('change', {
+ target: { value: '', name: 'module_args' },
+ });
+ });
+ waitForElement(wrapper, 'ExclamationCircleIcon', el => el.length > 0);
+ });
+
+ test('expect credential step to throw error', async () => {
+ CredentialsAPI.read.mockRejectedValue(
+ new Error({
+ response: {
+ config: {
+ method: 'get',
+ url: '/api/v2/credentals',
+ },
+ data: 'An error occurred',
+ status: 403,
+ },
+ })
+ );
+ await waitForElement(wrapper, 'WizardNavItem', el => el.length > 0);
+
+ await act(async () => {
+ wrapper.find('AnsibleSelect[name="module_name"]').prop('onChange')(
+ {},
+ 'command'
+ );
+ wrapper.find('input#module_args').simulate('change', {
+ target: { value: 'foo', name: 'module_args' },
+ });
+ wrapper.find('AnsibleSelect[name="verbosity"]').prop('onChange')({}, 1);
+ });
+ wrapper.update();
+ expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(
+ false
+ );
+
+ await act(async () =>
+ wrapper.find('Button[type="submit"]').prop('onClick')()
+ );
+
+ wrapper.update();
+ expect(wrapper.find('ContentError').length).toBe(1);
+ });
+});
diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.jsx
new file mode 100644
index 0000000000..9a1f4fb094
--- /dev/null
+++ b/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.jsx
@@ -0,0 +1,128 @@
+import React, { useEffect, useCallback } from 'react';
+import { useHistory } from 'react-router-dom';
+import { withI18n } from '@lingui/react';
+import { t } from '@lingui/macro';
+import PropTypes from 'prop-types';
+import { useField } from 'formik';
+import { Form, FormGroup } from '@patternfly/react-core';
+import { CredentialsAPI } from '../../api';
+import { FieldTooltip } from '../FormField';
+
+import { getQSConfig, parseQueryString, mergeParams } from '../../util/qs';
+import useRequest from '../../util/useRequest';
+import ContentError from '../ContentError';
+import ContentLoading from '../ContentLoading';
+import { required } from '../../util/validators';
+import OptionsList from '../OptionsList';
+
+const QS_CONFIG = getQSConfig('credentials', {
+ page: 1,
+ page_size: 5,
+ order_by: 'name',
+});
+
+function AdHocCredentialStep({ i18n, credentialTypeId, onEnableLaunch }) {
+ const history = useHistory();
+ const {
+ error,
+ isLoading,
+ request: fetchCredentials,
+ result: { credentials, credentialCount },
+ } = useRequest(
+ useCallback(async () => {
+ const params = parseQueryString(QS_CONFIG, history.location.search);
+
+ const {
+ data: { results, count },
+ } = await CredentialsAPI.read(
+ mergeParams(params, { credential_type: credentialTypeId })
+ );
+
+ return {
+ credentials: results,
+ credentialCount: count,
+ };
+ }, [credentialTypeId, history.location.search]),
+ { credentials: [], credentialCount: 0 }
+ );
+
+ useEffect(() => {
+ fetchCredentials();
+ }, [fetchCredentials]);
+
+ const [credentialField, credentialMeta, credentialHelpers] = useField({
+ name: 'credential',
+ validate: required(null, i18n),
+ });
+ if (error) {
+ return ;
+ }
+ if (isLoading) {
+ return ;
+ }
+ return (
+
+ );
+}
+
+AdHocCredentialStep.propTypes = {
+ credentialTypeId: PropTypes.number.isRequired,
+ onEnableLaunch: PropTypes.func.isRequired,
+};
+export default withI18n()(AdHocCredentialStep);
diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.test.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.test.jsx
new file mode 100644
index 0000000000..873b792278
--- /dev/null
+++ b/awx/ui_next/src/components/AdHocCommands/AdHocCredentialStep.test.jsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import { act } from 'react-dom/test-utils';
+import { Formik } from 'formik';
+import {
+ mountWithContexts,
+ waitForElement,
+} from '../../../testUtils/enzymeHelpers';
+import { CredentialsAPI } from '../../api';
+import AdHocCredentialStep from './AdHocCredentialStep';
+
+jest.mock('../../api/models/Credentials');
+
+describe(' ', () => {
+ const onEnableLaunch = jest.fn();
+ let wrapper;
+ beforeEach(async () => {
+ CredentialsAPI.read.mockResolvedValue({
+ data: {
+ results: [
+ { id: 1, name: 'Cred 1', url: 'wwww.google.com' },
+ { id: 2, name: 'Cred2', url: 'wwww.google.com' },
+ ],
+ count: 2,
+ },
+ });
+ await act(async () => {
+ wrapper = mountWithContexts(
+
+
+
+ );
+ });
+ });
+ afterEach(() => {
+ jest.clearAllMocks();
+ wrapper.unmount();
+ });
+
+ test('should mount properly', async () => {
+ await waitForElement(wrapper, 'OptionsList', el => el.length > 0);
+ });
+
+ test('should call api', async () => {
+ await waitForElement(wrapper, 'OptionsList', el => el.length > 0);
+ expect(CredentialsAPI.read).toHaveBeenCalled();
+ expect(wrapper.find('CheckboxListItem').length).toBe(2);
+ });
+});
diff --git a/awx/ui_next/src/components/AdHocCommands/AdHocDetailsStep.jsx b/awx/ui_next/src/components/AdHocCommands/AdHocDetailsStep.jsx
new file mode 100644
index 0000000000..bd5fdab92c
--- /dev/null
+++ b/awx/ui_next/src/components/AdHocCommands/AdHocDetailsStep.jsx
@@ -0,0 +1,323 @@
+/* eslint-disable react/no-unescaped-entities */
+import React from 'react';
+import { withI18n } from '@lingui/react';
+import { t } from '@lingui/macro';
+import PropTypes from 'prop-types';
+import { useField } from 'formik';
+import { Form, FormGroup, Switch, Checkbox } from '@patternfly/react-core';
+import styled from 'styled-components';
+
+import { BrandName } from '../../variables';
+import AnsibleSelect from '../AnsibleSelect';
+import FormField, { FieldTooltip } from '../FormField';
+import { VariablesField } from '../CodeMirrorInput';
+import {
+ FormColumnLayout,
+ FormFullWidthLayout,
+ FormCheckboxLayout,
+} from '../FormLayout';
+import { required } from '../../util/validators';
+
+const TooltipWrapper = styled.div`
+ text-align: left;
+`;
+
+// Setting BrandName to a variable here is necessary to get the jest tests
+// passing. Attempting to use BrandName in the template literal results
+// in failing tests.
+const brandName = BrandName;
+
+function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
+ const [moduleNameField, moduleNameMeta, moduleNameHelpers] = useField({
+ name: 'module_name',
+ validate: required(null, i18n),
+ });
+
+ const [variablesField] = useField('extra_vars');
+ const [diffModeField, , diffModeHelpers] = useField('diff_mode');
+ const [becomeEnabledField, , becomeEnabledHelpers] = useField(
+ 'become_enabled'
+ );
+ const [verbosityField, verbosityMeta, verbosityHelpers] = useField({
+ name: 'verbosity',
+ validate: required(null, i18n),
+ });
+
+ const argumentsRequired =
+ moduleNameField.value === 'command' || moduleNameField.value === 'shell';
+ const [, argumentsMeta, argumentsHelpers] = useField({
+ name: 'module_args',
+ validate: argumentsRequired && required(null, i18n),
+ });
+
+ const isValid = !argumentsMeta.error || !argumentsMeta.touched;
+
+ return (
+
+ }
+ />
+
+ }
+ id="become_enabled"
+ isChecked={becomeEnabledField.value}
+ onChange={checked => {
+ becomeEnabledHelpers.setValue(checked);
+ }}
+ />
+
+
+
+
+