diff --git a/.gitignore b/.gitignore index ca9dd12298..afd8aa7187 100644 --- a/.gitignore +++ b/.gitignore @@ -106,7 +106,6 @@ reports *.log.[0-9] *.results local/ -*.mo # AWX python libs populated by requirements.txt awx/lib/.deps_built diff --git a/Makefile b/Makefile index 0679a11911..5acfa44f86 100644 --- a/Makefile +++ b/Makefile @@ -428,7 +428,7 @@ celeryd: @if [ "$(VENV_BASE)" ]; then \ . $(VENV_BASE)/tower/bin/activate; \ fi; \ - $(PYTHON) manage.py celeryd -l DEBUG -B --autoreload --autoscale=20,3 --schedule=$(CELERY_SCHEDULE_FILE) -Q projects,jobs,default,scheduler,broadcast_all,$(COMPOSE_HOST) + $(PYTHON) manage.py celeryd -l DEBUG -B --autoreload --autoscale=20,3 --schedule=$(CELERY_SCHEDULE_FILE) -Q projects,jobs,default,scheduler,broadcast_all,$(COMPOSE_HOST) -n celery@$(COMPOSE_HOST) #$(PYTHON) manage.py celery multi show projects jobs default -l DEBUG -Q:projects projects -Q:jobs jobs -Q:default default -c:projects 1 -c:jobs 3 -c:default 3 -Ofair -B --schedule=$(CELERY_SCHEDULE_FILE) # Run to start the zeromq callback receiver @@ -559,9 +559,12 @@ messages: fi; \ $(PYTHON) manage.py makemessages -l $(LANG) --keep-pot -# generate l10n .json .mo -languages: $(UI_DEPS_FLAG_FILE) check-po +# generate l10n .json +ui-languages: $(UI_DEPS_FLAG_FILE) check-po $(NPM_BIN) --prefix awx/ui run languages + +# generate l10n .mo +api-languages: @if [ "$(VENV_BASE)" ]; then \ . $(VENV_BASE)/tower/bin/activate; \ fi; \ @@ -592,8 +595,7 @@ ui-devel: $(UI_DEPS_FLAG_FILE) ui-release: $(UI_RELEASE_FLAG_FILE) -# todo: include languages target when .po deliverables are added to source control -$(UI_RELEASE_FLAG_FILE): $(UI_DEPS_FLAG_FILE) +$(UI_RELEASE_FLAG_FILE): ui-languages $(UI_DEPS_FLAG_FILE) $(NPM_BIN) --prefix awx/ui run build-release touch $(UI_RELEASE_FLAG_FILE) diff --git a/awx/api/metadata.py b/awx/api/metadata.py index fb5c4d6493..8a3e75bdfb 100644 --- a/awx/api/metadata.py +++ b/awx/api/metadata.py @@ -13,7 +13,7 @@ from django.utils.translation import ugettext_lazy as _ from rest_framework import exceptions from rest_framework import metadata from rest_framework import serializers -from rest_framework.relations import RelatedField +from rest_framework.relations import RelatedField, ManyRelatedField from rest_framework.request import clone_request # Ansible Tower @@ -75,7 +75,7 @@ class Metadata(metadata.SimpleMetadata): elif getattr(field, 'fields', None): field_info['children'] = self.get_serializer_info(field) - if hasattr(field, 'choices') and not isinstance(field, RelatedField): + if not isinstance(field, (RelatedField, ManyRelatedField)) and hasattr(field, 'choices'): field_info['choices'] = [(choice_value, choice_name) for choice_value, choice_name in field.choices.items()] # Indicate if a field is write-only. diff --git a/awx/api/pagination.py b/awx/api/pagination.py index b6463ce515..9a416e9995 100644 --- a/awx/api/pagination.py +++ b/awx/api/pagination.py @@ -16,6 +16,7 @@ class Pagination(pagination.PageNumberPagination): if not self.page.has_next(): return None url = self.request and self.request.get_full_path() or '' + url = url.encode('utf-8') page_number = self.page.next_page_number() return replace_query_param(url, self.page_query_param, page_number) @@ -23,5 +24,6 @@ class Pagination(pagination.PageNumberPagination): if not self.page.has_previous(): return None url = self.request and self.request.get_full_path() or '' + url = url.encode('utf-8') page_number = self.page.previous_page_number() return replace_query_param(url, self.page_query_param, page_number) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 05dca74cb6..8824a8b881 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -251,6 +251,7 @@ class BaseSerializer(serializers.ModelSerializer): 'inventory_update': _('Inventory Sync'), 'system_job': _('Management Job'), 'workflow_job': _('Workflow Job'), + 'workflow_job_template': _('Workflow Template'), } choices = [] for t in self.get_types(): @@ -1619,7 +1620,8 @@ class ResourceAccessListElementSerializer(UserSerializer): 'name': role.name, 'description': role.description, 'team_id': team_role.object_id, - 'team_name': team_role.content_object.name + 'team_name': team_role.content_object.name, + 'team_organization_name': team_role.content_object.organization.name, } if role.content_type is not None: role_dict['resource_name'] = role.content_object.name @@ -2369,7 +2371,7 @@ class WorkflowJobTemplateNodeSerializer(WorkflowNodeBaseSerializer): if view and view.request: request_method = view.request.method if request_method in ['PATCH']: - obj = view.get_object() + obj = self.instance char_prompts = copy.copy(obj.char_prompts) char_prompts.update(self.extract_char_prompts(data)) else: @@ -2708,18 +2710,15 @@ class WorkflowJobLaunchSerializer(BaseSerializer): variables_needed_to_start = serializers.ReadOnlyField() survey_enabled = serializers.SerializerMethodField() extra_vars = VerbatimField(required=False, write_only=True) - warnings = serializers.SerializerMethodField() workflow_job_template_data = serializers.SerializerMethodField() class Meta: model = WorkflowJobTemplate - fields = ('can_start_without_user_input', 'extra_vars', 'warnings', + fields = ('can_start_without_user_input', 'extra_vars', 'survey_enabled', 'variables_needed_to_start', + 'node_templates_missing', 'node_prompts_rejected', 'workflow_job_template_data') - def get_warnings(self, obj): - return obj.get_warnings() - def get_survey_enabled(self, obj): if obj: return obj.survey_enabled and 'spec' in obj.survey_spec diff --git a/awx/api/templates/api/system_job_template_launch.md b/awx/api/templates/api/system_job_template_launch.md index 4543014005..9433bcadfa 100644 --- a/awx/api/templates/api/system_job_template_launch.md +++ b/awx/api/templates/api/system_job_template_launch.md @@ -13,7 +13,7 @@ Which will act on data older than 30 days. For `cleanup_facts`: -`{"older_than": "4w", `granularity`: "3d"}` +`{"older_than": "4w", "granularity": "3d"}` Which will reduce the granularity of scan data to one scan per 3 days when the data is older than 4w. diff --git a/awx/api/views.py b/awx/api/views.py index 30bc51f781..965078727a 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -851,6 +851,7 @@ class OrganizationNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView) serializer_class = NotificationTemplateSerializer parent_model = Organization relationship = 'notification_templates_any' + new_in_300 = True class OrganizationNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): @@ -859,6 +860,7 @@ class OrganizationNotificationTemplatesErrorList(SubListCreateAttachDetachAPIVie serializer_class = NotificationTemplateSerializer parent_model = Organization relationship = 'notification_templates_error' + new_in_300 = True class OrganizationNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): @@ -867,6 +869,7 @@ class OrganizationNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIV serializer_class = NotificationTemplateSerializer parent_model = Organization relationship = 'notification_templates_success' + new_in_300 = True class OrganizationAccessList(ResourceAccessList): @@ -921,6 +924,7 @@ class TeamRolesList(SubListCreateAttachDetachAPIView): metadata_class = RoleMetadata parent_model = Team relationship='member_role.children' + new_in_300 = True def get_queryset(self): team = get_object_or_404(Team, pk=self.kwargs['pk']) @@ -1103,6 +1107,7 @@ class ProjectNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView): serializer_class = NotificationTemplateSerializer parent_model = Project relationship = 'notification_templates_any' + new_in_300 = True class ProjectNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): @@ -1111,6 +1116,7 @@ class ProjectNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): serializer_class = NotificationTemplateSerializer parent_model = Project relationship = 'notification_templates_error' + new_in_300 = True class ProjectNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): @@ -1119,6 +1125,7 @@ class ProjectNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): serializer_class = NotificationTemplateSerializer parent_model = Project relationship = 'notification_templates_success' + new_in_300 = True class ProjectUpdatesList(SubListAPIView): @@ -1156,6 +1163,7 @@ class ProjectUpdateList(ListAPIView): model = ProjectUpdate serializer_class = ProjectUpdateListSerializer + new_in_13 = True class ProjectUpdateDetail(RetrieveDestroyAPIView): @@ -1196,6 +1204,7 @@ class ProjectUpdateNotificationsList(SubListAPIView): serializer_class = NotificationSerializer parent_model = ProjectUpdate relationship = 'notifications' + new_in_300 = True class ProjectAccessList(ResourceAccessList): @@ -1271,6 +1280,7 @@ class UserRolesList(SubListCreateAttachDetachAPIView): parent_model = User relationship='roles' permission_classes = (IsAuthenticated,) + new_in_300 = True def get_queryset(self): u = get_object_or_404(User, pk=self.kwargs['pk']) @@ -1543,12 +1553,14 @@ class InventoryScriptList(ListCreateAPIView): model = CustomInventoryScript serializer_class = CustomInventoryScriptSerializer + new_in_210 = True class InventoryScriptDetail(RetrieveUpdateDestroyAPIView): model = CustomInventoryScript serializer_class = CustomInventoryScriptSerializer + new_in_210 = True def destroy(self, request, *args, **kwargs): instance = self.get_object() @@ -2170,6 +2182,7 @@ class InventorySourceNotificationTemplatesAnyList(SubListCreateAttachDetachAPIVi serializer_class = NotificationTemplateSerializer parent_model = InventorySource relationship = 'notification_templates_any' + new_in_300 = True def post(self, request, *args, **kwargs): parent = self.get_parent_object() @@ -2281,6 +2294,7 @@ class InventoryUpdateNotificationsList(SubListAPIView): serializer_class = NotificationSerializer parent_model = InventoryUpdate relationship = 'notifications' + new_in_300 = True class JobTemplateList(ListCreateAPIView): @@ -2316,7 +2330,10 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView): always_allow_superuser = False def update_raw_data(self, data): - obj = self.get_object() + try: + obj = self.get_object() + except PermissionDenied: + return data extra_vars = data.pop('extra_vars', None) or {} if obj: for p in obj.passwords_needed_to_start: @@ -2396,6 +2413,7 @@ class JobTemplateSurveySpec(GenericAPIView): model = JobTemplate parent_model = JobTemplate serializer_class = EmptySerializer + new_in_210 = True def get(self, request, *args, **kwargs): obj = self.get_object() @@ -2462,6 +2480,7 @@ class WorkflowJobTemplateSurveySpec(WorkflowsEnforcementMixin, JobTemplateSurvey model = WorkflowJobTemplate parent_model = WorkflowJobTemplate + new_in_310 = True class JobTemplateActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): @@ -2479,6 +2498,7 @@ class JobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView): serializer_class = NotificationTemplateSerializer parent_model = JobTemplate relationship = 'notification_templates_any' + new_in_300 = True class JobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): @@ -2487,6 +2507,7 @@ class JobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView serializer_class = NotificationTemplateSerializer parent_model = JobTemplate relationship = 'notification_templates_error' + new_in_300 = True class JobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): @@ -2495,6 +2516,7 @@ class JobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIVi serializer_class = NotificationTemplateSerializer parent_model = JobTemplate relationship = 'notification_templates_success' + new_in_300 = True class JobTemplateLabelList(DeleteLastUnattachLabelMixin, SubListCreateAttachDetachAPIView): @@ -2884,10 +2906,16 @@ class WorkflowJobTemplateCopy(WorkflowsEnforcementMixin, GenericAPIView): def get(self, request, *args, **kwargs): obj = self.get_object() - data = {} - copy_TF, messages = request.user.can_access_with_errors(self.model, 'copy', obj) - data['can_copy'] = copy_TF - data['warnings'] = messages + can_copy, messages = request.user.can_access_with_errors(self.model, 'copy', obj) + data = OrderedDict([ + ('can_copy', can_copy), ('can_copy_without_user_input', can_copy), + ('templates_unable_to_copy', [] if can_copy else ['all']), + ('credentials_unable_to_copy', [] if can_copy else ['all']), + ('inventories_unable_to_copy', [] if can_copy else ['all']) + ]) + if messages and can_copy: + data['can_copy_without_user_input'] = False + data.update(messages) return Response(data) def post(self, request, *args, **kwargs): @@ -2918,7 +2946,10 @@ class WorkflowJobTemplateLaunch(WorkflowsEnforcementMixin, RetrieveAPIView): always_allow_superuser = False def update_raw_data(self, data): - obj = self.get_object() + try: + obj = self.get_object() + except PermissionDenied: + return data extra_vars = data.pop('extra_vars', None) or {} if obj: for v in obj.variables_needed_to_start: @@ -2953,6 +2984,14 @@ class WorkflowJobRelaunch(WorkflowsEnforcementMixin, GenericAPIView): model = WorkflowJob serializer_class = EmptySerializer is_job_start = True + new_in_310 = True + + def check_object_permissions(self, request, obj): + if request.method == 'POST' and obj: + relaunch_perm, messages = request.user.can_access_with_errors(self.model, 'start', obj) + if not relaunch_perm and 'workflow_job_template' in messages: + self.permission_denied(request, message=messages['workflow_job_template']) + return super(WorkflowJobRelaunch, self).check_object_permissions(request, obj) def get(self, request, *args, **kwargs): return Response({}) @@ -3129,6 +3168,7 @@ class SystemJobTemplateList(ListAPIView): model = SystemJobTemplate serializer_class = SystemJobTemplateSerializer + new_in_210 = True def get(self, request, *args, **kwargs): if not request.user.is_superuser and not request.user.is_system_auditor: @@ -3140,6 +3180,7 @@ class SystemJobTemplateDetail(RetrieveAPIView): model = SystemJobTemplate serializer_class = SystemJobTemplateSerializer + new_in_210 = True class SystemJobTemplateLaunch(GenericAPIView): @@ -3147,6 +3188,7 @@ class SystemJobTemplateLaunch(GenericAPIView): model = SystemJobTemplate serializer_class = EmptySerializer is_job_start = True + new_in_210 = True def get(self, request, *args, **kwargs): return Response({}) @@ -3154,8 +3196,8 @@ class SystemJobTemplateLaunch(GenericAPIView): def post(self, request, *args, **kwargs): obj = self.get_object() - new_job = obj.create_unified_job(**request.data) - new_job.signal_start(**request.data) + new_job = obj.create_unified_job(extra_vars=request.data.get('extra_vars', {})) + new_job.signal_start() data = dict(system_job=new_job.id) return Response(data, status=status.HTTP_201_CREATED) @@ -3169,6 +3211,7 @@ class SystemJobTemplateSchedulesList(SubListCreateAttachDetachAPIView): parent_model = SystemJobTemplate relationship = 'schedules' parent_key = 'unified_job_template' + new_in_210 = True class SystemJobTemplateJobsList(SubListAPIView): @@ -3178,6 +3221,7 @@ class SystemJobTemplateJobsList(SubListAPIView): parent_model = SystemJobTemplate relationship = 'jobs' parent_key = 'system_job_template' + new_in_210 = True class SystemJobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView): @@ -3186,6 +3230,7 @@ class SystemJobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPI serializer_class = NotificationTemplateSerializer parent_model = SystemJobTemplate relationship = 'notification_templates_any' + new_in_300 = True class SystemJobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): @@ -3194,6 +3239,7 @@ class SystemJobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachA serializer_class = NotificationTemplateSerializer parent_model = SystemJobTemplate relationship = 'notification_templates_error' + new_in_300 = True class SystemJobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): @@ -3202,6 +3248,7 @@ class SystemJobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetac serializer_class = NotificationTemplateSerializer parent_model = SystemJobTemplate relationship = 'notification_templates_success' + new_in_300 = True class JobList(ListCreateAPIView): @@ -3239,10 +3286,12 @@ class JobLabelList(SubListAPIView): parent_model = Job relationship = 'labels' parent_key = 'job' + new_in_300 = True class WorkflowJobLabelList(WorkflowsEnforcementMixin, JobLabelList): parent_model = WorkflowJob + new_in_310 = True class JobActivityStreamList(ActivityStreamEnforcementMixin, SubListAPIView): @@ -3337,6 +3386,7 @@ class JobNotificationsList(SubListAPIView): serializer_class = NotificationSerializer parent_model = Job relationship = 'notifications' + new_in_300 = True class BaseJobHostSummariesList(SubListAPIView): @@ -3847,12 +3897,14 @@ class AdHocCommandNotificationsList(SubListAPIView): serializer_class = NotificationSerializer parent_model = AdHocCommand relationship = 'notifications' + new_in_300 = True class SystemJobList(ListCreateAPIView): model = SystemJob serializer_class = SystemJobListSerializer + new_in_210 = True def get(self, request, *args, **kwargs): if not request.user.is_superuser and not request.user.is_system_auditor: @@ -3864,6 +3916,7 @@ class SystemJobDetail(RetrieveDestroyAPIView): model = SystemJob serializer_class = SystemJobSerializer + new_in_210 = True class SystemJobCancel(RetrieveAPIView): @@ -3871,6 +3924,7 @@ class SystemJobCancel(RetrieveAPIView): model = SystemJob serializer_class = SystemJobCancelSerializer is_job_cancel = True + new_in_210 = True def post(self, request, *args, **kwargs): obj = self.get_object() @@ -3887,6 +3941,7 @@ class SystemJobNotificationsList(SubListAPIView): serializer_class = NotificationSerializer parent_model = SystemJob relationship = 'notifications' + new_in_300 = True class UnifiedJobTemplateList(ListAPIView): @@ -4009,6 +4064,7 @@ class UnifiedJobStdout(RetrieveAPIView): class ProjectUpdateStdout(UnifiedJobStdout): model = ProjectUpdate + new_in_13 = True class InventoryUpdateStdout(UnifiedJobStdout): @@ -4079,6 +4135,7 @@ class NotificationTemplateNotificationList(SubListAPIView): parent_model = NotificationTemplate relationship = 'notifications' parent_key = 'notification_template' + new_in_300 = True class NotificationList(ListAPIView): diff --git a/awx/conf/apps.py b/awx/conf/apps.py index 62ad0085df..6e09545236 100644 --- a/awx/conf/apps.py +++ b/awx/conf/apps.py @@ -16,7 +16,10 @@ class ConfConfig(AppConfig): from .settings import SettingsWrapper SettingsWrapper.initialize() if settings.LOG_AGGREGATOR_ENABLED: - LOGGING = settings.LOGGING - LOGGING['handlers']['http_receiver']['class'] = 'awx.main.utils.handlers.HTTPSHandler' - configure_logging(settings.LOGGING_CONFIG, LOGGING) + LOGGING_DICT = settings.LOGGING + LOGGING_DICT['handlers']['http_receiver']['class'] = 'awx.main.utils.handlers.HTTPSHandler' + if 'awx' in settings.LOG_AGGREGATOR_LOGGERS: + if 'http_receiver' not in LOGGING_DICT['loggers']['awx']['handlers']: + LOGGING_DICT['loggers']['awx']['handlers'] += ['http_receiver'] + configure_logging(settings.LOGGING_CONFIG, LOGGING_DICT) # checks.register(SettingsWrapper._check_settings) diff --git a/awx/conf/signals.py b/awx/conf/signals.py index 78411b1435..9d1813843e 100644 --- a/awx/conf/signals.py +++ b/awx/conf/signals.py @@ -13,7 +13,7 @@ import awx.main.signals from awx.conf import settings_registry from awx.conf.models import Setting from awx.conf.serializers import SettingSerializer -from awx.main.tasks import clear_cache_keys +from awx.main.tasks import process_cache_changes logger = logging.getLogger('awx.conf.signals') @@ -32,7 +32,7 @@ def handle_setting_change(key, for_delete=False): cache_keys = set([Setting.get_cache_key(k) for k in setting_keys]) logger.debug('sending signals to delete cache keys(%r)', cache_keys) cache.delete_many(cache_keys) - clear_cache_keys.delay(list(cache_keys)) + process_cache_changes.delay(list(cache_keys)) # Send setting_changed signal with new value for each setting. for setting_key in setting_keys: diff --git a/awx/lib/tower_display_callback/events.py b/awx/lib/tower_display_callback/events.py index 80265f21c6..a419b33e85 100644 --- a/awx/lib/tower_display_callback/events.py +++ b/awx/lib/tower_display_callback/events.py @@ -181,7 +181,7 @@ class EventContext(object): event_data['res'] = {} event_dict = dict(event=event, event_data=event_data) for key in event_data.keys(): - if key in ('job_id', 'ad_hoc_command_id', 'uuid', 'parent_uuid', 'created', 'artifact_data'): + if key in ('job_id', 'ad_hoc_command_id', 'uuid', 'parent_uuid', 'created',): event_dict[key] = event_data.pop(key) elif key in ('verbosity', 'pid'): event_dict[key] = event_data[key] diff --git a/awx/lib/tower_display_callback/module.py b/awx/lib/tower_display_callback/module.py index 59faa7ac79..02c5eee432 100644 --- a/awx/lib/tower_display_callback/module.py +++ b/awx/lib/tower_display_callback/module.py @@ -19,8 +19,6 @@ from __future__ import (absolute_import, division, print_function) # Python import contextlib -import copy -import re import sys import uuid @@ -77,45 +75,11 @@ class BaseCallbackModule(CallbackBase): super(BaseCallbackModule, self).__init__() self.task_uuids = set() - def censor_result(self, res, no_log=False): - if not isinstance(res, dict): - if no_log: - return "the output has been hidden due to the fact that 'no_log: true' was specified for this result" - return res - if res.get('_ansible_no_log', no_log): - new_res = {} - for k in self.CENSOR_FIELD_WHITELIST: - if k in res: - new_res[k] = res[k] - if k == 'cmd' and k in res: - if isinstance(res['cmd'], list): - res['cmd'] = ' '.join(res['cmd']) - if re.search(r'\s', res['cmd']): - new_res['cmd'] = re.sub(r'^(([^\s\\]|\\\s)+).*$', - r'\1 ', - res['cmd']) - new_res['censored'] = "the output has been hidden due to the fact that 'no_log: true' was specified for this result" - res = new_res - if 'results' in res: - if isinstance(res['results'], list): - for i in xrange(len(res['results'])): - res['results'][i] = self.censor_result(res['results'][i], res.get('_ansible_no_log', no_log)) - elif res.get('_ansible_no_log', False): - res['results'] = "the output has been hidden due to the fact that 'no_log: true' was specified for this result" - return res - @contextlib.contextmanager def capture_event_data(self, event, **event_data): event_data.setdefault('uuid', str(uuid.uuid4())) - if 'res' in event_data: - event_data['res'] = self.censor_result(copy.copy(event_data['res'])) - res = event_data.get('res', None) - if res and isinstance(res, dict): - if 'artifact_data' in res: - event_data['artifact_data'] = res['artifact_data'] - if event not in self.EVENTS_WITHOUT_TASK: task = event_data.pop('task', None) else: @@ -262,7 +226,7 @@ class BaseCallbackModule(CallbackBase): if task_uuid in self.task_uuids: # FIXME: When this task UUID repeats, it means the play is using the # free strategy, so different hosts may be running different tasks - # within a play. + # within a play. return self.task_uuids.add(task_uuid) self.set_task(task) @@ -319,6 +283,9 @@ class BaseCallbackModule(CallbackBase): with self.capture_event_data('playbook_on_notify', **event_data): super(BaseCallbackModule, self).v2_playbook_on_notify(result, handler) + ''' + ansible_stats is, retoractively, added in 2.2 + ''' def v2_playbook_on_stats(self, stats): self.clear_play() # FIXME: Add count of plays/tasks. @@ -329,7 +296,9 @@ class BaseCallbackModule(CallbackBase): ok=stats.ok, processed=stats.processed, skipped=stats.skipped, + artifact_data=stats.custom.get('_run', {}) if hasattr(stats, 'custom') else {} ) + with self.capture_event_data('playbook_on_stats', **event_data): super(BaseCallbackModule, self).v2_playbook_on_stats(stats) diff --git a/awx/locale/en-us/LC_MESSAGES/django.mo b/awx/locale/en-us/LC_MESSAGES/django.mo new file mode 100644 index 0000000000..927001688e Binary files /dev/null and b/awx/locale/en-us/LC_MESSAGES/django.mo differ diff --git a/awx/locale/en-us/LC_MESSAGES/django.po b/awx/locale/en-us/LC_MESSAGES/django.po new file mode 100644 index 0000000000..99aef1ef20 --- /dev/null +++ b/awx/locale/en-us/LC_MESSAGES/django.po @@ -0,0 +1,3637 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-12-14 21:27+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: api/authentication.py:67 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: api/authentication.py:70 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: api/authentication.py:105 +msgid "User inactive or deleted" +msgstr "" + +#: api/authentication.py:161 +msgid "Invalid task token" +msgstr "" + +#: api/conf.py:12 +msgid "Idle Time Force Log Out" +msgstr "" + +#: api/conf.py:13 +msgid "" +"Number of seconds that a user is inactive before they will need to login " +"again." +msgstr "" + +#: api/conf.py:14 api/conf.py:24 api/conf.py:33 sso/conf.py:124 +#: sso/conf.py:135 sso/conf.py:147 sso/conf.py:162 +msgid "Authentication" +msgstr "" + +#: api/conf.py:22 +msgid "Maximum number of simultaneous logins" +msgstr "" + +#: api/conf.py:23 +msgid "" +"Maximum number of simultaneous logins a user may have. To disable enter -1." +msgstr "" + +#: api/conf.py:31 +msgid "Enable HTTP Basic Auth" +msgstr "" + +#: api/conf.py:32 +msgid "Enable HTTP Basic Auth for the API Browser." +msgstr "" + +#: api/generics.py:446 +msgid "\"id\" is required to disassociate" +msgstr "" + +#: api/metadata.py:50 +msgid "Database ID for this {}." +msgstr "" + +#: api/metadata.py:51 +msgid "Name of this {}." +msgstr "" + +#: api/metadata.py:52 +msgid "Optional description of this {}." +msgstr "" + +#: api/metadata.py:53 +msgid "Data type for this {}." +msgstr "" + +#: api/metadata.py:54 +msgid "URL for this {}." +msgstr "" + +#: api/metadata.py:55 +msgid "Data structure with URLs of related resources." +msgstr "" + +#: api/metadata.py:56 +msgid "Data structure with name/description for related resources." +msgstr "" + +#: api/metadata.py:57 +msgid "Timestamp when this {} was created." +msgstr "" + +#: api/metadata.py:58 +msgid "Timestamp when this {} was last modified." +msgstr "" + +#: api/parsers.py:31 +#, python-format +msgid "JSON parse error - %s" +msgstr "" + +#: api/serializers.py:248 +msgid "Playbook Run" +msgstr "" + +#: api/serializers.py:249 +msgid "Command" +msgstr "" + +#: api/serializers.py:250 +msgid "SCM Update" +msgstr "" + +#: api/serializers.py:251 +msgid "Inventory Sync" +msgstr "" + +#: api/serializers.py:252 +msgid "Management Job" +msgstr "" + +#: api/serializers.py:253 +msgid "Workflow Job" +msgstr "" + +#: api/serializers.py:655 api/serializers.py:713 api/views.py:3914 +#, python-format +msgid "" +"Standard Output too large to display (%(text_size)d bytes), only download " +"supported for sizes over %(supported_size)d bytes" +msgstr "" + +#: api/serializers.py:728 +msgid "Write-only field used to change the password." +msgstr "" + +#: api/serializers.py:730 +msgid "Set if the account is managed by an external service" +msgstr "" + +#: api/serializers.py:754 +msgid "Password required for new User." +msgstr "" + +#: api/serializers.py:838 +#, python-format +msgid "Unable to change %s on user managed by LDAP." +msgstr "" + +#: api/serializers.py:990 +msgid "Organization is missing" +msgstr "" + +#: api/serializers.py:996 +msgid "Array of playbooks available within this project." +msgstr "" + +#: api/serializers.py:1178 +#, python-format +msgid "Invalid port specification: %s" +msgstr "" + +#: api/serializers.py:1206 main/validators.py:192 +msgid "Must be valid JSON or YAML." +msgstr "" + +#: api/serializers.py:1263 +msgid "Invalid group name." +msgstr "" + +#: api/serializers.py:1338 +msgid "" +"Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python" +msgstr "" + +#: api/serializers.py:1391 +msgid "If 'source' is 'custom', 'source_script' must be provided." +msgstr "" + +#: api/serializers.py:1395 +msgid "" +"The 'source_script' does not belong to the same organization as the " +"inventory." +msgstr "" + +#: api/serializers.py:1397 +msgid "'source_script' doesn't exist." +msgstr "" + +#: api/serializers.py:1756 +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 "" + +#: api/serializers.py:1761 +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 "" + +#: api/serializers.py:1766 +msgid "" +"Inherit permissions from organization roles. If provided on creation, do not " +"give either user or team." +msgstr "" + +#: api/serializers.py:1782 +msgid "Missing 'user', 'team', or 'organization'." +msgstr "" + +#: api/serializers.py:1795 +msgid "" +"Credential organization must be set and match before assigning to a team" +msgstr "" + +#: api/serializers.py:1887 +msgid "This field is required." +msgstr "" + +#: api/serializers.py:1889 api/serializers.py:1891 +msgid "Playbook not found for project." +msgstr "" + +#: api/serializers.py:1893 +msgid "Must select playbook for project." +msgstr "" + +#: api/serializers.py:1957 main/models/jobs.py:280 +msgid "Scan jobs must be assigned a fixed inventory." +msgstr "" + +#: api/serializers.py:1959 main/models/jobs.py:283 +msgid "Job types 'run' and 'check' must have assigned a project." +msgstr "" + +#: api/serializers.py:1962 +msgid "Survey Enabled cannot be used with scan jobs." +msgstr "" + +#: api/serializers.py:2024 +msgid "Invalid job template." +msgstr "" + +#: api/serializers.py:2109 +msgid "Credential not found or deleted." +msgstr "" + +#: api/serializers.py:2111 +msgid "Job Template Project is missing or undefined." +msgstr "" + +#: api/serializers.py:2113 +msgid "Job Template Inventory is missing or undefined." +msgstr "" + +#: api/serializers.py:2398 +#, python-format +msgid "%(job_type)s is not a valid job type. The choices are %(choices)s." +msgstr "" + +#: api/serializers.py:2403 +msgid "Workflow job template is missing during creation." +msgstr "" + +#: api/serializers.py:2408 +#, python-format +msgid "Cannot nest a %s inside a WorkflowJobTemplate" +msgstr "" + +#: api/serializers.py:2646 +#, python-format +msgid "Job Template '%s' is missing or undefined." +msgstr "" + +#: api/serializers.py:2672 +msgid "Must be a valid JSON or YAML dictionary." +msgstr "" + +#: api/serializers.py:2817 +msgid "" +"Missing required fields for Notification Configuration: notification_type" +msgstr "" + +#: api/serializers.py:2840 +msgid "No values specified for field '{}'" +msgstr "" + +#: api/serializers.py:2845 +msgid "Missing required fields for Notification Configuration: {}." +msgstr "" + +#: api/serializers.py:2848 +msgid "Configuration field '{}' incorrect type, expected {}." +msgstr "" + +#: api/serializers.py:2901 +msgid "Inventory Source must be a cloud resource." +msgstr "" + +#: api/serializers.py:2903 +msgid "Manual Project can not have a schedule set." +msgstr "" + +#: api/serializers.py:2925 +msgid "DTSTART required in rrule. Value should match: DTSTART:YYYYMMDDTHHMMSSZ" +msgstr "" + +#: api/serializers.py:2927 +msgid "Multiple DTSTART is not supported." +msgstr "" + +#: api/serializers.py:2929 +msgid "RRULE require in rrule." +msgstr "" + +#: api/serializers.py:2931 +msgid "Multiple RRULE is not supported." +msgstr "" + +#: api/serializers.py:2933 +msgid "INTERVAL required in rrule." +msgstr "" + +#: api/serializers.py:2935 +msgid "TZID is not supported." +msgstr "" + +#: api/serializers.py:2937 +msgid "SECONDLY is not supported." +msgstr "" + +#: api/serializers.py:2939 +msgid "Multiple BYMONTHDAYs not supported." +msgstr "" + +#: api/serializers.py:2941 +msgid "Multiple BYMONTHs not supported." +msgstr "" + +#: api/serializers.py:2943 +msgid "BYDAY with numeric prefix not supported." +msgstr "" + +#: api/serializers.py:2945 +msgid "BYYEARDAY not supported." +msgstr "" + +#: api/serializers.py:2947 +msgid "BYWEEKNO not supported." +msgstr "" + +#: api/serializers.py:2951 +msgid "COUNT > 999 is unsupported." +msgstr "" + +#: api/serializers.py:2955 +msgid "rrule parsing failed validation." +msgstr "" + +#: api/serializers.py:2973 +msgid "" +"A summary of the new and changed values when an object is created, updated, " +"or deleted" +msgstr "" + +#: api/serializers.py:2975 +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 "" + +#: api/serializers.py:2978 +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 "" + +#: api/serializers.py:2981 +msgid "The action taken with respect to the given object(s)." +msgstr "" + +#: api/serializers.py:3081 +msgid "Unable to login with provided credentials." +msgstr "" + +#: api/serializers.py:3083 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: api/views.py:96 +msgid "Your license does not allow use of the activity stream." +msgstr "" + +#: api/views.py:106 +msgid "Your license does not permit use of system tracking." +msgstr "" + +#: api/views.py:116 +msgid "Your license does not allow use of workflows." +msgstr "" + +#: api/views.py:124 templates/rest_framework/api.html:28 +msgid "REST API" +msgstr "" + +#: api/views.py:131 templates/rest_framework/api.html:4 +msgid "Ansible Tower REST API" +msgstr "" + +#: api/views.py:147 +msgid "Version 1" +msgstr "" + +#: api/views.py:198 +msgid "Ping" +msgstr "" + +#: api/views.py:227 conf/apps.py:12 +msgid "Configuration" +msgstr "" + +#: api/views.py:280 +msgid "Invalid license data" +msgstr "" + +#: api/views.py:282 +msgid "Missing 'eula_accepted' property" +msgstr "" + +#: api/views.py:286 +msgid "'eula_accepted' value is invalid" +msgstr "" + +#: api/views.py:289 +msgid "'eula_accepted' must be True" +msgstr "" + +#: api/views.py:296 +msgid "Invalid JSON" +msgstr "" + +#: api/views.py:304 +msgid "Invalid License" +msgstr "" + +#: api/views.py:314 +msgid "Invalid license" +msgstr "" + +#: api/views.py:322 +#, python-format +msgid "Failed to remove license (%s)" +msgstr "" + +#: api/views.py:327 +msgid "Dashboard" +msgstr "" + +#: api/views.py:433 +msgid "Dashboard Jobs Graphs" +msgstr "" + +#: api/views.py:469 +#, python-format +msgid "Unknown period \"%s\"" +msgstr "" + +#: api/views.py:483 +msgid "Schedules" +msgstr "" + +#: api/views.py:502 +msgid "Schedule Jobs List" +msgstr "" + +#: api/views.py:711 +msgid "Your Tower license only permits a single organization to exist." +msgstr "" + +#: api/views.py:932 api/views.py:1284 +msgid "Role 'id' field is missing." +msgstr "" + +#: api/views.py:938 api/views.py:4182 +msgid "You cannot assign an Organization role as a child role for a Team." +msgstr "" + +#: api/views.py:942 api/views.py:4196 +msgid "You cannot grant system-level permissions to a team." +msgstr "" + +#: api/views.py:949 api/views.py:4188 +msgid "" +"You cannot grant credential access to a team when the Organization field " +"isn't set, or belongs to a different organization" +msgstr "" + +#: api/views.py:1039 +msgid "Cannot delete project." +msgstr "" + +#: api/views.py:1068 +msgid "Project Schedules" +msgstr "" + +#: api/views.py:1168 api/views.py:2252 api/views.py:3225 +msgid "Cannot delete job resource when associated workflow job is running." +msgstr "" + +#: api/views.py:1244 +msgid "Me" +msgstr "" + +#: api/views.py:1288 api/views.py:4137 +msgid "You may not perform any action with your own admin_role." +msgstr "" + +#: api/views.py:1294 api/views.py:4141 +msgid "You may not change the membership of a users admin_role" +msgstr "" + +#: api/views.py:1299 api/views.py:4146 +msgid "" +"You cannot grant credential access to a user not in the credentials' " +"organization" +msgstr "" + +#: api/views.py:1303 api/views.py:4150 +msgid "You cannot grant private credential access to another user" +msgstr "" + +#: api/views.py:1401 +#, python-format +msgid "Cannot change %s." +msgstr "" + +#: api/views.py:1407 +msgid "Cannot delete user." +msgstr "" + +#: api/views.py:1553 +msgid "Cannot delete inventory script." +msgstr "" + +#: api/views.py:1788 +msgid "Fact not found." +msgstr "" + +#: api/views.py:2108 +msgid "Inventory Source List" +msgstr "" + +#: api/views.py:2136 +msgid "Cannot delete inventory source." +msgstr "" + +#: api/views.py:2144 +msgid "Inventory Source Schedules" +msgstr "" + +#: api/views.py:2173 +msgid "Notification Templates can only be assigned when source is one of {}." +msgstr "" + +#: api/views.py:2380 +msgid "Job Template Schedules" +msgstr "" + +#: api/views.py:2399 api/views.py:2409 +msgid "Your license does not allow adding surveys." +msgstr "" + +#: api/views.py:2416 +msgid "'name' missing from survey spec." +msgstr "" + +#: api/views.py:2418 +msgid "'description' missing from survey spec." +msgstr "" + +#: api/views.py:2420 +msgid "'spec' missing from survey spec." +msgstr "" + +#: api/views.py:2422 +msgid "'spec' must be a list of items." +msgstr "" + +#: api/views.py:2424 +msgid "'spec' doesn't contain any items." +msgstr "" + +#: api/views.py:2429 +#, python-format +msgid "Survey question %s is not a json object." +msgstr "" + +#: api/views.py:2431 +#, python-format +msgid "'type' missing from survey question %s." +msgstr "" + +#: api/views.py:2433 +#, python-format +msgid "'question_name' missing from survey question %s." +msgstr "" + +#: api/views.py:2435 +#, python-format +msgid "'variable' missing from survey question %s." +msgstr "" + +#: api/views.py:2437 +#, python-format +msgid "'variable' '%(item)s' duplicated in survey question %(survey)s." +msgstr "" + +#: api/views.py:2442 +#, python-format +msgid "'required' missing from survey question %s." +msgstr "" + +#: api/views.py:2641 +msgid "No matching host could be found!" +msgstr "" + +#: api/views.py:2644 +msgid "Multiple hosts matched the request!" +msgstr "" + +#: api/views.py:2649 +msgid "Cannot start automatically, user input required!" +msgstr "" + +#: api/views.py:2656 +msgid "Host callback job already pending." +msgstr "" + +#: api/views.py:2669 +msgid "Error starting job!" +msgstr "" + +#: api/views.py:2995 +msgid "Workflow Job Template Schedules" +msgstr "" + +#: api/views.py:3131 api/views.py:3853 +msgid "Superuser privileges needed." +msgstr "" + +#: api/views.py:3161 +msgid "System Job Template Schedules" +msgstr "" + +#: api/views.py:3344 +msgid "Job Host Summaries List" +msgstr "" + +#: api/views.py:3386 +msgid "Job Event Children List" +msgstr "" + +#: api/views.py:3395 +msgid "Job Event Hosts List" +msgstr "" + +#: api/views.py:3404 +msgid "Job Events List" +msgstr "" + +#: api/views.py:3436 +msgid "Job Plays List" +msgstr "" + +#: api/views.py:3513 +msgid "Job Play Tasks List" +msgstr "" + +#: api/views.py:3529 +msgid "Job not found." +msgstr "" + +#: api/views.py:3533 +msgid "'event_id' not provided." +msgstr "" + +#: api/views.py:3537 +msgid "Parent event not found." +msgstr "" + +#: api/views.py:3809 +msgid "Ad Hoc Command Events List" +msgstr "" + +#: api/views.py:3963 +#, python-format +msgid "Error generating stdout download file: %s" +msgstr "" + +#: api/views.py:4009 +msgid "Delete not allowed while there are pending notifications" +msgstr "" + +#: api/views.py:4016 +msgid "NotificationTemplate Test" +msgstr "" + +#: api/views.py:4131 +msgid "User 'id' field is missing." +msgstr "" + +#: api/views.py:4174 +msgid "Team 'id' field is missing." +msgstr "" + +#: conf/conf.py:20 +msgid "Bud Frogs" +msgstr "" + +#: conf/conf.py:21 +msgid "Bunny" +msgstr "" + +#: conf/conf.py:22 +msgid "Cheese" +msgstr "" + +#: conf/conf.py:23 +msgid "Daemon" +msgstr "" + +#: conf/conf.py:24 +msgid "Default Cow" +msgstr "" + +#: conf/conf.py:25 +msgid "Dragon" +msgstr "" + +#: conf/conf.py:26 +msgid "Elephant in Snake" +msgstr "" + +#: conf/conf.py:27 +msgid "Elephant" +msgstr "" + +#: conf/conf.py:28 +msgid "Eyes" +msgstr "" + +#: conf/conf.py:29 +msgid "Hello Kitty" +msgstr "" + +#: conf/conf.py:30 +msgid "Kitty" +msgstr "" + +#: conf/conf.py:31 +msgid "Luke Koala" +msgstr "" + +#: conf/conf.py:32 +msgid "Meow" +msgstr "" + +#: conf/conf.py:33 +msgid "Milk" +msgstr "" + +#: conf/conf.py:34 +msgid "Moofasa" +msgstr "" + +#: conf/conf.py:35 +msgid "Moose" +msgstr "" + +#: conf/conf.py:36 +msgid "Ren" +msgstr "" + +#: conf/conf.py:37 +msgid "Sheep" +msgstr "" + +#: conf/conf.py:38 +msgid "Small Cow" +msgstr "" + +#: conf/conf.py:39 +msgid "Stegosaurus" +msgstr "" + +#: conf/conf.py:40 +msgid "Stimpy" +msgstr "" + +#: conf/conf.py:41 +msgid "Super Milker" +msgstr "" + +#: conf/conf.py:42 +msgid "Three Eyes" +msgstr "" + +#: conf/conf.py:43 +msgid "Turkey" +msgstr "" + +#: conf/conf.py:44 +msgid "Turtle" +msgstr "" + +#: conf/conf.py:45 +msgid "Tux" +msgstr "" + +#: conf/conf.py:46 +msgid "Udder" +msgstr "" + +#: conf/conf.py:47 +msgid "Vader Koala" +msgstr "" + +#: conf/conf.py:48 +msgid "Vader" +msgstr "" + +#: conf/conf.py:49 +msgid "WWW" +msgstr "" + +#: conf/conf.py:52 +msgid "Cow Selection" +msgstr "" + +#: conf/conf.py:53 +msgid "Select which cow to use with cowsay when running jobs." +msgstr "" + +#: conf/conf.py:54 conf/conf.py:75 +msgid "Cows" +msgstr "" + +#: conf/conf.py:73 +msgid "Example Read-Only Setting" +msgstr "" + +#: conf/conf.py:74 +msgid "Example setting that cannot be changed." +msgstr "" + +#: conf/conf.py:93 +msgid "Example Setting" +msgstr "" + +#: conf/conf.py:94 +msgid "Example setting which can be different for each user." +msgstr "" + +#: conf/conf.py:95 conf/registry.py:67 conf/views.py:46 +msgid "User" +msgstr "" + +#: conf/fields.py:38 +msgid "Enter a valid URL" +msgstr "" + +#: conf/license.py:19 +msgid "Your Tower license does not allow that." +msgstr "" + +#: conf/management/commands/migrate_to_database_settings.py:41 +msgid "Only show which settings would be commented/migrated." +msgstr "" + +#: conf/management/commands/migrate_to_database_settings.py:48 +msgid "Skip over settings that would raise an error when commenting/migrating." +msgstr "" + +#: conf/management/commands/migrate_to_database_settings.py:55 +msgid "Skip commenting out settings in files." +msgstr "" + +#: conf/management/commands/migrate_to_database_settings.py:61 +msgid "Backup existing settings files with this suffix." +msgstr "" + +#: conf/registry.py:55 +msgid "All" +msgstr "" + +#: conf/registry.py:56 +msgid "Changed" +msgstr "" + +#: conf/registry.py:68 +msgid "User-Defaults" +msgstr "" + +#: conf/views.py:38 +msgid "Setting Categories" +msgstr "" + +#: conf/views.py:61 +msgid "Setting Detail" +msgstr "" + +#: main/access.py:255 +#, python-format +msgid "Bad data found in related field %s." +msgstr "" + +#: main/access.py:296 +msgid "License is missing." +msgstr "" + +#: main/access.py:298 +msgid "License has expired." +msgstr "" + +#: main/access.py:303 +#, python-format +msgid "License count of %s instances has been reached." +msgstr "" + +#: main/access.py:305 +#, python-format +msgid "License count of %s instances has been exceeded." +msgstr "" + +#: main/access.py:307 +msgid "Host count exceeds available instances." +msgstr "" + +#: main/access.py:311 +#, python-format +msgid "Feature %s is not enabled in the active license." +msgstr "" + +#: main/access.py:313 +msgid "Features not found in active license." +msgstr "" + +#: main/access.py:507 main/access.py:574 main/access.py:694 main/access.py:957 +#: main/access.py:1198 main/access.py:1587 +msgid "Resource is being used by running jobs" +msgstr "" + +#: main/access.py:618 +msgid "Unable to change inventory on a host." +msgstr "" + +#: main/access.py:630 main/access.py:675 +msgid "Cannot associate two items from different inventories." +msgstr "" + +#: main/access.py:663 +msgid "Unable to change inventory on a group." +msgstr "" + +#: main/access.py:877 +msgid "Unable to change organization on a team." +msgstr "" + +#: main/access.py:890 +msgid "The {} role cannot be assigned to a team" +msgstr "" + +#: main/access.py:892 +msgid "The admin_role for a User cannot be assigned to a team" +msgstr "" + +#: main/apps.py:9 +msgid "Main" +msgstr "" + +#: main/conf.py:17 +msgid "Enable Activity Stream" +msgstr "" + +#: main/conf.py:18 +msgid "Enable capturing activity for the Tower activity stream." +msgstr "" + +#: main/conf.py:19 main/conf.py:29 main/conf.py:39 main/conf.py:48 +#: main/conf.py:60 main/conf.py:78 main/conf.py:103 +msgid "System" +msgstr "" + +#: main/conf.py:27 +msgid "Enable Activity Stream for Inventory Sync" +msgstr "" + +#: main/conf.py:28 +msgid "" +"Enable capturing activity for the Tower activity stream when running " +"inventory sync." +msgstr "" + +#: main/conf.py:37 +msgid "All Users Visible to Organization Admins" +msgstr "" + +#: main/conf.py:38 +msgid "" +"Controls whether any Organization Admin can view all users, even those not " +"associated with their Organization." +msgstr "" + +#: main/conf.py:46 +msgid "Enable Tower Administrator Alerts" +msgstr "" + +#: main/conf.py:47 +msgid "" +"Allow Tower to email Admin users for system events that may require " +"attention." +msgstr "" + +#: main/conf.py:57 +msgid "Base URL of the Tower host" +msgstr "" + +#: main/conf.py:58 +msgid "" +"This setting is used by services like notifications to render a valid url to " +"the Tower host." +msgstr "" + +#: main/conf.py:67 +msgid "Remote Host Headers" +msgstr "" + +#: main/conf.py:68 +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 " +"behind a reverse proxy.\n" +"\n" +"Note: The headers will be searched in order and the first found remote host " +"name or IP will be used.\n" +"\n" +"In the below example 8.8.8.7 would be the chosen IP address.\n" +"X-Forwarded-For: 8.8.8.7, 192.168.2.1, 127.0.0.1\n" +"Host: 127.0.0.1\n" +"REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST']" +msgstr "" + +#: main/conf.py:99 +msgid "Tower License" +msgstr "" + +#: main/conf.py:100 +msgid "" +"The license controls which features and functionality are enabled in Tower. " +"Use /api/v1/config/ to update or change the license." +msgstr "" + +#: main/conf.py:110 +msgid "Ansible Modules Allowed for Ad Hoc Jobs" +msgstr "" + +#: main/conf.py:111 +msgid "List of modules allowed to be used by ad-hoc jobs." +msgstr "" + +#: main/conf.py:112 main/conf.py:121 main/conf.py:130 main/conf.py:139 +#: main/conf.py:148 main/conf.py:158 main/conf.py:168 main/conf.py:178 +#: main/conf.py:187 main/conf.py:199 main/conf.py:211 main/conf.py:223 +msgid "Jobs" +msgstr "" + +#: main/conf.py:119 +msgid "Enable job isolation" +msgstr "" + +#: main/conf.py:120 +msgid "" +"Isolates an Ansible job from protected parts of the Tower system to prevent " +"exposing sensitive information." +msgstr "" + +#: main/conf.py:128 +msgid "Job isolation execution path" +msgstr "" + +#: main/conf.py:129 +msgid "" +"Create temporary working directories for isolated jobs in this location." +msgstr "" + +#: main/conf.py:137 +msgid "Paths to hide from isolated jobs" +msgstr "" + +#: main/conf.py:138 +msgid "Additional paths to hide from isolated processes." +msgstr "" + +#: main/conf.py:146 +msgid "Paths to expose to isolated jobs" +msgstr "" + +#: main/conf.py:147 +msgid "" +"Whitelist of paths that would otherwise be hidden to expose to isolated jobs." +msgstr "" + +#: main/conf.py:156 +msgid "Standard Output Maximum Display Size" +msgstr "" + +#: main/conf.py:157 +msgid "" +"Maximum Size of Standard Output in bytes to display before requiring the " +"output be downloaded." +msgstr "" + +#: main/conf.py:166 +msgid "Job Event Standard Output Maximum Display Size" +msgstr "" + +#: main/conf.py:167 +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 "" + +#: main/conf.py:176 +msgid "Maximum Scheduled Jobs" +msgstr "" + +#: main/conf.py:177 +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 "" + +#: main/conf.py:185 +msgid "Ansible Callback Plugins" +msgstr "" + +#: main/conf.py:186 +msgid "" +"List of paths to search for extra callback plugins to be used when running " +"jobs." +msgstr "" + +#: main/conf.py:196 +msgid "Default Job Timeout" +msgstr "" + +#: main/conf.py:197 +msgid "" +"Maximum time 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 "" + +#: main/conf.py:208 +msgid "Default Inventory Update Timeout" +msgstr "" + +#: main/conf.py:209 +msgid "" +"Maximum time 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 "" + +#: main/conf.py:220 +msgid "Default Project Update Timeout" +msgstr "" + +#: main/conf.py:221 +msgid "" +"Maximum time 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 "" + +#: main/conf.py:231 +msgid "Logging Aggregator Receiving Host" +msgstr "" + +#: main/conf.py:232 +msgid "External host maintain a log collector to send logs to" +msgstr "" + +#: main/conf.py:233 main/conf.py:242 main/conf.py:252 main/conf.py:261 +#: main/conf.py:271 main/conf.py:286 main/conf.py:297 main/conf.py:306 +msgid "Logging" +msgstr "" + +#: main/conf.py:240 +msgid "Logging Aggregator Receiving Port" +msgstr "" + +#: main/conf.py:241 +msgid "Port that the log collector is listening on" +msgstr "" + +#: main/conf.py:250 +msgid "Logging Aggregator Type: Logstash, Loggly, Datadog, etc" +msgstr "" + +#: main/conf.py:251 +msgid "The type of log aggregator service to format messages for" +msgstr "" + +#: main/conf.py:259 +msgid "Logging Aggregator Username to Authenticate With" +msgstr "" + +#: main/conf.py:260 +msgid "Username for Logstash or others (basic auth)" +msgstr "" + +#: main/conf.py:269 +msgid "Logging Aggregator Password to Authenticate With" +msgstr "" + +#: main/conf.py:270 +msgid "Password for Logstash or others (basic auth)" +msgstr "" + +#: main/conf.py:278 +msgid "Loggers to send data to the log aggregator from" +msgstr "" + +#: main/conf.py:279 +msgid "" +"List of loggers that will send HTTP logs to the collector, these can include " +"any or all of: \n" +"activity_stream - logs duplicate to records entered in activity stream\n" +"job_events - callback data from Ansible job events\n" +"system_tracking - data generated from scan jobs\n" +"Sending generic Tower logs must be configured through local_settings." +"pyinstead of this mechanism." +msgstr "" + +#: main/conf.py:293 +msgid "" +"Flag denoting to send individual messages for each fact in system tracking" +msgstr "" + +#: main/conf.py:294 +msgid "" +"If not set, the data from system tracking will be sent inside of a single " +"dictionary, but if set, separate requests will be sent for each package, " +"service, etc. that is found in the scan." +msgstr "" + +#: main/conf.py:304 +msgid "Flag denoting whether to use the external logger system" +msgstr "" + +#: main/conf.py:305 +msgid "" +"If not set, only normal settings data will be used to configure loggers." +msgstr "" + +#: main/models/activity_stream.py:22 +msgid "Entity Created" +msgstr "" + +#: main/models/activity_stream.py:23 +msgid "Entity Updated" +msgstr "" + +#: main/models/activity_stream.py:24 +msgid "Entity Deleted" +msgstr "" + +#: main/models/activity_stream.py:25 +msgid "Entity Associated with another Entity" +msgstr "" + +#: main/models/activity_stream.py:26 +msgid "Entity was Disassociated with another Entity" +msgstr "" + +#: main/models/ad_hoc_commands.py:96 +msgid "No valid inventory." +msgstr "" + +#: main/models/ad_hoc_commands.py:103 main/models/jobs.py:163 +msgid "You must provide a machine / SSH credential." +msgstr "" + +#: main/models/ad_hoc_commands.py:114 main/models/ad_hoc_commands.py:122 +msgid "Invalid type for ad hoc command" +msgstr "" + +#: main/models/ad_hoc_commands.py:117 +msgid "Unsupported module for ad hoc commands." +msgstr "" + +#: main/models/ad_hoc_commands.py:125 +#, python-format +msgid "No argument passed to %s module." +msgstr "" + +#: main/models/ad_hoc_commands.py:220 main/models/jobs.py:767 +msgid "Host Failed" +msgstr "" + +#: main/models/ad_hoc_commands.py:221 main/models/jobs.py:768 +msgid "Host OK" +msgstr "" + +#: main/models/ad_hoc_commands.py:222 main/models/jobs.py:771 +msgid "Host Unreachable" +msgstr "" + +#: main/models/ad_hoc_commands.py:227 main/models/jobs.py:770 +msgid "Host Skipped" +msgstr "" + +#: main/models/ad_hoc_commands.py:237 main/models/jobs.py:798 +msgid "Debug" +msgstr "" + +#: main/models/ad_hoc_commands.py:238 main/models/jobs.py:799 +msgid "Verbose" +msgstr "" + +#: main/models/ad_hoc_commands.py:239 main/models/jobs.py:800 +msgid "Deprecated" +msgstr "" + +#: main/models/ad_hoc_commands.py:240 main/models/jobs.py:801 +msgid "Warning" +msgstr "" + +#: main/models/ad_hoc_commands.py:241 main/models/jobs.py:802 +msgid "System Warning" +msgstr "" + +#: main/models/ad_hoc_commands.py:242 main/models/jobs.py:803 +#: main/models/unified_jobs.py:62 +msgid "Error" +msgstr "" + +#: main/models/base.py:45 main/models/base.py:51 main/models/base.py:56 +msgid "Run" +msgstr "" + +#: main/models/base.py:46 main/models/base.py:52 main/models/base.py:57 +msgid "Check" +msgstr "" + +#: main/models/base.py:47 +msgid "Scan" +msgstr "" + +#: main/models/base.py:61 +msgid "Read Inventory" +msgstr "" + +#: main/models/base.py:62 +msgid "Edit Inventory" +msgstr "" + +#: main/models/base.py:63 +msgid "Administrate Inventory" +msgstr "" + +#: main/models/base.py:64 +msgid "Deploy To Inventory" +msgstr "" + +#: main/models/base.py:65 +msgid "Deploy To Inventory (Dry Run)" +msgstr "" + +#: main/models/base.py:66 +msgid "Scan an Inventory" +msgstr "" + +#: main/models/base.py:67 +msgid "Create a Job Template" +msgstr "" + +#: main/models/credential.py:33 +msgid "Machine" +msgstr "" + +#: main/models/credential.py:34 +msgid "Network" +msgstr "" + +#: main/models/credential.py:35 +msgid "Source Control" +msgstr "" + +#: main/models/credential.py:36 +msgid "Amazon Web Services" +msgstr "" + +#: main/models/credential.py:37 +msgid "Rackspace" +msgstr "" + +#: main/models/credential.py:38 main/models/inventory.py:713 +msgid "VMware vCenter" +msgstr "" + +#: main/models/credential.py:39 main/models/inventory.py:714 +msgid "Red Hat Satellite 6" +msgstr "" + +#: main/models/credential.py:40 main/models/inventory.py:715 +msgid "Red Hat CloudForms" +msgstr "" + +#: main/models/credential.py:41 main/models/inventory.py:710 +msgid "Google Compute Engine" +msgstr "" + +#: main/models/credential.py:42 main/models/inventory.py:711 +msgid "Microsoft Azure Classic (deprecated)" +msgstr "" + +#: main/models/credential.py:43 main/models/inventory.py:712 +msgid "Microsoft Azure Resource Manager" +msgstr "" + +#: main/models/credential.py:44 main/models/inventory.py:716 +msgid "OpenStack" +msgstr "" + +#: main/models/credential.py:48 +msgid "None" +msgstr "" + +#: main/models/credential.py:49 +msgid "Sudo" +msgstr "" + +#: main/models/credential.py:50 +msgid "Su" +msgstr "" + +#: main/models/credential.py:51 +msgid "Pbrun" +msgstr "" + +#: main/models/credential.py:52 +msgid "Pfexec" +msgstr "" + +#: main/models/credential.py:101 +msgid "Host" +msgstr "" + +#: main/models/credential.py:102 +msgid "The hostname or IP address to use." +msgstr "" + +#: main/models/credential.py:108 +msgid "Username" +msgstr "" + +#: main/models/credential.py:109 +msgid "Username for this credential." +msgstr "" + +#: main/models/credential.py:115 +msgid "Password" +msgstr "" + +#: main/models/credential.py:116 +msgid "" +"Password for this credential (or \"ASK\" to prompt the user for machine " +"credentials)." +msgstr "" + +#: main/models/credential.py:123 +msgid "Security Token" +msgstr "" + +#: main/models/credential.py:124 +msgid "Security Token for this credential" +msgstr "" + +#: main/models/credential.py:130 +msgid "Project" +msgstr "" + +#: main/models/credential.py:131 +msgid "The identifier for the project." +msgstr "" + +#: main/models/credential.py:137 +msgid "Domain" +msgstr "" + +#: main/models/credential.py:138 +msgid "The identifier for the domain." +msgstr "" + +#: main/models/credential.py:143 +msgid "SSH private key" +msgstr "" + +#: main/models/credential.py:144 +msgid "RSA or DSA private key to be used instead of password." +msgstr "" + +#: main/models/credential.py:150 +msgid "SSH key unlock" +msgstr "" + +#: main/models/credential.py:151 +msgid "" +"Passphrase to unlock SSH private key if encrypted (or \"ASK\" to prompt the " +"user for machine credentials)." +msgstr "" + +#: main/models/credential.py:159 +msgid "Privilege escalation method." +msgstr "" + +#: main/models/credential.py:165 +msgid "Privilege escalation username." +msgstr "" + +#: main/models/credential.py:171 +msgid "Password for privilege escalation method." +msgstr "" + +#: main/models/credential.py:177 +msgid "Vault password (or \"ASK\" to prompt the user)." +msgstr "" + +#: main/models/credential.py:181 +msgid "Whether to use the authorize mechanism." +msgstr "" + +#: main/models/credential.py:187 +msgid "Password used by the authorize mechanism." +msgstr "" + +#: main/models/credential.py:193 +msgid "Client Id or Application Id for the credential" +msgstr "" + +#: main/models/credential.py:199 +msgid "Secret Token for this credential" +msgstr "" + +#: main/models/credential.py:205 +msgid "Subscription identifier for this credential" +msgstr "" + +#: main/models/credential.py:211 +msgid "Tenant identifier for this credential" +msgstr "" + +#: main/models/credential.py:281 +msgid "Host required for VMware credential." +msgstr "" + +#: main/models/credential.py:283 +msgid "Host required for OpenStack credential." +msgstr "" + +#: main/models/credential.py:292 +msgid "Access key required for AWS credential." +msgstr "" + +#: main/models/credential.py:294 +msgid "Username required for Rackspace credential." +msgstr "" + +#: main/models/credential.py:297 +msgid "Username required for VMware credential." +msgstr "" + +#: main/models/credential.py:299 +msgid "Username required for OpenStack credential." +msgstr "" + +#: main/models/credential.py:305 +msgid "Secret key required for AWS credential." +msgstr "" + +#: main/models/credential.py:307 +msgid "API key required for Rackspace credential." +msgstr "" + +#: main/models/credential.py:309 +msgid "Password required for VMware credential." +msgstr "" + +#: main/models/credential.py:311 +msgid "Password or API key required for OpenStack credential." +msgstr "" + +#: main/models/credential.py:317 +msgid "Project name required for OpenStack credential." +msgstr "" + +#: main/models/credential.py:344 +msgid "SSH key unlock must be set when SSH key is encrypted." +msgstr "" + +#: main/models/credential.py:350 +msgid "Credential cannot be assigned to both a user and team." +msgstr "" + +#: main/models/fact.py:21 +msgid "Host for the facts that the fact scan captured." +msgstr "" + +#: main/models/fact.py:26 +msgid "Date and time of the corresponding fact scan gathering time." +msgstr "" + +#: main/models/fact.py:29 +msgid "" +"Arbitrary JSON structure of module facts captured at timestamp for a single " +"host." +msgstr "" + +#: main/models/inventory.py:45 +msgid "inventories" +msgstr "" + +#: main/models/inventory.py:52 +msgid "Organization containing this inventory." +msgstr "" + +#: main/models/inventory.py:58 +msgid "Inventory variables in JSON or YAML format." +msgstr "" + +#: main/models/inventory.py:63 +msgid "Flag indicating whether any hosts in this inventory have failed." +msgstr "" + +#: main/models/inventory.py:68 +msgid "Total number of hosts in this inventory." +msgstr "" + +#: main/models/inventory.py:73 +msgid "Number of hosts in this inventory with active failures." +msgstr "" + +#: main/models/inventory.py:78 +msgid "Total number of groups in this inventory." +msgstr "" + +#: main/models/inventory.py:83 +msgid "Number of groups in this inventory with active failures." +msgstr "" + +#: main/models/inventory.py:88 +msgid "" +"Flag indicating whether this inventory has any external inventory sources." +msgstr "" + +#: main/models/inventory.py:93 +msgid "" +"Total number of external inventory sources configured within this inventory." +msgstr "" + +#: main/models/inventory.py:98 +msgid "Number of external inventory sources in this inventory with failures." +msgstr "" + +#: main/models/inventory.py:339 +msgid "Is this host online and available for running jobs?" +msgstr "" + +#: main/models/inventory.py:345 +msgid "" +"The value used by the remote inventory source to uniquely identify the host" +msgstr "" + +#: main/models/inventory.py:350 +msgid "Host variables in JSON or YAML format." +msgstr "" + +#: main/models/inventory.py:372 +msgid "Flag indicating whether the last job failed for this host." +msgstr "" + +#: main/models/inventory.py:377 +msgid "" +"Flag indicating whether this host was created/updated from any external " +"inventory sources." +msgstr "" + +#: main/models/inventory.py:383 +msgid "Inventory source(s) that created or modified this host." +msgstr "" + +#: main/models/inventory.py:474 +msgid "Group variables in JSON or YAML format." +msgstr "" + +#: main/models/inventory.py:480 +msgid "Hosts associated directly with this group." +msgstr "" + +#: main/models/inventory.py:485 +msgid "Total number of hosts directly or indirectly in this group." +msgstr "" + +#: main/models/inventory.py:490 +msgid "Flag indicating whether this group has any hosts with active failures." +msgstr "" + +#: main/models/inventory.py:495 +msgid "Number of hosts in this group with active failures." +msgstr "" + +#: main/models/inventory.py:500 +msgid "Total number of child groups contained within this group." +msgstr "" + +#: main/models/inventory.py:505 +msgid "Number of child groups within this group that have active failures." +msgstr "" + +#: main/models/inventory.py:510 +msgid "" +"Flag indicating whether this group was created/updated from any external " +"inventory sources." +msgstr "" + +#: main/models/inventory.py:516 +msgid "Inventory source(s) that created or modified this group." +msgstr "" + +#: main/models/inventory.py:706 main/models/projects.py:42 +#: main/models/unified_jobs.py:386 +msgid "Manual" +msgstr "" + +#: main/models/inventory.py:707 +msgid "Local File, Directory or Script" +msgstr "" + +#: main/models/inventory.py:708 +msgid "Rackspace Cloud Servers" +msgstr "" + +#: main/models/inventory.py:709 +msgid "Amazon EC2" +msgstr "" + +#: main/models/inventory.py:717 +msgid "Custom Script" +msgstr "" + +#: main/models/inventory.py:828 +msgid "Inventory source variables in YAML or JSON format." +msgstr "" + +#: main/models/inventory.py:847 +msgid "" +"Comma-separated list of filter expressions (EC2 only). Hosts are imported " +"when ANY of the filters match." +msgstr "" + +#: main/models/inventory.py:853 +msgid "Limit groups automatically created from inventory source (EC2 only)." +msgstr "" + +#: main/models/inventory.py:857 +msgid "Overwrite local groups and hosts from remote inventory source." +msgstr "" + +#: main/models/inventory.py:861 +msgid "Overwrite local variables from remote inventory source." +msgstr "" + +#: main/models/inventory.py:893 +msgid "Availability Zone" +msgstr "" + +#: main/models/inventory.py:894 +msgid "Image ID" +msgstr "" + +#: main/models/inventory.py:895 +msgid "Instance ID" +msgstr "" + +#: main/models/inventory.py:896 +msgid "Instance Type" +msgstr "" + +#: main/models/inventory.py:897 +msgid "Key Name" +msgstr "" + +#: main/models/inventory.py:898 +msgid "Region" +msgstr "" + +#: main/models/inventory.py:899 +msgid "Security Group" +msgstr "" + +#: main/models/inventory.py:900 +msgid "Tags" +msgstr "" + +#: main/models/inventory.py:901 +msgid "VPC ID" +msgstr "" + +#: main/models/inventory.py:902 +msgid "Tag None" +msgstr "" + +#: main/models/inventory.py:973 +#, python-format +msgid "" +"Cloud-based inventory sources (such as %s) require credentials for the " +"matching cloud service." +msgstr "" + +#: main/models/inventory.py:980 +msgid "Credential is required for a cloud source." +msgstr "" + +#: main/models/inventory.py:1005 +#, python-format +msgid "Invalid %(source)s region%(plural)s: %(region)s" +msgstr "" + +#: main/models/inventory.py:1031 +#, python-format +msgid "Invalid filter expression%(plural)s: %(filter)s" +msgstr "" + +#: main/models/inventory.py:1050 +#, python-format +msgid "Invalid group by choice%(plural)s: %(choice)s" +msgstr "" + +#: main/models/inventory.py:1198 +#, python-format +msgid "" +"Unable to configure this item for cloud sync. It is already managed by %s." +msgstr "" + +#: main/models/inventory.py:1293 +msgid "Inventory script contents" +msgstr "" + +#: main/models/inventory.py:1298 +msgid "Organization owning this inventory script" +msgstr "" + +#: main/models/jobs.py:171 +msgid "You must provide a network credential." +msgstr "" + +#: main/models/jobs.py:179 +msgid "" +"Must provide a credential for a cloud provider, such as Amazon Web Services " +"or Rackspace." +msgstr "" + +#: main/models/jobs.py:271 +msgid "Job Template must provide 'inventory' or allow prompting for it." +msgstr "" + +#: main/models/jobs.py:275 +msgid "Job Template must provide 'credential' or allow prompting for it." +msgstr "" + +#: main/models/jobs.py:364 +msgid "Cannot override job_type to or from a scan job." +msgstr "" + +#: main/models/jobs.py:367 +msgid "Inventory cannot be changed at runtime for scan jobs." +msgstr "" + +#: main/models/jobs.py:433 main/models/projects.py:243 +msgid "SCM Revision" +msgstr "" + +#: main/models/jobs.py:434 +msgid "The SCM Revision from the Project used for this job, if available" +msgstr "" + +#: main/models/jobs.py:442 +msgid "" +"The SCM Refresh task used to make sure the playbooks were available for the " +"job run" +msgstr "" + +#: main/models/jobs.py:666 +msgid "job host summaries" +msgstr "" + +#: main/models/jobs.py:769 +msgid "Host Failure" +msgstr "" + +#: main/models/jobs.py:772 main/models/jobs.py:786 +msgid "No Hosts Remaining" +msgstr "" + +#: main/models/jobs.py:773 +msgid "Host Polling" +msgstr "" + +#: main/models/jobs.py:774 +msgid "Host Async OK" +msgstr "" + +#: main/models/jobs.py:775 +msgid "Host Async Failure" +msgstr "" + +#: main/models/jobs.py:776 +msgid "Item OK" +msgstr "" + +#: main/models/jobs.py:777 +msgid "Item Failed" +msgstr "" + +#: main/models/jobs.py:778 +msgid "Item Skipped" +msgstr "" + +#: main/models/jobs.py:779 +msgid "Host Retry" +msgstr "" + +#: main/models/jobs.py:781 +msgid "File Difference" +msgstr "" + +#: main/models/jobs.py:782 +msgid "Playbook Started" +msgstr "" + +#: main/models/jobs.py:783 +msgid "Running Handlers" +msgstr "" + +#: main/models/jobs.py:784 +msgid "Including File" +msgstr "" + +#: main/models/jobs.py:785 +msgid "No Hosts Matched" +msgstr "" + +#: main/models/jobs.py:787 +msgid "Task Started" +msgstr "" + +#: main/models/jobs.py:789 +msgid "Variables Prompted" +msgstr "" + +#: main/models/jobs.py:790 +msgid "Gathering Facts" +msgstr "" + +#: main/models/jobs.py:791 +msgid "internal: on Import for Host" +msgstr "" + +#: main/models/jobs.py:792 +msgid "internal: on Not Import for Host" +msgstr "" + +#: main/models/jobs.py:793 +msgid "Play Started" +msgstr "" + +#: main/models/jobs.py:794 +msgid "Playbook Complete" +msgstr "" + +#: main/models/jobs.py:1240 +msgid "Remove jobs older than a certain number of days" +msgstr "" + +#: main/models/jobs.py:1241 +msgid "Remove activity stream entries older than a certain number of days" +msgstr "" + +#: main/models/jobs.py:1242 +msgid "Purge and/or reduce the granularity of system tracking data" +msgstr "" + +#: main/models/label.py:29 +msgid "Organization this label belongs to." +msgstr "" + +#: main/models/notifications.py:31 +msgid "Email" +msgstr "" + +#: main/models/notifications.py:32 +msgid "Slack" +msgstr "" + +#: main/models/notifications.py:33 +msgid "Twilio" +msgstr "" + +#: main/models/notifications.py:34 +msgid "Pagerduty" +msgstr "" + +#: main/models/notifications.py:35 +msgid "HipChat" +msgstr "" + +#: main/models/notifications.py:36 +msgid "Webhook" +msgstr "" + +#: main/models/notifications.py:37 +msgid "IRC" +msgstr "" + +#: main/models/notifications.py:127 main/models/unified_jobs.py:57 +msgid "Pending" +msgstr "" + +#: main/models/notifications.py:128 main/models/unified_jobs.py:60 +msgid "Successful" +msgstr "" + +#: main/models/notifications.py:129 main/models/unified_jobs.py:61 +msgid "Failed" +msgstr "" + +#: main/models/organization.py:157 +msgid "Execute Commands on the Inventory" +msgstr "" + +#: main/models/organization.py:211 +msgid "Token not invalidated" +msgstr "" + +#: main/models/organization.py:212 +msgid "Token is expired" +msgstr "" + +#: main/models/organization.py:213 +msgid "Maximum per-user sessions reached" +msgstr "" + +#: main/models/organization.py:216 +msgid "Invalid token" +msgstr "" + +#: main/models/organization.py:233 +msgid "Reason the auth token was invalidated." +msgstr "" + +#: main/models/organization.py:272 +msgid "Invalid reason specified" +msgstr "" + +#: main/models/projects.py:43 +msgid "Git" +msgstr "" + +#: main/models/projects.py:44 +msgid "Mercurial" +msgstr "" + +#: main/models/projects.py:45 +msgid "Subversion" +msgstr "" + +#: main/models/projects.py:71 +msgid "" +"Local path (relative to PROJECTS_ROOT) containing playbooks and related " +"files for this project." +msgstr "" + +#: main/models/projects.py:80 +msgid "SCM Type" +msgstr "" + +#: main/models/projects.py:81 +msgid "Specifies the source control system used to store the project." +msgstr "" + +#: main/models/projects.py:87 +msgid "SCM URL" +msgstr "" + +#: main/models/projects.py:88 +msgid "The location where the project is stored." +msgstr "" + +#: main/models/projects.py:94 +msgid "SCM Branch" +msgstr "" + +#: main/models/projects.py:95 +msgid "Specific branch, tag or commit to checkout." +msgstr "" + +#: main/models/projects.py:99 +msgid "Discard any local changes before syncing the project." +msgstr "" + +#: main/models/projects.py:103 +msgid "Delete the project before syncing." +msgstr "" + +#: main/models/projects.py:116 +msgid "The amount of time to run before the task is canceled." +msgstr "" + +#: main/models/projects.py:130 +msgid "Invalid SCM URL." +msgstr "" + +#: main/models/projects.py:133 +msgid "SCM URL is required." +msgstr "" + +#: main/models/projects.py:142 +msgid "Credential kind must be 'scm'." +msgstr "" + +#: main/models/projects.py:157 +msgid "Invalid credential." +msgstr "" + +#: main/models/projects.py:229 +msgid "Update the project when a job is launched that uses the project." +msgstr "" + +#: main/models/projects.py:234 +msgid "" +"The number of seconds after the last project update ran that a newproject " +"update will be launched as a job dependency." +msgstr "" + +#: main/models/projects.py:244 +msgid "The last revision fetched by a project update" +msgstr "" + +#: main/models/projects.py:251 +msgid "Playbook Files" +msgstr "" + +#: main/models/projects.py:252 +msgid "List of playbooks found in the project" +msgstr "" + +#: main/models/rbac.py:122 +msgid "roles" +msgstr "" + +#: main/models/rbac.py:438 +msgid "role_ancestors" +msgstr "" + +#: main/models/schedules.py:69 +msgid "Enables processing of this schedule by Tower." +msgstr "" + +#: main/models/schedules.py:75 +msgid "The first occurrence of the schedule occurs on or after this time." +msgstr "" + +#: main/models/schedules.py:81 +msgid "" +"The last occurrence of the schedule occurs before this time, aftewards the " +"schedule expires." +msgstr "" + +#: main/models/schedules.py:85 +msgid "A value representing the schedules iCal recurrence rule." +msgstr "" + +#: main/models/schedules.py:91 +msgid "The next time that the scheduled action will run." +msgstr "" + +#: main/models/unified_jobs.py:56 +msgid "New" +msgstr "" + +#: main/models/unified_jobs.py:58 +msgid "Waiting" +msgstr "" + +#: main/models/unified_jobs.py:59 +msgid "Running" +msgstr "" + +#: main/models/unified_jobs.py:63 +msgid "Canceled" +msgstr "" + +#: main/models/unified_jobs.py:67 +msgid "Never Updated" +msgstr "" + +#: main/models/unified_jobs.py:71 ui/templates/ui/index.html:85 +#: ui/templates/ui/index.html.py:104 +msgid "OK" +msgstr "" + +#: main/models/unified_jobs.py:72 +msgid "Missing" +msgstr "" + +#: main/models/unified_jobs.py:76 +msgid "No External Source" +msgstr "" + +#: main/models/unified_jobs.py:83 +msgid "Updating" +msgstr "" + +#: main/models/unified_jobs.py:387 +msgid "Relaunch" +msgstr "" + +#: main/models/unified_jobs.py:388 +msgid "Callback" +msgstr "" + +#: main/models/unified_jobs.py:389 +msgid "Scheduled" +msgstr "" + +#: main/models/unified_jobs.py:390 +msgid "Dependency" +msgstr "" + +#: main/models/unified_jobs.py:391 +msgid "Workflow" +msgstr "" + +#: main/models/unified_jobs.py:437 +msgid "The Tower node the job executed on." +msgstr "" + +#: main/models/unified_jobs.py:463 +msgid "The date and time the job was queued for starting." +msgstr "" + +#: main/models/unified_jobs.py:469 +msgid "The date and time the job finished execution." +msgstr "" + +#: main/models/unified_jobs.py:475 +msgid "Elapsed time in seconds that the job ran." +msgstr "" + +#: main/models/unified_jobs.py:497 +msgid "" +"A status field to indicate the state of the job if it wasn't able to run and " +"capture stdout" +msgstr "" + +#: main/notifications/base.py:17 main/notifications/email_backend.py:28 +msgid "" +"{} #{} had status {} on Ansible Tower, view details at {}\n" +"\n" +msgstr "" + +#: main/notifications/hipchat_backend.py:46 +msgid "Error sending messages: {}" +msgstr "" + +#: main/notifications/hipchat_backend.py:48 +msgid "Error sending message to hipchat: {}" +msgstr "" + +#: main/notifications/irc_backend.py:54 +msgid "Exception connecting to irc server: {}" +msgstr "" + +#: main/notifications/pagerduty_backend.py:39 +msgid "Exception connecting to PagerDuty: {}" +msgstr "" + +#: main/notifications/pagerduty_backend.py:48 +#: main/notifications/slack_backend.py:52 +#: main/notifications/twilio_backend.py:46 +msgid "Exception sending messages: {}" +msgstr "" + +#: main/notifications/twilio_backend.py:36 +msgid "Exception connecting to Twilio: {}" +msgstr "" + +#: main/notifications/webhook_backend.py:38 +#: main/notifications/webhook_backend.py:40 +msgid "Error sending notification webhook: {}" +msgstr "" + +#: main/tasks.py:139 +msgid "Ansible Tower host usage over 90%" +msgstr "" + +#: main/tasks.py:144 +msgid "Ansible Tower license will expire soon" +msgstr "" + +#: main/tasks.py:197 +msgid "status_str must be either succeeded or failed" +msgstr "" + +#: main/utils/common.py:88 +#, python-format +msgid "Unable to convert \"%s\" to boolean" +msgstr "" + +#: main/utils/common.py:242 +#, python-format +msgid "Unsupported SCM type \"%s\"" +msgstr "" + +#: main/utils/common.py:249 main/utils/common.py:261 main/utils/common.py:280 +#, python-format +msgid "Invalid %s URL" +msgstr "" + +#: main/utils/common.py:251 main/utils/common.py:289 +#, python-format +msgid "Unsupported %s URL" +msgstr "" + +#: main/utils/common.py:291 +#, python-format +msgid "Unsupported host \"%s\" for file:// URL" +msgstr "" + +#: main/utils/common.py:293 +#, python-format +msgid "Host is required for %s URL" +msgstr "" + +#: main/utils/common.py:311 +#, python-format +msgid "Username must be \"git\" for SSH access to %s." +msgstr "" + +#: main/utils/common.py:317 +#, python-format +msgid "Username must be \"hg\" for SSH access to %s." +msgstr "" + +#: main/validators.py:60 +#, python-format +msgid "Invalid certificate or key: %r..." +msgstr "" + +#: main/validators.py:74 +#, python-format +msgid "Invalid private key: unsupported type \"%s\"" +msgstr "" + +#: main/validators.py:78 +#, python-format +msgid "Unsupported PEM object type: \"%s\"" +msgstr "" + +#: main/validators.py:103 +msgid "Invalid base64-encoded data" +msgstr "" + +#: main/validators.py:122 +msgid "Exactly one private key is required." +msgstr "" + +#: main/validators.py:124 +msgid "At least one private key is required." +msgstr "" + +#: main/validators.py:126 +#, python-format +msgid "" +"At least %(min_keys)d private keys are required, only %(key_count)d provided." +msgstr "" + +#: main/validators.py:129 +#, python-format +msgid "Only one private key is allowed, %(key_count)d provided." +msgstr "" + +#: main/validators.py:131 +#, python-format +msgid "" +"No more than %(max_keys)d private keys are allowed, %(key_count)d provided." +msgstr "" + +#: main/validators.py:136 +msgid "Exactly one certificate is required." +msgstr "" + +#: main/validators.py:138 +msgid "At least one certificate is required." +msgstr "" + +#: main/validators.py:140 +#, python-format +msgid "" +"At least %(min_certs)d certificates are required, only %(cert_count)d " +"provided." +msgstr "" + +#: main/validators.py:143 +#, python-format +msgid "Only one certificate is allowed, %(cert_count)d provided." +msgstr "" + +#: main/validators.py:145 +#, python-format +msgid "" +"No more than %(max_certs)d certificates are allowed, %(cert_count)d provided." +msgstr "" + +#: main/views.py:20 +msgid "API Error" +msgstr "" + +#: main/views.py:49 +msgid "Bad Request" +msgstr "" + +#: main/views.py:50 +msgid "The request could not be understood by the server." +msgstr "" + +#: main/views.py:57 +msgid "Forbidden" +msgstr "" + +#: main/views.py:58 +msgid "You don't have permission to access the requested resource." +msgstr "" + +#: main/views.py:65 +msgid "Not Found" +msgstr "" + +#: main/views.py:66 +msgid "The requested resource could not be found." +msgstr "" + +#: main/views.py:73 +msgid "Server Error" +msgstr "" + +#: main/views.py:74 +msgid "A server error has occurred." +msgstr "" + +#: settings/defaults.py:593 +msgid "Chicago" +msgstr "" + +#: settings/defaults.py:594 +msgid "Dallas/Ft. Worth" +msgstr "" + +#: settings/defaults.py:595 +msgid "Northern Virginia" +msgstr "" + +#: settings/defaults.py:596 +msgid "London" +msgstr "" + +#: settings/defaults.py:597 +msgid "Sydney" +msgstr "" + +#: settings/defaults.py:598 +msgid "Hong Kong" +msgstr "" + +#: settings/defaults.py:625 +msgid "US East (Northern Virginia)" +msgstr "" + +#: settings/defaults.py:626 +msgid "US East (Ohio)" +msgstr "" + +#: settings/defaults.py:627 +msgid "US West (Oregon)" +msgstr "" + +#: settings/defaults.py:628 +msgid "US West (Northern California)" +msgstr "" + +#: settings/defaults.py:629 +msgid "EU (Frankfurt)" +msgstr "" + +#: settings/defaults.py:630 +msgid "EU (Ireland)" +msgstr "" + +#: settings/defaults.py:631 +msgid "Asia Pacific (Singapore)" +msgstr "" + +#: settings/defaults.py:632 +msgid "Asia Pacific (Sydney)" +msgstr "" + +#: settings/defaults.py:633 +msgid "Asia Pacific (Tokyo)" +msgstr "" + +#: settings/defaults.py:634 +msgid "Asia Pacific (Seoul)" +msgstr "" + +#: settings/defaults.py:635 +msgid "Asia Pacific (Mumbai)" +msgstr "" + +#: settings/defaults.py:636 +msgid "South America (Sao Paulo)" +msgstr "" + +#: settings/defaults.py:637 +msgid "US West (GovCloud)" +msgstr "" + +#: settings/defaults.py:638 +msgid "China (Beijing)" +msgstr "" + +#: settings/defaults.py:687 +msgid "US East (B)" +msgstr "" + +#: settings/defaults.py:688 +msgid "US East (C)" +msgstr "" + +#: settings/defaults.py:689 +msgid "US East (D)" +msgstr "" + +#: settings/defaults.py:690 +msgid "US Central (A)" +msgstr "" + +#: settings/defaults.py:691 +msgid "US Central (B)" +msgstr "" + +#: settings/defaults.py:692 +msgid "US Central (C)" +msgstr "" + +#: settings/defaults.py:693 +msgid "US Central (F)" +msgstr "" + +#: settings/defaults.py:694 +msgid "Europe West (B)" +msgstr "" + +#: settings/defaults.py:695 +msgid "Europe West (C)" +msgstr "" + +#: settings/defaults.py:696 +msgid "Europe West (D)" +msgstr "" + +#: settings/defaults.py:697 +msgid "Asia East (A)" +msgstr "" + +#: settings/defaults.py:698 +msgid "Asia East (B)" +msgstr "" + +#: settings/defaults.py:699 +msgid "Asia East (C)" +msgstr "" + +#: settings/defaults.py:723 +msgid "US Central" +msgstr "" + +#: settings/defaults.py:724 +msgid "US East" +msgstr "" + +#: settings/defaults.py:725 +msgid "US East 2" +msgstr "" + +#: settings/defaults.py:726 +msgid "US North Central" +msgstr "" + +#: settings/defaults.py:727 +msgid "US South Central" +msgstr "" + +#: settings/defaults.py:728 +msgid "US West" +msgstr "" + +#: settings/defaults.py:729 +msgid "Europe North" +msgstr "" + +#: settings/defaults.py:730 +msgid "Europe West" +msgstr "" + +#: settings/defaults.py:731 +msgid "Asia Pacific East" +msgstr "" + +#: settings/defaults.py:732 +msgid "Asia Pacific Southeast" +msgstr "" + +#: settings/defaults.py:733 +msgid "Japan East" +msgstr "" + +#: settings/defaults.py:734 +msgid "Japan West" +msgstr "" + +#: settings/defaults.py:735 +msgid "Brazil South" +msgstr "" + +#: sso/apps.py:9 +msgid "Single Sign-On" +msgstr "" + +#: sso/conf.py:27 +msgid "" +"Mapping to organization admins/users from social auth accounts. This " +"setting\n" +"controls which users are placed into which Tower organizations based on\n" +"their username and email address. Dictionary keys are organization names.\n" +"organizations will be created if not present if the license allows for\n" +"multiple organizations, otherwise the single default organization is used\n" +"regardless of the key. Values are dictionaries defining the options for\n" +"each organization's membership. For each organization it is possible to\n" +"specify which users are automatically users of the organization and also\n" +"which users can administer the organization. \n" +"\n" +"- admins: None, True/False, string or list of strings.\n" +" If None, organization admins will not be updated.\n" +" If True, all users using social auth will automatically be added as " +"admins\n" +" of the organization.\n" +" If False, no social auth users will be automatically added as admins of\n" +" the organization.\n" +" If a string or list of strings, specifies the usernames and emails for\n" +" users who will be added to the organization. Strings in the format\n" +" \"//\" will be interpreted as JavaScript regular " +"expressions and\n" +" may also be used instead of string literals; only \"i\" and \"m\" are " +"supported\n" +" for flags.\n" +"- remove_admins: True/False. Defaults to True.\n" +" If True, a user who does not match will be removed from the " +"organization's\n" +" administrative list.\n" +"- users: None, True/False, string or list of strings. Same rules apply as " +"for\n" +" admins.\n" +"- remove_users: True/False. Defaults to True. Same rules as apply for \n" +" remove_admins." +msgstr "" + +#: sso/conf.py:76 +msgid "" +"Mapping of team members (users) from social auth accounts. Keys are team\n" +"names (will be created if not present). Values are dictionaries of options\n" +"for each team's membership, where each can contain the following " +"parameters:\n" +"\n" +"- organization: string. The name of the organization to which the team\n" +" belongs. The team will be created if the combination of organization and\n" +" team name does not exist. The organization will first be created if it\n" +" does not exist. If the license does not allow for multiple " +"organizations,\n" +" the team will always be assigned to the single default organization.\n" +"- users: None, True/False, string or list of strings.\n" +" If None, team members will not be updated.\n" +" If True/False, all social auth users will be added/removed as team\n" +" members.\n" +" If a string or list of strings, specifies expressions used to match " +"users.\n" +" User will be added as a team member if the username or email matches.\n" +" Strings in the format \"//\" will be interpreted as " +"JavaScript\n" +" regular expressions and may also be used instead of string literals; only " +"\"i\"\n" +" and \"m\" are supported for flags.\n" +"- remove: True/False. Defaults to True. If True, a user who does not match\n" +" the rules above will be removed from the team." +msgstr "" + +#: sso/conf.py:119 +msgid "Authentication Backends" +msgstr "" + +#: sso/conf.py:120 +msgid "" +"List of authentication backends that are enabled based on license features " +"and other authentication settings." +msgstr "" + +#: sso/conf.py:133 +msgid "Social Auth Organization Map" +msgstr "" + +#: sso/conf.py:145 +msgid "Social Auth Team Map" +msgstr "" + +#: sso/conf.py:157 +msgid "Social Auth User Fields" +msgstr "" + +#: sso/conf.py:158 +msgid "" +"When set to an empty list `[]`, this setting prevents new user accounts from " +"being created. Only users who have previously logged in using social auth or " +"have a user account with a matching email address will be able to login." +msgstr "" + +#: sso/conf.py:176 +msgid "LDAP Server URI" +msgstr "" + +#: sso/conf.py:177 +msgid "" +"URI to connect to LDAP server, such as \"ldap://ldap.example.com:389\" (non-" +"SSL) or \"ldaps://ldap.example.com:636\" (SSL). Multiple LDAP servers may be " +"specified by separating with spaces or commas. LDAP authentication is " +"disabled if this parameter is empty." +msgstr "" + +#: sso/conf.py:181 sso/conf.py:199 sso/conf.py:211 sso/conf.py:223 +#: sso/conf.py:239 sso/conf.py:258 sso/conf.py:279 sso/conf.py:295 +#: sso/conf.py:314 sso/conf.py:331 sso/conf.py:347 sso/conf.py:362 +#: sso/conf.py:379 sso/conf.py:417 sso/conf.py:458 +msgid "LDAP" +msgstr "" + +#: sso/conf.py:193 +msgid "LDAP Bind DN" +msgstr "" + +#: sso/conf.py:194 +msgid "" +"DN (Distinguished Name) of user to bind for all search queries. Normally in " +"the format \"CN=Some User,OU=Users,DC=example,DC=com\" but may also be " +"specified as \"DOMAIN\\username\" for Active Directory. This is the system " +"user account we will use to login to query LDAP for other user information." +msgstr "" + +#: sso/conf.py:209 +msgid "LDAP Bind Password" +msgstr "" + +#: sso/conf.py:210 +msgid "Password used to bind LDAP user account." +msgstr "" + +#: sso/conf.py:221 +msgid "LDAP Start TLS" +msgstr "" + +#: sso/conf.py:222 +msgid "Whether to enable TLS when the LDAP connection is not using SSL." +msgstr "" + +#: sso/conf.py:232 +msgid "LDAP Connection Options" +msgstr "" + +#: sso/conf.py:233 +msgid "" +"Additional options to set for the LDAP connection. LDAP referrals are " +"disabled by default (to prevent certain LDAP queries from hanging with AD). " +"Option names should be strings (e.g. \"OPT_REFERRALS\"). Refer to https://" +"www.python-ldap.org/doc/html/ldap.html#options for possible options and " +"values that can be set." +msgstr "" + +#: sso/conf.py:251 +msgid "LDAP User Search" +msgstr "" + +#: sso/conf.py:252 +msgid "" +"LDAP search query to find users. Any user that matches the given pattern " +"will be able to login to Tower. The user should also be mapped into an " +"Tower organization (as defined in the AUTH_LDAP_ORGANIZATION_MAP setting). " +"If multiple search queries need to be supported use of \"LDAPUnion\" is " +"possible. See python-ldap documentation as linked at the top of this section." +msgstr "" + +#: sso/conf.py:273 +msgid "LDAP User DN Template" +msgstr "" + +#: sso/conf.py:274 +msgid "" +"Alternative to user search, if user DNs are all of the same format. This " +"approach will be more efficient for user lookups than searching if it is " +"usable in your organizational environment. If this setting has a value it " +"will be used instead of AUTH_LDAP_USER_SEARCH." +msgstr "" + +#: sso/conf.py:289 +msgid "LDAP User Attribute Map" +msgstr "" + +#: sso/conf.py:290 +msgid "" +"Mapping of LDAP user schema to Tower API user attributes (key is user " +"attribute name, value is LDAP attribute name). The default setting is valid " +"for ActiveDirectory but users with other LDAP configurations may need to " +"change the values (not the keys) of the dictionary/hash-table." +msgstr "" + +#: sso/conf.py:309 +msgid "LDAP Group Search" +msgstr "" + +#: sso/conf.py:310 +msgid "" +"Users in Tower are mapped to organizations based on their membership in LDAP " +"groups. This setting defines the LDAP search query to find groups. Note that " +"this, unlike the user search above, does not support LDAPSearchUnion." +msgstr "" + +#: sso/conf.py:327 +msgid "LDAP Group Type" +msgstr "" + +#: sso/conf.py:328 +msgid "" +"The group type may need to be changed based on the type of the LDAP server. " +"Values are listed at: http://pythonhosted.org/django-auth-ldap/groups." +"html#types-of-groups" +msgstr "" + +#: sso/conf.py:342 +msgid "LDAP Require Group" +msgstr "" + +#: sso/conf.py:343 +msgid "" +"Group DN required to login. If specified, user must be a member of this " +"group to login via LDAP. If not set, everyone in LDAP that matches the user " +"search will be able to login via Tower. Only one require group is supported." +msgstr "" + +#: sso/conf.py:358 +msgid "LDAP Deny Group" +msgstr "" + +#: sso/conf.py:359 +msgid "" +"Group DN denied from login. If specified, user will not be allowed to login " +"if a member of this group. Only one deny group is supported." +msgstr "" + +#: sso/conf.py:372 +msgid "LDAP User Flags By Group" +msgstr "" + +#: sso/conf.py:373 +msgid "" +"User profile flags updated from group membership (key is user attribute " +"name, value is group DN). These are boolean fields that are matched based " +"on whether the user is a member of the given group. So far only " +"is_superuser is settable via this method. This flag is set both true and " +"false at login time based on current LDAP settings." +msgstr "" + +#: sso/conf.py:391 +msgid "LDAP Organization Map" +msgstr "" + +#: sso/conf.py:392 +msgid "" +"Mapping between organization admins/users and LDAP groups. This controls " +"what users are placed into what Tower organizations relative to their LDAP " +"group memberships. Keys are organization names. Organizations will be " +"created if not present. Values are dictionaries defining the options for " +"each organization's membership. For each organization it is possible to " +"specify what groups are automatically users of the organization and also " +"what groups can administer the organization.\n" +"\n" +" - admins: None, True/False, string or list of strings.\n" +" If None, organization admins will not be updated based on LDAP values.\n" +" If True, all users in LDAP will automatically be added as admins of the " +"organization.\n" +" If False, no LDAP users will be automatically added as admins of the " +"organization.\n" +" If a string or list of strings, specifies the group DN(s) that will be " +"added of the organization if they match any of the specified groups.\n" +" - remove_admins: True/False. Defaults to True.\n" +" If True, a user who is not an member of the given groups will be removed " +"from the organization's administrative list.\n" +" - users: None, True/False, string or list of strings. Same rules apply as " +"for admins.\n" +" - remove_users: True/False. Defaults to True. Same rules apply as for " +"remove_admins." +msgstr "" + +#: sso/conf.py:440 +msgid "LDAP Team Map" +msgstr "" + +#: sso/conf.py:441 +msgid "" +"Mapping between team members (users) and LDAP groups. Keys are team names " +"(will be created if not present). Values are dictionaries of options for " +"each team's membership, where each can contain the following parameters:\n" +"\n" +" - organization: string. The name of the organization to which the team " +"belongs. The team will be created if the combination of organization and " +"team name does not exist. The organization will first be created if it does " +"not exist.\n" +" - users: None, True/False, string or list of strings.\n" +" If None, team members will not be updated.\n" +" If True/False, all LDAP users will be added/removed as team members.\n" +" If a string or list of strings, specifies the group DN(s). User will be " +"added as a team member if the user is a member of ANY of these groups.\n" +"- remove: True/False. Defaults to True. If True, a user who is not a member " +"of the given groups will be removed from the team." +msgstr "" + +#: sso/conf.py:484 +msgid "RADIUS Server" +msgstr "" + +#: sso/conf.py:485 +msgid "" +"Hostname/IP of RADIUS server. RADIUS authentication will be disabled if this " +"setting is empty." +msgstr "" + +#: sso/conf.py:487 sso/conf.py:501 sso/conf.py:513 +msgid "RADIUS" +msgstr "" + +#: sso/conf.py:499 +msgid "RADIUS Port" +msgstr "" + +#: sso/conf.py:500 +msgid "Port of RADIUS server." +msgstr "" + +#: sso/conf.py:511 +msgid "RADIUS Secret" +msgstr "" + +#: sso/conf.py:512 +msgid "Shared secret for authenticating to RADIUS server." +msgstr "" + +#: sso/conf.py:528 +msgid "Google OAuth2 Callback URL" +msgstr "" + +#: sso/conf.py:529 +msgid "" +"Create a project at https://console.developers.google.com/ to obtain an " +"OAuth2 key and secret for a web application. Ensure that the Google+ API is " +"enabled. Provide this URL as the callback URL for your application." +msgstr "" + +#: sso/conf.py:533 sso/conf.py:544 sso/conf.py:555 sso/conf.py:568 +#: sso/conf.py:582 sso/conf.py:594 sso/conf.py:606 +msgid "Google OAuth2" +msgstr "" + +#: sso/conf.py:542 +msgid "Google OAuth2 Key" +msgstr "" + +#: sso/conf.py:543 +msgid "" +"The OAuth2 key from your web application at https://console.developers." +"google.com/." +msgstr "" + +#: sso/conf.py:553 +msgid "Google OAuth2 Secret" +msgstr "" + +#: sso/conf.py:554 +msgid "" +"The OAuth2 secret from your web application at https://console.developers." +"google.com/." +msgstr "" + +#: sso/conf.py:565 +msgid "Google OAuth2 Whitelisted Domains" +msgstr "" + +#: sso/conf.py:566 +msgid "" +"Update this setting to restrict the domains who are allowed to login using " +"Google OAuth2." +msgstr "" + +#: sso/conf.py:577 +msgid "Google OAuth2 Extra Arguments" +msgstr "" + +#: sso/conf.py:578 +msgid "" +"Extra arguments for Google OAuth2 login. When only allowing a single domain " +"to authenticate, set to `{\"hd\": \"yourdomain.com\"}` and Google will not " +"display any other accounts even if the user is logged in with multiple " +"Google accounts." +msgstr "" + +#: sso/conf.py:592 +msgid "Google OAuth2 Organization Map" +msgstr "" + +#: sso/conf.py:604 +msgid "Google OAuth2 Team Map" +msgstr "" + +#: sso/conf.py:620 +msgid "GitHub OAuth2 Callback URL" +msgstr "" + +#: sso/conf.py:621 +msgid "" +"Create a developer application at https://github.com/settings/developers to " +"obtain an OAuth2 key (Client ID) and secret (Client Secret). Provide this " +"URL as the callback URL for your application." +msgstr "" + +#: sso/conf.py:625 sso/conf.py:636 sso/conf.py:646 sso/conf.py:658 +#: sso/conf.py:670 +msgid "GitHub OAuth2" +msgstr "" + +#: sso/conf.py:634 +msgid "GitHub OAuth2 Key" +msgstr "" + +#: sso/conf.py:635 +msgid "The OAuth2 key (Client ID) from your GitHub developer application." +msgstr "" + +#: sso/conf.py:644 +msgid "GitHub OAuth2 Secret" +msgstr "" + +#: sso/conf.py:645 +msgid "" +"The OAuth2 secret (Client Secret) from your GitHub developer application." +msgstr "" + +#: sso/conf.py:656 +msgid "GitHub OAuth2 Organization Map" +msgstr "" + +#: sso/conf.py:668 +msgid "GitHub OAuth2 Team Map" +msgstr "" + +#: sso/conf.py:684 +msgid "GitHub Organization OAuth2 Callback URL" +msgstr "" + +#: sso/conf.py:685 sso/conf.py:760 +msgid "" +"Create an organization-owned application at https://github.com/organizations/" +"/settings/applications and obtain an OAuth2 key (Client ID) and " +"secret (Client Secret). Provide this URL as the callback URL for your " +"application." +msgstr "" + +#: sso/conf.py:689 sso/conf.py:700 sso/conf.py:710 sso/conf.py:722 +#: sso/conf.py:733 sso/conf.py:745 +msgid "GitHub Organization OAuth2" +msgstr "" + +#: sso/conf.py:698 +msgid "GitHub Organization OAuth2 Key" +msgstr "" + +#: sso/conf.py:699 sso/conf.py:774 +msgid "The OAuth2 key (Client ID) from your GitHub organization application." +msgstr "" + +#: sso/conf.py:708 +msgid "GitHub Organization OAuth2 Secret" +msgstr "" + +#: sso/conf.py:709 sso/conf.py:784 +msgid "" +"The OAuth2 secret (Client Secret) from your GitHub organization application." +msgstr "" + +#: sso/conf.py:719 +msgid "GitHub Organization Name" +msgstr "" + +#: sso/conf.py:720 +msgid "" +"The name of your GitHub organization, as used in your organization's URL: " +"https://github.com//." +msgstr "" + +#: sso/conf.py:731 +msgid "GitHub Organization OAuth2 Organization Map" +msgstr "" + +#: sso/conf.py:743 +msgid "GitHub Organization OAuth2 Team Map" +msgstr "" + +#: sso/conf.py:759 +msgid "GitHub Team OAuth2 Callback URL" +msgstr "" + +#: sso/conf.py:764 sso/conf.py:775 sso/conf.py:785 sso/conf.py:797 +#: sso/conf.py:808 sso/conf.py:820 +msgid "GitHub Team OAuth2" +msgstr "" + +#: sso/conf.py:773 +msgid "GitHub Team OAuth2 Key" +msgstr "" + +#: sso/conf.py:783 +msgid "GitHub Team OAuth2 Secret" +msgstr "" + +#: sso/conf.py:794 +msgid "GitHub Team ID" +msgstr "" + +#: sso/conf.py:795 +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 "" + +#: sso/conf.py:806 +msgid "GitHub Team OAuth2 Organization Map" +msgstr "" + +#: sso/conf.py:818 +msgid "GitHub Team OAuth2 Team Map" +msgstr "" + +#: sso/conf.py:834 +msgid "Azure AD OAuth2 Callback URL" +msgstr "" + +#: sso/conf.py:835 +msgid "" +"Register an Azure AD application as described by https://msdn.microsoft.com/" +"en-us/library/azure/dn132599.aspx and obtain an OAuth2 key (Client ID) and " +"secret (Client Secret). Provide this URL as the callback URL for your " +"application." +msgstr "" + +#: sso/conf.py:839 sso/conf.py:850 sso/conf.py:860 sso/conf.py:872 +#: sso/conf.py:884 +msgid "Azure AD OAuth2" +msgstr "" + +#: sso/conf.py:848 +msgid "Azure AD OAuth2 Key" +msgstr "" + +#: sso/conf.py:849 +msgid "The OAuth2 key (Client ID) from your Azure AD application." +msgstr "" + +#: sso/conf.py:858 +msgid "Azure AD OAuth2 Secret" +msgstr "" + +#: sso/conf.py:859 +msgid "The OAuth2 secret (Client Secret) from your Azure AD application." +msgstr "" + +#: sso/conf.py:870 +msgid "Azure AD OAuth2 Organization Map" +msgstr "" + +#: sso/conf.py:882 +msgid "Azure AD OAuth2 Team Map" +msgstr "" + +#: sso/conf.py:903 +msgid "SAML Service Provider Callback URL" +msgstr "" + +#: sso/conf.py:904 +msgid "" +"Register Tower as a service provider (SP) with each identity provider (IdP) " +"you have configured. Provide your SP Entity ID and this callback URL for " +"your application." +msgstr "" + +#: sso/conf.py:907 sso/conf.py:921 sso/conf.py:934 sso/conf.py:948 +#: sso/conf.py:962 sso/conf.py:980 sso/conf.py:1002 sso/conf.py:1021 +#: sso/conf.py:1041 sso/conf.py:1075 sso/conf.py:1088 +msgid "SAML" +msgstr "" + +#: sso/conf.py:918 +msgid "SAML Service Provider Metadata URL" +msgstr "" + +#: sso/conf.py:919 +msgid "" +"If your identity provider (IdP) allows uploading an XML metadata file, you " +"can download one from this URL." +msgstr "" + +#: sso/conf.py:931 +msgid "SAML Service Provider Entity ID" +msgstr "" + +#: sso/conf.py:932 +msgid "" +"The application-defined unique identifier used as the audience of the SAML " +"service provider (SP) configuration." +msgstr "" + +#: sso/conf.py:945 +msgid "SAML Service Provider Public Certificate" +msgstr "" + +#: sso/conf.py:946 +msgid "" +"Create a keypair for Tower to use as a service provider (SP) and include the " +"certificate content here." +msgstr "" + +#: sso/conf.py:959 +msgid "SAML Service Provider Private Key" +msgstr "" + +#: sso/conf.py:960 +msgid "" +"Create a keypair for Tower to use as a service provider (SP) and include the " +"private key content here." +msgstr "" + +#: sso/conf.py:978 +msgid "SAML Service Provider Organization Info" +msgstr "" + +#: sso/conf.py:979 +msgid "Configure this setting with information about your app." +msgstr "" + +#: sso/conf.py:1000 +msgid "SAML Service Provider Technical Contact" +msgstr "" + +#: sso/conf.py:1001 sso/conf.py:1020 +msgid "Configure this setting with your contact information." +msgstr "" + +#: sso/conf.py:1019 +msgid "SAML Service Provider Support Contact" +msgstr "" + +#: sso/conf.py:1034 +msgid "SAML Enabled Identity Providers" +msgstr "" + +#: sso/conf.py:1035 +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 " +"data using attribute names that differ from the default OIDs (https://github." +"com/omab/python-social-auth/blob/master/social/backends/saml.py#L16). " +"Attribute names may be overridden for each IdP." +msgstr "" + +#: sso/conf.py:1073 +msgid "SAML Organization Map" +msgstr "" + +#: sso/conf.py:1086 +msgid "SAML Team Map" +msgstr "" + +#: sso/fields.py:123 +msgid "Invalid connection option(s): {invalid_options}." +msgstr "" + +#: sso/fields.py:182 +msgid "Base" +msgstr "" + +#: sso/fields.py:183 +msgid "One Level" +msgstr "" + +#: sso/fields.py:184 +msgid "Subtree" +msgstr "" + +#: sso/fields.py:202 +msgid "Expected a list of three items but got {length} instead." +msgstr "" + +#: sso/fields.py:203 +msgid "Expected an instance of LDAPSearch but got {input_type} instead." +msgstr "" + +#: sso/fields.py:239 +msgid "" +"Expected an instance of LDAPSearch or LDAPSearchUnion but got {input_type} " +"instead." +msgstr "" + +#: sso/fields.py:266 +msgid "Invalid user attribute(s): {invalid_attrs}." +msgstr "" + +#: sso/fields.py:283 +msgid "Expected an instance of LDAPGroupType but got {input_type} instead." +msgstr "" + +#: sso/fields.py:308 +msgid "Invalid user flag: \"{invalid_flag}\"." +msgstr "" + +#: sso/fields.py:324 sso/fields.py:491 +msgid "" +"Expected None, True, False, a string or list of strings but got {input_type} " +"instead." +msgstr "" + +#: sso/fields.py:360 +msgid "Missing key(s): {missing_keys}." +msgstr "" + +#: sso/fields.py:361 +msgid "Invalid key(s): {invalid_keys}." +msgstr "" + +#: sso/fields.py:410 sso/fields.py:527 +msgid "Invalid key(s) for organization map: {invalid_keys}." +msgstr "" + +#: sso/fields.py:428 +msgid "Missing required key for team map: {invalid_keys}." +msgstr "" + +#: sso/fields.py:429 sso/fields.py:546 +msgid "Invalid key(s) for team map: {invalid_keys}." +msgstr "" + +#: sso/fields.py:545 +msgid "Missing required key for team map: {missing_keys}." +msgstr "" + +#: sso/fields.py:563 +msgid "Missing required key(s) for org info record: {missing_keys}." +msgstr "" + +#: sso/fields.py:576 +msgid "Invalid language code(s) for org info: {invalid_lang_codes}." +msgstr "" + +#: sso/fields.py:595 +msgid "Missing required key(s) for contact: {missing_keys}." +msgstr "" + +#: sso/fields.py:607 +msgid "Missing required key(s) for IdP: {missing_keys}." +msgstr "" + +#: sso/pipeline.py:24 +msgid "An account cannot be found for {0}" +msgstr "" + +#: sso/pipeline.py:30 +msgid "Your account is inactive" +msgstr "" + +#: sso/validators.py:19 sso/validators.py:44 +#, python-format +msgid "DN must include \"%%(user)s\" placeholder for username: %s" +msgstr "" + +#: sso/validators.py:26 +#, python-format +msgid "Invalid DN: %s" +msgstr "" + +#: sso/validators.py:56 +#, python-format +msgid "Invalid filter: %s" +msgstr "" + +#: templates/error.html:4 ui/templates/ui/index.html:8 +msgid "Ansible Tower" +msgstr "" + +#: templates/rest_framework/api.html:39 +msgid "Ansible Tower API Guide" +msgstr "" + +#: templates/rest_framework/api.html:40 +msgid "Back to Ansible Tower" +msgstr "" + +#: templates/rest_framework/api.html:41 +msgid "Resize" +msgstr "" + +#: templates/rest_framework/base.html:78 templates/rest_framework/base.html:92 +#, python-format +msgid "Make a GET request on the %(name)s resource" +msgstr "" + +#: templates/rest_framework/base.html:80 +msgid "Specify a format for the GET request" +msgstr "" + +#: templates/rest_framework/base.html:86 +#, python-format +msgid "" +"Make a GET request on the %(name)s resource with the format set to `" +"%(format)s`" +msgstr "" + +#: templates/rest_framework/base.html:100 +#, python-format +msgid "Make an OPTIONS request on the %(name)s resource" +msgstr "" + +#: templates/rest_framework/base.html:106 +#, python-format +msgid "Make a DELETE request on the %(name)s resource" +msgstr "" + +#: templates/rest_framework/base.html:113 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/base.html:172 +#: templates/rest_framework/base.html:186 +#, python-format +msgid "Make a POST request on the %(name)s resource" +msgstr "" + +#: templates/rest_framework/base.html:216 +#: templates/rest_framework/base.html:230 +#, python-format +msgid "Make a PUT request on the %(name)s resource" +msgstr "" + +#: templates/rest_framework/base.html:233 +#, python-format +msgid "Make a PATCH request on the %(name)s resource" +msgstr "" + +#: ui/apps.py:9 ui/conf.py:22 ui/conf.py:38 ui/conf.py:53 +msgid "UI" +msgstr "" + +#: ui/conf.py:16 +msgid "Off" +msgstr "" + +#: ui/conf.py:17 +msgid "Anonymous" +msgstr "" + +#: ui/conf.py:18 +msgid "Detailed" +msgstr "" + +#: ui/conf.py:20 +msgid "Analytics Tracking State" +msgstr "" + +#: ui/conf.py:21 +msgid "Enable or Disable Analytics Tracking." +msgstr "" + +#: ui/conf.py:31 +msgid "Custom Login Info" +msgstr "" + +#: ui/conf.py:32 +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. If multiple paragraphs of text are needed, new lines " +"(paragraphs) must be escaped as `\\n` within the block of text." +msgstr "" + +#: ui/conf.py:48 +msgid "Custom Logo" +msgstr "" + +#: ui/conf.py:49 +msgid "" +"To set up a custom logo, provide a file that you create. For the custom logo " +"to look its best, use a `.png` file with a transparent background. GIF, PNG " +"and JPEG formats are supported." +msgstr "" + +#: ui/fields.py:29 +msgid "" +"Invalid format for custom logo. Must be a data URL with a base64-encoded " +"GIF, PNG or JPEG image." +msgstr "" + +#: ui/fields.py:30 +msgid "Invalid base64-encoded data in data URL." +msgstr "" + +#: ui/templates/ui/index.html:49 +msgid "" +"Your session will expire in 60 seconds, would you like to continue?" +msgstr "" + +#: ui/templates/ui/index.html:64 +msgid "CANCEL" +msgstr "" + +#: ui/templates/ui/index.html:116 +msgid "Set how many days of data should be retained." +msgstr "" + +#: ui/templates/ui/index.html:122 +msgid "" +"Please enter an integer that is not " +"negative that is lower than 9999." +msgstr "" + +#: ui/templates/ui/index.html:127 +msgid "" +"For facts collected older than the time period specified, save one fact scan " +"(snapshot) per time window (frequency). For example, facts older than 30 " +"days are purged, while one weekly fact scan is kept.\n" +"
\n" +"
CAUTION: Setting both numerical variables to \"0\" " +"will delete all facts.\n" +"
\n" +"
" +msgstr "" + +#: ui/templates/ui/index.html:136 +msgid "Select a time period after which to remove old facts" +msgstr "" + +#: ui/templates/ui/index.html:150 +msgid "" +"Please enter an integer " +"that is not negative " +"that is lower than 9999." +msgstr "" + +#: ui/templates/ui/index.html:155 +msgid "Select a frequency for snapshot retention" +msgstr "" + +#: ui/templates/ui/index.html:169 +msgid "" +"Please enter an integer that is not negative that is " +"lower than 9999." +msgstr "" + +#: ui/templates/ui/index.html:175 +msgid "working..." +msgstr "" diff --git a/awx/locale/fr/LC_MESSAGES/ansible-tower-ui.mo b/awx/locale/fr/LC_MESSAGES/ansible-tower-ui.mo new file mode 100644 index 0000000000..26c7ae5267 Binary files /dev/null and b/awx/locale/fr/LC_MESSAGES/ansible-tower-ui.mo differ diff --git a/awx/locale/fr/LC_MESSAGES/ansible-tower-ui.po b/awx/locale/fr/LC_MESSAGES/ansible-tower-ui.po new file mode 100644 index 0000000000..b37f3871b7 --- /dev/null +++ b/awx/locale/fr/LC_MESSAGES/ansible-tower-ui.po @@ -0,0 +1,2963 @@ +# Corina Roe , 2017. #zanata +# Sam Friedmann , 2017. #zanata +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Project-Id-Version: \n" +"MIME-Version: 1.0\n" +"PO-Revision-Date: 2017-01-11 12:31+0000\n" +"Last-Translator: Corina Roe \n" +"Language-Team: French\n" +"Language: fr\n" +"X-Generator: Zanata 3.9.6\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" + +#: client/src/notifications/notificationTemplates.form.js:371 +msgid "%s or %s" +msgstr "%s ou %s" + +#: client/src/controllers/Projects.js:397 +#: client/src/controllers/Projects.js:679 +msgid "" +"%sNote:%s Mercurial does not support password authentication for SSH. Do not " +"put the username and key in the URL. If using Bitbucket and SSH, do not " +"supply your Bitbucket username." +msgstr "" +"%Remarque :%s Mercurial ne prend pas en charge l'authentification par mot de " +"passe pour SSH. N'entrez ni le nom d'utilisateur, ni la clé dans l'URL. Si " +"vous utilisez Bitbucket et SSH, ne saisissez pas votre nom d'utilisateur " +"Bitbucket." + +#: client/src/controllers/Projects.js:384 +#: client/src/controllers/Projects.js:666 +msgid "" +"%sNote:%s When using SSH protocol for GitHub or Bitbucket, enter an SSH key " +"only, do not enter a username (other than git). Additionally, GitHub and " +"Bitbucket do not support password authentication when using SSH. GIT read " +"only protocol (git://) does not use username or password information." +msgstr "" +"%Remarque :%s Si vous utilisez le protocole SSH pour GitHub ou Bitbucket, " +"entrez uniquement une clé SSH sans nom d'utilisateur (autre que git). De " +"plus, GitHub et Bitbucket ne prennent pas en charge l'authentification par " +"mot de passe lorsque SSH est utilisé. Le protocole GIT en lecture seule (git:" +"//) n'utilise pas les informations de nom d'utilisateur ou de mot de passe." + +#: client/src/forms/Credentials.js:287 +msgid "(defaults to %s)" +msgstr "(défini par défaut sur %s)" + +#: client/src/organizations/list/organizations-list.partial.html:15 +msgid "+ ADD" +msgstr "+ AJOUTER" + +#: client/src/controllers/Users.js:185 +msgid "A value is required" +msgstr "Entrez une valeur" + +#: client/src/forms/Credentials.js:442 +#: client/src/forms/Inventories.js:153 +#: client/src/forms/JobTemplates.js:414 +#: client/src/forms/Organizations.js:75 +#: client/src/forms/Projects.js:237 +#: client/src/forms/Teams.js:86 +#: client/src/forms/Workflows.js:127 +#: client/src/inventory-scripts/inventory-scripts.list.js:45 +#: client/src/lists/Credentials.js:59 +#: client/src/lists/Inventories.js:68 +#: client/src/lists/Projects.js:67 +#: client/src/lists/Teams.js:50 +#: client/src/lists/Templates.js:62 +#: client/src/lists/Users.js:58 +#: client/src/notifications/notificationTemplates.list.js:52 +msgid "ADD" +msgstr "AJOUTER" + +#: client/src/notifications/notifications.list.js:68 +msgid "ADD NOTIFICATION TEMPLATE" +msgstr "AJOUTER UN MODÈLE DE NOTIFICATION" + +#: client/src/forms/Credentials.js:199 +msgid "API Key" +msgstr "Clé API" + +#: client/src/notifications/notificationTemplates.form.js:248 +msgid "API Service/Integration Key" +msgstr "Service API/Clé d'intégration" + +#: client/src/notifications/shared/type-change.service.js:52 +msgid "API Token" +msgstr "Token API" + +#: client/src/setup-menu/setup-menu.partial.html:59 +msgid "About Tower" +msgstr "Tower" + +#: client/src/forms/Credentials.js:92 +msgid "Access Key" +msgstr "Clé d'accès" + +#: client/src/notifications/notificationTemplates.form.js:226 +msgid "Account SID" +msgstr "SID de compte" + +#: client/src/notifications/notificationTemplates.form.js:184 +msgid "Account Token" +msgstr "Token de compte" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:20 +#: client/src/shared/list-generator/list-generator.factory.js:538 +msgid "Actions" +msgstr "Actions" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:17 +#: client/src/lists/Templates.js:40 +msgid "Activity" +msgstr "Activité" + +#: client/src/configuration/system-form/configuration-system.controller.js:81 +msgid "Activity Stream" +msgstr "Flux d'activité" + +#: client/src/forms/Inventories.js:104 +#: client/src/forms/Inventories.js:150 +#: client/src/forms/Organizations.js:72 +#: client/src/forms/Teams.js:83 +#: client/src/forms/Workflows.js:124 +msgid "Add" +msgstr "Ajouter" + +#: client/src/lists/Credentials.js:17 +msgid "Add Credentials" +msgstr "Ajouter des informations d'identification" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:12 +msgid "Add Existing Hosts" +msgstr "Ajouter des hôtes existants" + +#: client/src/lists/Inventories.js:15 +msgid "Add Inventories" +msgstr "Ajouter des inventaires" + +#: client/src/notifications/notifications.list.js:63 +msgid "Add Notification" +msgstr "Ajouter une notification" + +#: client/src/lists/Projects.js:15 +msgid "Add Project" +msgstr "Ajouter un projet" + +#: client/src/forms/JobTemplates.js:459 +#: client/src/forms/Workflows.js:172 +#: client/src/shared/form-generator.js:1707 +msgid "Add Survey" +msgstr "Ajouter un questionnaire" + +#: client/src/lists/Teams.js:15 +msgid "Add Team" +msgstr "Ajouter une équipe" + +#: client/src/lists/Users.js:25 +msgid "Add Users" +msgstr "Ajouter des utilisateurs" + +#: client/src/forms/Credentials.js:440 +#: client/src/forms/Inventories.js:151 +#: client/src/forms/JobTemplates.js:412 +#: client/src/forms/Organizations.js:73 +#: client/src/forms/Projects.js:235 +msgid "Add a permission" +msgstr "Ajouter une permission" + +#: client/src/setup-menu/setup-menu.partial.html:23 +msgid "" +"Add passwords, SSH keys, etc. for Tower to use when launching jobs against " +"machines, or when syncing inventories or projects." +msgstr "" +"Ajouter des mots de passe, des clés SSH, etc. pour Tower afin de les " +"utiliser lors du lancement de tâches sur des machines ou durant la " +"synchronisation d'inventaires ou de projets." + +#: client/src/forms/Teams.js:84 +msgid "Add user to team" +msgstr "Ajouter un utilisateur à l'équipe" + +#: client/src/shared/form-generator.js:1450 +msgid "Admin" +msgstr "Administrateur" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:37 +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:43 +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:65 +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:74 +msgid "All" +msgstr "Tous" + +#: client/src/portal-mode/portal-mode-jobs.partial.html:7 +msgid "All Jobs" +msgstr "Toutes les tâches" + +#: client/src/forms/JobTemplates.js:299 +#: client/src/forms/JobTemplates.js:306 +msgid "Allow Provisioning Callbacks" +msgstr "Autoriser les rappels d'exécution de Tower job_template" + +#: client/src/setup-menu/setup-menu.partial.html:11 +msgid "Allow others to sign into Tower and own the content they create." +msgstr "" +"Autoriser les autres à se connecter à Tower et à devenir propriétaire du " +"contenu qu'ils créent." + +#: client/src/forms/WorkflowMaker.js:50 +msgid "Always" +msgstr "Toujours" + +#: client/src/controllers/Projects.js:220 +msgid "" +"An SCM update does not appear to be running for project: %s. Click the " +"%sRefresh%s button to view the latest status." +msgstr "" +"Une mise à jour SCM ne semble pas s'exécuter pour le projet : %s. Cliquez " +"sur le bouton %sActualiser%s pour voir l'état le plus récent." + +#: client/src/controllers/Projects.js:162 +msgid "Are you sure you want to delete the project below?" +msgstr "Voulez-vous vraiment supprimer le projet ci-dessous ?" + +#: client/src/controllers/Users.js:102 +msgid "Are you sure you want to delete the user below?" +msgstr "Voulez-vous vraiment supprimer l'utilisateur ci-dessous ?" + +#: client/src/controllers/Projects.js:647 +msgid "Are you sure you want to remove the %s below from %s?" +msgstr "Voulez-vous vraimment supprimer le %s ci-dessous de %s ?" + +#: client/src/forms/Credentials.js:233 +#: client/src/forms/Credentials.js:271 +#: client/src/forms/Credentials.js:310 +#: client/src/forms/Credentials.js:395 +msgid "Ask at runtime?" +msgstr "Demander durant l'éxecution ?" + +#: client/src/shared/form-generator.js:1452 +msgid "Auditor" +msgstr "Auditeur" + +#: client/src/forms/Credentials.js:73 +msgid "" +"Authentication for network device access. This can include SSH keys, " +"usernames, passwords, and authorize information. Network credentials are " +"used when submitting jobs to run playbooks against network devices." +msgstr "" +"Authentification pour l'accès aux périphériques réseau. Il peut s'agir de " +"clés SSH, de noms d'utilisateur, de mots de passe et d'informations " +"d'autorisation. Les informations d'identification réseau sont utilisées au " +"cours de l'envoi de tâches afin d'exécuter des playbooks sur des " +"périphériques réseau." + +#: client/src/forms/Credentials.js:69 +msgid "" +"Authentication for remote machine access. This can include SSH keys, " +"usernames, passwords, and sudo information. Machine credentials are used " +"when submitting jobs to run playbooks against remote hosts." +msgstr "" +"Authentification pour l'accès aux machines distantes. Il peut s'agir de clés " +"SSH, de noms d'utilisateur, de mots de passe et d'informations sudo. Les " +"informations d'identification de machine sont utilisées au cours de l'envoi " +"de tâches afin d'exécuter des playbooks sur des hôtes distants." + +#: client/src/forms/Credentials.js:341 +msgid "Authorize" +msgstr "Autoriser" + +#: client/src/forms/Credentials.js:349 +msgid "Authorize Password" +msgstr "Mot de passe d'autorisation" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:101 +msgid "Azure AD" +msgstr "Azure AD" + +#: client/src/forms/Projects.js:80 +msgid "" +"Base path used for locating playbooks. Directories found inside this path " +"will be listed in the playbook directory drop-down. Together the base path " +"and selected playbook directory provide the full path used to locate " +"playbooks." +msgstr "" +"Chemin de base utilisé pour localiser les playbooks. Les répertoires " +"localisés dans ce chemin sont répertoriés dans la liste déroulante des " +"répertoires de playbooks. Le chemin de base et le répertoire de playbook " +"sélectionnés fournissent ensemble le chemin complet servant à localiser les " +"playbooks." + +#: client/src/forms/JobTemplates.js:293 +msgid "Become Privilege Escalation" +msgstr "Activer l'élévation des privilèges" + +#: client/src/license/license.partial.html:104 +msgid "Browse" +msgstr "Parcourir" + +#: client/src/app.js:317 +msgid "CREDENTIALS" +msgstr "INFORMATIONS D'IDENTIFICATION" + +#: client/src/forms/Projects.js:194 +msgid "Cache Timeout" +msgstr "Expiration du délai d'attente du cache" + +#: client/src/forms/Projects.js:183 +msgid "Cache Timeout%s (seconds)%s" +msgstr "Expiration du délai d'attente du cache%s (secondes)%s" + +#: client/src/controllers/Projects.js:156 +#: client/src/controllers/Users.js:95 +msgid "Call to %s failed. DELETE returned status:" +msgstr "Échec de l'appel de %s. État DELETE renvoyé :" + +#: client/src/controllers/Projects.js:201 +#: client/src/controllers/Projects.js:217 +msgid "Call to %s failed. GET status:" +msgstr "Échec de l'appel de %s. État GET :" + +#: client/src/controllers/Projects.js:641 +msgid "Call to %s failed. POST returned status:" +msgstr "Échec de l'appel de %s. État POST renvoyé :" + +#: client/src/controllers/Projects.js:180 +msgid "Call to %s failed. POST status:" +msgstr "Échec de l'appel de %s. État POST :" + +#: client/src/controllers/Projects.js:226 +msgid "Call to get project failed. GET status:" +msgstr "Échec de l'appel du projet en GET. État GET :" + +#: client/src/configuration/configuration.controller.js:434 +#: client/src/shared/form-generator.js:1695 +msgid "Cancel" +msgstr "Annuler" + +#: client/src/controllers/Projects.js:196 +msgid "Cancel Not Allowed" +msgstr "Annulation non autorisée" + +#: client/src/lists/Projects.js:121 +msgid "Cancel the SCM update" +msgstr "Annuler la mise à jour SCM" + +#: client/src/controllers/Projects.js:53 +msgid "Canceled. Click for details" +msgstr "Annulé. Cliquez pour connaître les détails." + +#: client/src/forms/Projects.js:82 +msgid "Change %s under \"Configure Tower\" to change this location." +msgstr "Modifiez %s sous \"Configurer Tower\" pour changer d'emplacement." + +#: client/src/shared/form-generator.js:1084 +msgid "Choose a %s" +msgstr "Choisir un %s" + +#: client/src/license/license.partial.html:97 +msgid "" +"Choose your license file, agree to the End User License Agreement, and click " +"submit." +msgstr "" +"Choisissez votre fichier de licence, acceptez le Contrat de licence de " +"l'utilisateur final et validez." + +#: client/src/forms/Projects.js:151 +msgid "Clean" +msgstr "Nettoyer" + +#: client/src/lists/Inventories.js:18 +msgid "" +"Click on a row to select it, and click Finished when done. Click the %s " +"button to create a new inventory." +msgstr "" +"Cliquez sur une ligne pour la sélectionner, puis sur Terminé lorsque vous " +"avez fini. Cliquez sur le bouton %s pour créer un inventaire." + +#: client/src/lists/Teams.js:18 +msgid "" +"Click on a row to select it, and click Finished when done. Click the %s " +"button to create a new team." +msgstr "" +"Cliquez sur une ligne pour la sélectionner, puis sur Terminé lorsque vous " +"avez fini. Cliquez sur le bouton %s pour créer une équipe." + +#: client/src/lists/Templates.js:19 +msgid "" +"Click on a row to select it, and click Finished when done. Use the %s button " +"to create a new job template." +msgstr "" +"Cliquez sur une ligne pour la sélectionner, puis sur Terminé lorsque vous " +"avez fini. Cliquez sur le bouton %s pour créer un modèle de tâche." + +#: client/src/forms/Credentials.js:319 +msgid "Client ID" +msgstr "ID du client" + +#: client/src/notifications/notificationTemplates.form.js:259 +msgid "Client Identifier" +msgstr "Identifiant client" + +#: client/src/forms/Credentials.js:328 +msgid "Client Secret" +msgstr "Question secrète du client" + +#: client/src/shared/form-generator.js:1699 +msgid "Close" +msgstr "Fermer" + +#: client/src/forms/JobTemplates.js:164 +#: client/src/forms/JobTemplates.js:176 +msgid "Cloud Credential" +msgstr "Informations d'identification cloud" + +#: client/src/helpers/Credentials.js:158 +msgid "CloudForms Host" +msgstr "Hôte CloudForms" + +#: client/src/notifications/notificationTemplates.form.js:295 +msgid "Color can be one of %s." +msgstr "La couleur peut être l'une des %s." + +#: client/src/lists/CompletedJobs.js:18 +msgid "Completed Jobs" +msgstr "Tâches terminées" + +#: client/src/management-jobs/card/card.partial.html:32 +msgid "Configure Notifications" +msgstr "Configurer les notifications" + +#: client/src/forms/Users.js:82 +msgid "Confirm Password" +msgstr "Confirmer le mot de passe" + +#: client/src/configuration/configuration.controller.js:441 +msgid "Confirm Reset" +msgstr "Confirmer la réinitialisation" + +#: client/src/configuration/configuration.controller.js:450 +msgid "Confirm factory reset" +msgstr "Confirmer la réinitialisation usine" + +#: client/src/forms/JobTemplates.js:255 +#: client/src/forms/JobTemplates.js:273 +#: client/src/forms/WorkflowMaker.js:141 +#: client/src/forms/WorkflowMaker.js:156 +msgid "" +"Consult the Ansible documentation for further details on the usage of tags." +msgstr "" +"Consultez la documentation d'Ansible pour en savoir plus sur l'utilisation " +"des balises." + +#: client/src/forms/JobTemplates.js:241 +msgid "" +"Control the level of output ansible will produce as the playbook executes." +msgstr "" +"Contrôlez le niveau de sortie qu'Ansible génère lors de l'exécution du " +"playbook." + +#: client/src/lists/Templates.js:100 +msgid "Copy" +msgstr "Copier" + +#: client/src/lists/Templates.js:103 +msgid "Copy template" +msgstr "Copier le modèle" + +#: client/src/forms/Credentials.js:18 +msgid "Create Credential" +msgstr "Créer des informations d'identification" + +#: client/src/lists/Users.js:52 +msgid "Create New" +msgstr "Créer" + +#: client/src/lists/Credentials.js:57 +msgid "Create a new credential" +msgstr "Créer de nouvelles informations d'identification" + +#: client/src/inventory-scripts/inventory-scripts.list.js:43 +msgid "Create a new custom inventory" +msgstr "Créer un inventaire personnalisé" + +#: client/src/lists/Inventories.js:66 +msgid "Create a new inventory" +msgstr "Créer un inventaire" + +#: client/src/notifications/notificationTemplates.list.js:50 +#: client/src/notifications/notifications.list.js:66 +msgid "Create a new notification template" +msgstr "Créer un modèle de notification" + +#: client/src/organizations/list/organizations-list.partial.html:16 +msgid "Create a new organization" +msgstr "Créer une organisation" + +#: client/src/lists/Projects.js:65 +msgid "Create a new project" +msgstr "Créer un projet" + +#: client/src/lists/Teams.js:48 +msgid "Create a new team" +msgstr "Créer une équipe" + +#: client/src/lists/Templates.js:60 +msgid "Create a new template" +msgstr "Créer un modèle" + +#: client/src/lists/Users.js:56 +msgid "Create a new user" +msgstr "Créer un utilisateur" + +#: client/src/setup-menu/setup-menu.partial.html:35 +msgid "Create and edit scripts to dynamically load hosts from any source." +msgstr "" +"Créez et modifiez des scripts pour charger dynamiquement des hôtes à partir " +"de n'importe quelle source." + +#: client/src/setup-menu/setup-menu.partial.html:42 +msgid "" +"Create templates for sending notifications with Email, HipChat, Slack, and " +"SMS." +msgstr "" +"Créer des modèles pour envoyer des notifications via email, HipChat, Slack, " +"et SMS." + +#: client/src/forms/JobTemplates.js:154 +#: client/src/forms/WorkflowMaker.js:60 +#: client/src/forms/WorkflowMaker.js:69 +msgid "Credential" +msgstr "Information d'identification" + +#: client/src/lists/Credentials.js:18 +#: client/src/lists/Credentials.js:19 +#: client/src/setup-menu/setup-menu.partial.html:22 +msgid "Credentials" +msgstr "Informations d'identification" + +#: client/src/inventory-scripts/inventory-scripts.form.js:50 +#: client/src/inventory-scripts/inventory-scripts.form.js:60 +msgid "Custom Script" +msgstr "Script personnalisé" + +#: client/src/app.js:409 +msgid "DASHBOARD" +msgstr "TABLEAU DE BORD" + +#: client/src/controllers/Projects.js:649 +#: client/src/controllers/Users.js:104 +msgid "DELETE" +msgstr "SUPPRIMER" + +#: client/src/controllers/Projects.js:161 +#: client/src/controllers/Projects.js:646 +#: client/src/controllers/Users.js:101 +#: client/src/inventory-scripts/inventory-scripts.list.js:74 +#: client/src/lists/Credentials.js:90 +#: client/src/lists/Inventories.js:92 +#: client/src/lists/Teams.js:77 +#: client/src/lists/Templates.js:125 +#: client/src/lists/Users.js:87 +#: client/src/notifications/notificationTemplates.list.js:89 +msgid "Delete" +msgstr "Supprimer" + +#: client/src/lists/Credentials.js:92 +msgid "Delete credential" +msgstr "Supprimer les informations d'identification" + +#: client/src/lists/Inventories.js:94 +msgid "Delete inventory" +msgstr "Supprimer l'inventaire" + +#: client/src/inventory-scripts/inventory-scripts.list.js:76 +msgid "Delete inventory script" +msgstr "Supprimer le script d'inventaire" + +#: client/src/notifications/notificationTemplates.list.js:91 +msgid "Delete notification" +msgstr "Supprimer la notification" + +#: client/src/forms/Projects.js:161 +msgid "Delete on Update" +msgstr "Supprimer lors de la mise à jour" + +#: client/src/lists/Teams.js:81 +msgid "Delete team" +msgstr "Supprimer l'équipe" + +#: client/src/lists/Templates.js:128 +msgid "Delete template" +msgstr "Supprimer le modèle" + +#: client/src/lists/CompletedJobs.js:82 +msgid "Delete the job" +msgstr "Supprimer la tâche" + +#: client/src/forms/Projects.js:163 +msgid "" +"Delete the local repository in its entirety prior to performing an update." +msgstr "" +"Supprimer le référentiel local dans son intégralité avant de lancer la mise " +"à jour." + +#: client/src/lists/Projects.js:115 +msgid "Delete the project" +msgstr "Supprimer le projet" + +#: client/src/lists/ScheduledJobs.js:80 +msgid "Delete the schedule" +msgstr "Supprimer la planification" + +#: client/src/lists/Users.js:91 +msgid "Delete user" +msgstr "Supprimer l'utilisateur" + +#: client/src/forms/Projects.js:163 +msgid "" +"Depending on the size of the repository this may significantly increase the " +"amount of time required to complete an update." +msgstr "" +"Selon la taille du référentiel, cette opération risque d'augmenter " +"considérablement le délai d'exécution de la mise à jour." + +#: client/src/forms/Credentials.js:41 +#: client/src/forms/Inventories.js:37 +#: client/src/forms/JobTemplates.js:42 +#: client/src/forms/Organizations.js:33 +#: client/src/forms/Projects.js:38 +#: client/src/forms/Teams.js:34 +#: client/src/forms/Users.js:142 +#: client/src/forms/Users.js:167 +#: client/src/forms/Workflows.js:41 +#: client/src/inventory-scripts/inventory-scripts.form.js:32 +#: client/src/inventory-scripts/inventory-scripts.list.js:25 +#: client/src/lists/Credentials.js:34 +#: client/src/lists/PortalJobTemplates.js:29 +#: client/src/lists/Teams.js:30 +#: client/src/lists/Templates.js:36 +#: client/src/notifications/notificationTemplates.form.js:36 +msgid "Description" +msgstr "Description" + +#: client/src/notifications/notificationTemplates.form.js:138 +#: client/src/notifications/notificationTemplates.form.js:143 +#: client/src/notifications/notificationTemplates.form.js:155 +#: client/src/notifications/notificationTemplates.form.js:160 +#: client/src/notifications/notificationTemplates.form.js:372 +msgid "Destination Channels" +msgstr "Canaux de destination" + +#: client/src/notifications/notificationTemplates.form.js:367 +msgid "Destination Channels or Users" +msgstr "Canaux de destination pour les utilisateurs" + +#: client/src/notifications/notificationTemplates.form.js:209 +#: client/src/notifications/notificationTemplates.form.js:214 +msgid "Destination SMS Number" +msgstr "Numéro SMS de destination" + +#: client/src/license/license.partial.html:5 +#: client/src/shared/form-generator.js:1481 +msgid "Details" +msgstr "Détails" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:70 +#: client/src/configuration/configuration.controller.js:170 +#: client/src/configuration/configuration.controller.js:232 +#: client/src/configuration/system-form/configuration-system.controller.js:49 +msgid "Discard changes" +msgstr "Ignorer les modifications" + +#: client/src/forms/Teams.js:148 +msgid "Dissasociate permission from team" +msgstr "Dissocier la permission de l'équipe" + +#: client/src/forms/Users.js:217 +msgid "Dissasociate permission from user" +msgstr "Dissocier la permission de l'utilisateur" + +#: client/src/forms/Credentials.js:382 +#: client/src/helpers/Credentials.js:133 +msgid "Domain Name" +msgstr "Nom de domaine" + +#: client/src/inventory-scripts/inventory-scripts.form.js:58 +msgid "" +"Drag and drop your custom inventory script file here or create one in the " +"field to import your custom inventory." +msgstr "" +"Faites glisser votre script d'inventaire personnalisé et déposez-le ici ou " +"créez-en un dans le champ pour importer votre inventaire personnalisé." + +#: client/src/forms/Projects.js:174 +msgid "" +"Each time a job runs using this project, perform an update to the local " +"repository prior to starting the job." +msgstr "" +"Chaque fois qu'une tâche s'exécute avec ce projet, réalisez une mise à jour " +"dans le référentiel local avant de lancer la tâche." + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:63 +#: client/src/inventory-scripts/inventory-scripts.list.js:57 +#: client/src/lists/Credentials.js:71 +#: client/src/lists/Inventories.js:78 +#: client/src/lists/Teams.js:60 +#: client/src/lists/Templates.js:108 +#: client/src/lists/Users.js:68 +#: client/src/notifications/notificationTemplates.list.js:63 +#: client/src/notifications/notificationTemplates.list.js:72 +msgid "Edit" +msgstr "Modifier" + +#: client/src/forms/JobTemplates.js:466 +#: client/src/forms/Workflows.js:179 +#: client/src/shared/form-generator.js:1711 +msgid "Edit Survey" +msgstr "Modifier le questionnaire" + +#: client/src/lists/Credentials.js:73 +msgid "Edit credential" +msgstr "Modifier les informations d'identification" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:66 +msgid "Edit host" +msgstr "Modifier l'hôte" + +#: client/src/lists/Inventories.js:80 +msgid "Edit inventory" +msgstr "Modifier l'inventaire" + +#: client/src/inventory-scripts/inventory-scripts.list.js:59 +msgid "Edit inventory script" +msgstr "Modifier le script d'inventaire" + +#: client/src/notifications/notificationTemplates.list.js:74 +msgid "Edit notification" +msgstr "Modifier la notification" + +#: client/src/lists/Teams.js:64 +msgid "Edit team" +msgstr "Modifier l'équipe" + +#: client/src/lists/Templates.js:110 +msgid "Edit template" +msgstr "Modifier le modèle" + +#: client/src/lists/Projects.js:102 +msgid "Edit the project" +msgstr "Modifier le projet" + +#: client/src/lists/ScheduledJobs.js:66 +msgid "Edit the schedule" +msgstr "Modifier la planification" + +#: client/src/lists/Users.js:72 +msgid "Edit user" +msgstr "Modifier l'utilisateur" + +#: client/src/controllers/Projects.js:196 +msgid "" +"Either you do not have access or the SCM update process completed. Click the " +"%sRefresh%s button to view the latest status." +msgstr "" +"Vous n'avez pas accès, ou la mise à jour SCM est terminée. Cliquez sur le " +"bouton %sActualiser%s pour voir l'état le plus récent." + +#: client/src/forms/Credentials.js:192 +#: client/src/forms/Users.js:42 +msgid "Email" +msgstr "Email" + +#: client/src/forms/JobTemplates.js:288 +msgid "Enable Privilege Escalation" +msgstr "Activer l'élévation des privilèges" + +#: client/src/forms/JobTemplates.js:303 +msgid "" +"Enables creation of a provisioning callback URL. Using the URL a host can " +"contact Tower and request a configuration update using this job template." +msgstr "" +"Active la création d'une URL de rappels d'exécution de Tower job_template. " +"Avec cette URL, un hôte peut contacter Tower et demander une mise à jour de " +"la configuration à l'aide de ce modèle de tâche." + +#: client/src/helpers/Credentials.js:306 +msgid "Encrypted credentials are not supported." +msgstr "" +"Les informations d'identification chiffrées ne sont pas prises en charge." + +#: client/src/license/license.partial.html:108 +msgid "End User License Agreement" +msgstr "Contrat de licence de l'utilisateur final" + +#: client/src/forms/Inventories.js:60 +msgid "" +"Enter inventory variables using either JSON or YAML syntax. Use the radio " +"button to toggle between the two." +msgstr "" +"Entrez les variables d'inventaire avec la syntaxe JSON ou YAML. Utilisez le " +"bouton radio pour basculer entre les deux." + +#: client/src/helpers/Credentials.js:159 +msgid "" +"Enter the hostname or IP address for the virtual %s machine which is hosting " +"the CloudForm appliance." +msgstr "" +"Entrez le nom d'hôte ou l'adresse IP de la machine %s virtuelle qui héberge " +"l'appliance CloudForm." + +#: client/src/helpers/Credentials.js:150 +msgid "" +"Enter the hostname or IP address name which %scorresponds to your Red Hat " +"Satellite 6 server." +msgstr "" +"Entrez le nom d'hôte ou l'adresse IP qui %scorrespond à votre serveur Red " +"Hat Satellite 6." + +#: client/src/helpers/Credentials.js:128 +msgid "" +"Enter the hostname or IP address which corresponds to your VMware vCenter." +msgstr "" +"Entrez le nom d'hôte ou l'adresse IP qui correspond à votre VMware vCenter." + +#: client/src/configuration/configuration.controller.js:292 +#: client/src/configuration/configuration.controller.js:370 +#: client/src/configuration/configuration.controller.js:404 +#: client/src/configuration/configuration.controller.js:423 +#: client/src/controllers/Projects.js:133 +#: client/src/controllers/Projects.js:155 +#: client/src/controllers/Projects.js:180 +#: client/src/controllers/Projects.js:201 +#: client/src/controllers/Projects.js:216 +#: client/src/controllers/Projects.js:225 +#: client/src/controllers/Projects.js:363 +#: client/src/controllers/Projects.js:557 +#: client/src/controllers/Projects.js:623 +#: client/src/controllers/Projects.js:641 +#: client/src/controllers/Users.js:182 +#: client/src/controllers/Users.js:267 +#: client/src/controllers/Users.js:321 +#: client/src/controllers/Users.js:94 +#: client/src/helpers/Credentials.js:310 +#: client/src/helpers/Credentials.js:326 +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:119 +msgid "Error!" +msgstr "Erreur !" + +#: client/src/controllers/Projects.js:381 +#: client/src/controllers/Projects.js:664 +msgid "Example URLs for GIT SCM include:" +msgstr "Exemples d'URL pour le SCM GIT :" + +#: client/src/controllers/Projects.js:394 +#: client/src/controllers/Projects.js:676 +msgid "Example URLs for Mercurial SCM include:" +msgstr "Exemples d'URL pour le SCM Mercurial :" + +#: client/src/controllers/Projects.js:389 +#: client/src/controllers/Projects.js:671 +msgid "Example URLs for Subversion SCM include:" +msgstr "Exemples d'URL pour le SCM Subversion :" + +#: client/src/license/license.partial.html:39 +msgid "Expires On" +msgstr "Arrive à expiration le" + +#: client/src/forms/JobTemplates.js:352 +#: client/src/forms/JobTemplates.js:364 +#: client/src/forms/Workflows.js:72 +#: client/src/forms/Workflows.js:84 +msgid "Extra Variables" +msgstr "Variables supplémentaires" + +#: client/src/dashboard/graphs/job-status/job-status-graph.directive.js:67 +msgid "FAILED" +msgstr "ÉCHEC" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:80 +msgid "Failed" +msgstr "Échec" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:44 +msgid "Failed Hosts" +msgstr "Échec des hôtes" + +#: client/src/controllers/Users.js:182 +msgid "Failed to add new user. POST returned status:" +msgstr "L'ajout de l'utilisateur a échoué. État POST renvoyé :" + +#: client/src/helpers/Credentials.js:311 +msgid "Failed to create new Credential. POST status:" +msgstr "La création des informations d'identification a échoué. État POST :" + +#: client/src/controllers/Projects.js:364 +msgid "Failed to create new project. POST returned status:" +msgstr "La création du projet a échoué. État POST renvoyé :" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:120 +msgid "Failed to get third-party login types. Returned status:" +msgstr "L'obtention des types de connexion tiers a échoué. État renvoyé :" + +#: client/src/controllers/Projects.js:558 +msgid "Failed to retrieve project: %s. GET status:" +msgstr "La récupération du projet a échoué : %s. État GET :" + +#: client/src/controllers/Users.js:268 +#: client/src/controllers/Users.js:322 +msgid "Failed to retrieve user: %s. GET status:" +msgstr "La récupération de l'utilisateur a échoué : %s. État GET :" + +#: client/src/configuration/configuration.controller.js:371 +msgid "Failed to save settings. Returned status:" +msgstr "L'enregistrement des paramètres a échoué. État renvoyé :" + +#: client/src/configuration/configuration.controller.js:405 +msgid "Failed to save toggle settings. Returned status:" +msgstr "" +"L'enregistrement des paramètres d'activation/désactivation a échoué. État " +"renvoyé :" + +#: client/src/helpers/Credentials.js:327 +msgid "Failed to update Credential. PUT status:" +msgstr "La mise à jour des informations d'identification a échoué. État PUT :" + +#: client/src/controllers/Projects.js:623 +msgid "Failed to update project: %s. PUT status:" +msgstr "La mise à jour du projet a échoué : %s. État PUT :" + +#: client/src/notifications/notifications.list.js:49 +msgid "Failure" +msgstr "Défaillance" + +#: client/src/lists/CompletedJobs.js:56 +#: client/src/lists/PortalJobs.js:37 +msgid "Finished" +msgstr "Terminé" + +#: client/src/forms/Users.js:28 +#: client/src/lists/Users.js:41 +msgid "First Name" +msgstr "Prénom" + +#: client/src/helpers/Credentials.js:142 +msgid "For example, %s" +msgstr "Par exemple, %s" + +#: client/src/notifications/notificationTemplates.form.js:142 +#: client/src/notifications/notificationTemplates.form.js:159 +#: client/src/notifications/notificationTemplates.form.js:213 +#: client/src/notifications/notificationTemplates.form.js:333 +#: client/src/notifications/notificationTemplates.form.js:371 +#: client/src/notifications/notificationTemplates.form.js:98 +msgid "For example:" +msgstr "Par exemple :" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:54 +msgid "" +"For hosts that are part of an external inventory, this flag cannot be " +"changed. It will be set by the inventory sync process." +msgstr "" +"Pour les hôtes qui font partie d'un inventaire externe, ce marqueur ne peut " +"pas être modifié. Il sera défini par le processus de synchronisation des " +"inventaires." + +#: client/src/forms/JobTemplates.js:223 +#: client/src/forms/WorkflowMaker.js:125 +msgid "" +"For more information and examples see %sthe Patterns topic at docs.ansible." +"com%s." +msgstr "" +"Pour obtenir plus d'informations et voir des exemples, reportez-vous à la " +"rubrique %Patterns sur docs.ansible.com%s." + +#: client/src/forms/JobTemplates.js:199 +#: client/src/forms/JobTemplates.js:212 +msgid "Forks" +msgstr "Forks" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:102 +msgid "GitHub" +msgstr "GitHub" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:103 +msgid "GitHub Org" +msgstr "GitHub Org" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:104 +msgid "GithHub Team" +msgstr "Équipe GithHub" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:105 +msgid "Google OAuth2" +msgstr "Google OAuth2" + +#: client/src/forms/Teams.js:118 +msgid "Granted Permissions" +msgstr "Permissions accordées" + +#: client/src/forms/Users.js:183 +msgid "Granted permissions" +msgstr "Permissions accordées" + +#: client/src/setup-menu/setup-menu.partial.html:5 +msgid "" +"Group all of your content to manage permissions across departments in your " +"company." +msgstr "" +"Regroupez l'ensemble du contenu pour gérer les permissions entre les " +"différents services de votre entreprise." + +#: client/src/notifications/notificationTemplates.form.js:324 +msgid "HTTP Headers" +msgstr "En-têtes HTTP" + +#: client/src/forms/Credentials.js:140 +#: client/src/notifications/notificationTemplates.form.js:72 +msgid "Host" +msgstr "Hôte" + +#: client/src/helpers/Credentials.js:131 +msgid "Host (Authentication URL)" +msgstr "Hôte (URL d'authentification)" + +#: client/src/forms/JobTemplates.js:326 +#: client/src/forms/JobTemplates.js:335 +msgid "Host Config Key" +msgstr "Clé de configuration de l'hôte" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:55 +msgid "Host Enabled" +msgstr "Hôte activé" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:39 +msgid "Hosts" +msgstr "Hôtes" + +#: client/src/license/license.partial.html:52 +msgid "Hosts Available" +msgstr "Hôtes disponibles" + +#: client/src/license/license.partial.html:64 +msgid "Hosts Remaining" +msgstr "Hôtes restants" + +#: client/src/license/license.partial.html:58 +msgid "Hosts Used" +msgstr "Hôtes utilisés" + +#: client/src/license/license.partial.html:116 +msgid "I agree to the End User License Agreement" +msgstr "J'accepte le Contrat de licence de l'utilisateur final" + +#: client/src/main-menu/main-menu.partial.html:104 +#: client/src/main-menu/main-menu.partial.html:27 +msgid "INVENTORIES" +msgstr "INVENTAIRES" + +#: client/src/notifications/notificationTemplates.form.js:356 +msgid "IRC Nick" +msgstr "Surnom IRC" + +#: client/src/notifications/notificationTemplates.form.js:345 +msgid "IRC Server Address" +msgstr "Adresse du serveur IRC" + +#: client/src/notifications/shared/type-change.service.js:58 +msgid "IRC Server Password" +msgstr "Mot de passe du serveur IRC" + +#: client/src/notifications/shared/type-change.service.js:57 +msgid "IRC Server Port" +msgstr "Port du serveur IRC" + +#: client/src/forms/JobTemplates.js:291 +msgid "" +"If enabled, run this playbook as an administrator. This is the equivalent of " +"passing the %s option to the %s command." +msgstr "" +"Si cette option est activée, exécutez ce playbook en tant qu'administrateur. " +"Cette opération revient à transmettre l'option %s à la commande %s." + +#: client/src/forms/Credentials.js:54 +msgid "" +"If no organization is given, the credential can only be used by the user " +"that creates the credential. Organization admins and system administrators " +"can assign an organization so that roles for the credential can be assigned " +"to users and teams in that organization." +msgstr "" +"Si aucune organisation n'est renseignée, les informations d'identification " +"ne peuvent être utilisées que par l'utilisateur qui les crée. Les " +"administrateurs d'organisation et les administrateurs système peuvent " +"assigner une organisation pour que les rôles liés aux informations " +"d'identification puissent être associés aux utilisateurs et aux équipes de " +"cette organisation." + +#: client/src/license/license.partial.html:70 +msgid "" +"If you are ready to upgrade, please contact us by clicking the button below" +msgstr "" +"Si vous êtes prêt à effectuer une mise à niveau, contactez-nous en cliquant " +"sur le bouton ci-dessous" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:54 +msgid "" +"Indicates if a host is available and should be included in running jobs." +msgstr "" +"Indique si un hôte est disponible et doit être ajouté aux tâches en cours " +"d'exécution." + +#: client/src/forms/JobTemplates.js:58 +msgid "" +"Instead, %s will check playbook syntax, test environment setup and report " +"problems." +msgstr "" +"À la place, %s vérifie la syntaxe du playbook, teste la configuration de " +"l'environnement et signale les problèmes." + +#: client/src/license/license.partial.html:11 +msgid "Invalid License" +msgstr "Licence non valide" + +#: client/src/license/license.controller.js:69 +#: client/src/license/license.controller.js:76 +msgid "Invalid file format. Please upload valid JSON." +msgstr "Format de fichier non valide. Chargez un fichier JSON valide." + +#: client/src/login/loginModal/loginModal.partial.html:34 +msgid "Invalid username and/or password. Please try again." +msgstr "Nom d'utilisateur et/ou mot de passe non valide. Veuillez réessayer." + +#: client/src/dashboard/counts/dashboard-counts.directive.js:50 +#: client/src/lists/Inventories.js:16 +#: client/src/lists/Inventories.js:17 +msgid "Inventories" +msgstr "Inventaires" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:41 +#: client/src/forms/JobTemplates.js:73 +#: client/src/forms/JobTemplates.js:86 +#: client/src/forms/WorkflowMaker.js:79 +#: client/src/forms/WorkflowMaker.js:89 +msgid "Inventory" +msgstr "Inventaire" + +#: client/src/inventory-scripts/inventory-scripts.list.js:12 +#: client/src/setup-menu/setup-menu.partial.html:34 +msgid "Inventory Scripts" +msgstr "Scripts d'inventaire" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:46 +msgid "Inventory Sync" +msgstr "Synchronisation des inventaires" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:55 +msgid "Inventory Sync Failures" +msgstr "Erreurs de synchronisation des inventaires" + +#: client/src/forms/Inventories.js:67 +msgid "Inventory Variables" +msgstr "Variables d'inventaire" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:4 +msgid "JOB STATUS" +msgstr "ÉTAT DE LA TÂCHE" + +#: client/src/forms/JobTemplates.js:23 +msgid "JOB TEMPLATE" +msgstr "MODÈLES DE TÂCHE" + +#: client/src/app.js:429 +#: client/src/dashboard/graphs/job-status/job-status-graph.directive.js:113 +#: client/src/main-menu/main-menu.partial.html:122 +#: client/src/main-menu/main-menu.partial.html:43 +msgid "JOBS" +msgstr "TÂCHES" + +#: client/src/forms/JobTemplates.js:248 +#: client/src/forms/JobTemplates.js:256 +#: client/src/forms/WorkflowMaker.js:134 +#: client/src/forms/WorkflowMaker.js:142 +msgid "Job Tags" +msgstr "Balises de tâche" + +#: client/src/lists/Templates.js:65 +msgid "Job Template" +msgstr "Modèle de tâche" + +#: client/src/lists/PortalJobTemplates.js:15 +#: client/src/lists/PortalJobTemplates.js:16 +msgid "Job Templates" +msgstr "Modèles de tâche" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:32 +#: client/src/forms/JobTemplates.js:48 +#: client/src/forms/JobTemplates.js:62 +#: client/src/forms/WorkflowMaker.js:110 +#: client/src/forms/WorkflowMaker.js:99 +msgid "Job Type" +msgstr "Type de tâche" + +#: client/src/lists/PortalJobs.js:15 +#: client/src/lists/PortalJobs.js:19 +#: client/src/partials/jobs.html:7 +msgid "Jobs" +msgstr "Tâches" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:106 +msgid "LDAP" +msgstr "LDAP" + +#: client/src/main-menu/main-menu.partial.html:83 +msgid "LOG OUT" +msgstr "SE DÉCONNECTER" + +#: client/src/notifications/notificationTemplates.form.js:270 +msgid "Label to be shown with notification" +msgstr "Libellé à afficher avec la notification" + +#: client/src/forms/JobTemplates.js:340 +#: client/src/forms/JobTemplates.js:345 +#: client/src/forms/Workflows.js:60 +#: client/src/forms/Workflows.js:65 +#: client/src/lists/Templates.js:47 +msgid "Labels" +msgstr "Libellés" + +#: client/src/forms/Users.js:35 +#: client/src/lists/Users.js:45 +msgid "Last Name" +msgstr "Nom" + +#: client/src/lists/Projects.js:53 +msgid "Last Updated" +msgstr "Dernière mise à jour" + +#: client/src/lists/PortalJobTemplates.js:39 +#: client/src/lists/Templates.js:84 +#: client/src/shared/form-generator.js:1703 +msgid "Launch" +msgstr "Lancer" + +#: client/src/management-jobs/card/card.partial.html:21 +msgid "Launch Management Job" +msgstr "Lancer la tâche de gestion" + +#: client/src/license/license.controller.js:42 +#: client/src/license/license.partial.html:8 +msgid "License" +msgstr "Licence" + +#: client/src/license/license.partial.html:102 +msgid "License File" +msgstr "Fichier de licence" + +#: client/src/license/license.partial.html:33 +msgid "License Key" +msgstr "Clé de licence" + +#: client/src/license/license.controller.js:42 +msgid "License Management" +msgstr "Gestion des licences" + +#: client/src/license/license.partial.html:21 +msgid "License Type" +msgstr "Type de licence" + +#: client/src/forms/JobTemplates.js:218 +#: client/src/forms/JobTemplates.js:225 +#: client/src/forms/WorkflowMaker.js:120 +#: client/src/forms/WorkflowMaker.js:127 +msgid "Limit" +msgstr "Limite" + +#: client/src/shared/socket/socket.service.js:170 +msgid "Live events: attempting to connect to the Tower server." +msgstr "Événements en direct : tentative de connexion au serveur Tower." + +#: client/src/shared/socket/socket.service.js:174 +msgid "" +"Live events: connected. Pages containing job status information will " +"automatically update in real-time." +msgstr "" +"Événements en direct : connecté. Les pages contenant des informations sur " +"l'état de la tâche seront automatiquement mises à jour en temps réel." + +#: client/src/shared/socket/socket.service.js:178 +msgid "Live events: error connecting to the Tower server." +msgstr "Événements en direct : erreur de connexion au serveur Tower." + +#: client/src/shared/form-generator.js:1977 +msgid "Loading..." +msgstr "Chargement en cours..." + +#: client/src/main-menu/main-menu.partial.html:188 +msgid "Log Out" +msgstr "Se déconnecter" + +#: client/src/configuration/system-form/configuration-system.controller.js:82 +msgid "Logging" +msgstr "Journalisation" + +#: client/src/management-jobs/card/card.route.js:21 +msgid "MANAGEMENT JOBS" +msgstr "TÂCHES DE GESTION" + +#: client/src/forms/Credentials.js:68 +msgid "Machine" +msgstr "Machine" + +#: client/src/forms/JobTemplates.js:137 +msgid "Machine Credential" +msgstr "Informations d'identification de la machine" + +#: client/src/setup-menu/setup-menu.partial.html:29 +msgid "" +"Manage the cleanup of old job history, activity streams, data marked for " +"deletion, and system tracking info." +msgstr "" +"Gérez le nettoyage de l'historique des anciennes tâches, des flux " +"d’activité, des données marquées pour suppression et des informations de " +"suivi du système." + +#: client/src/helpers/Credentials.js:111 +msgid "Management Certificate" +msgstr "Certificat de gestion" + +#: client/src/management-jobs/card/card.partial.html:4 +#: client/src/setup-menu/setup-menu.partial.html:28 +msgid "Management Jobs" +msgstr "Tâches de gestion" + +#: client/src/controllers/Projects.js:62 +msgid "Manual projects do not require a schedule" +msgstr "Les projets manuels ne nécessitent pas de planification" + +#: client/src/controllers/Projects.js:547 +#: client/src/controllers/Projects.js:61 +msgid "Manual projects do not require an SCM update" +msgstr "Les projets manuels ne nécessitent pas de mise à jour SCM" + +#: client/src/login/loginModal/loginModal.partial.html:28 +msgid "Maximum per-user sessions reached. Please sign in." +msgstr "" +"Nombre maximum de sessions par utilisateur atteintes. Veuillez vous " +"connecter." + +#: client/src/configuration/system-form/configuration-system.controller.js:80 +msgid "Misc. System" +msgstr "Système divers" + +#: client/src/portal-mode/portal-mode-jobs.partial.html:4 +msgid "My Jobs" +msgstr "Mes tâches" + +#: client/src/main-menu/main-menu.partial.html:160 +msgid "My View" +msgstr "Ma vue" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:18 +msgid "NO HOSTS FOUND" +msgstr "AUCUN HÔTE DÉTECTÉ" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:14 +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:13 +#: client/src/forms/Credentials.js:34 +#: client/src/forms/Inventories.js:29 +#: client/src/forms/JobTemplates.js:35 +#: client/src/forms/Organizations.js:26 +#: client/src/forms/Projects.js:31 +#: client/src/forms/Teams.js:126 +#: client/src/forms/Teams.js:27 +#: client/src/forms/Users.js:139 +#: client/src/forms/Users.js:164 +#: client/src/forms/Users.js:190 +#: client/src/forms/Workflows.js:34 +#: client/src/inventory-scripts/inventory-scripts.form.js:25 +#: client/src/inventory-scripts/inventory-scripts.list.js:20 +#: client/src/lists/CompletedJobs.js:43 +#: client/src/lists/Credentials.js:29 +#: client/src/lists/Inventories.js:46 +#: client/src/lists/PortalJobTemplates.js:24 +#: client/src/lists/PortalJobs.js:32 +#: client/src/lists/Projects.js:37 +#: client/src/lists/ScheduledJobs.js:32 +#: client/src/lists/Teams.js:25 +#: client/src/lists/Templates.js:26 +#: client/src/notifications/notificationTemplates.form.js:29 +#: client/src/notifications/notificationTemplates.list.js:33 +#: client/src/notifications/notifications.list.js:26 +msgid "Name" +msgstr "Nom" + +#: client/src/forms/Credentials.js:72 +msgid "Network" +msgstr "Réseau" + +#: client/src/forms/JobTemplates.js:182 +#: client/src/forms/JobTemplates.js:193 +msgid "Network Credential" +msgstr "Informations d'identification réseau" + +#: client/src/forms/JobTemplates.js:192 +msgid "" +"Network credentials are used by Ansible networking modules to connect to and " +"manage networking devices." +msgstr "" +"Les informations d'identification sont utilisées par les modules de mise en " +"réseau d'Ansible pour connecter et gérer les périphériques réseau." + +#: client/src/inventory-scripts/inventory-scripts.form.js:16 +msgid "New Custom Inventory" +msgstr "Nouvel inventaire personnalisé" + +#: client/src/forms/Inventories.js:18 +msgid "New Inventory" +msgstr "Nouvel inventaire" + +#: client/src/forms/JobTemplates.js:20 +msgid "New Job Template" +msgstr "Nouveau modèle de tâche" + +#: client/src/notifications/notificationTemplates.form.js:16 +msgid "New Notification Template" +msgstr "Nouveau modèle de notification" + +#: client/src/forms/Organizations.js:18 +msgid "New Organization" +msgstr "Nouvelle organisation" + +#: client/src/forms/Projects.js:18 +msgid "New Project" +msgstr "Nouveau projet" + +#: client/src/forms/Teams.js:18 +msgid "New Team" +msgstr "Nouvelle équipe" + +#: client/src/forms/Users.js:18 +msgid "New User" +msgstr "Nouvel utilisateur" + +#: client/src/forms/Workflows.js:19 +msgid "New Workflow Job Template" +msgstr "Nouveau modèle de tâche Workflow" + +#: client/src/controllers/Users.js:174 +msgid "New user successfully created!" +msgstr "Création de l'utilisateur réussie" + +#: client/src/lists/ScheduledJobs.js:50 +msgid "Next Run" +msgstr "Exécution suivante" + +#: client/src/lists/Credentials.js:24 +msgid "No Credentials Have Been Created" +msgstr "Informations d'identification non créées" + +#: client/src/controllers/Projects.js:123 +msgid "No SCM Configuration" +msgstr "Aucune configuration SCM" + +#: client/src/controllers/Projects.js:114 +msgid "No Updates Available" +msgstr "Aucune mise à jour disponible" + +#: client/src/lists/CompletedJobs.js:22 +msgid "No completed jobs" +msgstr "Aucune tâche terminée" + +#: client/src/license/license.controller.js:41 +msgid "No file selected." +msgstr "Aucun fichier sélectionné." + +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:46 +msgid "No jobs were recently run." +msgstr "Aucune tâche récemment exécutée." + +#: client/src/forms/Teams.js:123 +#: client/src/forms/Users.js:187 +msgid "No permissions have been granted" +msgstr "Aucune permission accordée" + +#: client/src/lists/ScheduledJobs.js:18 +msgid "No schedules exist" +msgstr "Aucune planification existante" + +#: client/src/controllers/Users.js:16 +msgid "Normal User" +msgstr "Utilisateur normal" + +#: client/src/controllers/Projects.js:64 +msgid "Not configured for SCM" +msgstr "Non configuré pour le SCM" + +#: client/src/notifications/notificationTemplates.form.js:293 +msgid "Notification Color" +msgstr "Couleur des notifications" + +#: client/src/notifications/notificationTemplates.list.js:14 +msgid "Notification Templates" +msgstr "Modèles de notification" + +#: client/src/notifications/notifications.list.js:17 +#: client/src/setup-menu/setup-menu.partial.html:41 +msgid "Notifications" +msgstr "Notifications" + +#: client/src/notifications/notificationTemplates.form.js:306 +msgid "Notify Channel" +msgstr "Canal de notification" + +#: client/src/notifications/notificationTemplates.form.js:198 +msgid "Number associated with the \"Messaging Service\" in Twilio." +msgstr "Numéro associé au \"Service de messagerie\" de Twilio." + +#: client/src/shared/form-generator.js:547 +msgid "OFF" +msgstr "DÉSACTIVÉ" + +#: client/src/shared/form-generator.js:545 +msgid "ON" +msgstr "ACTIVÉ" + +#: client/src/organizations/list/organizations-list.partial.html:6 +msgid "ORGANIZATIONS" +msgstr "ORGANISATIONS" + +#: client/src/forms/WorkflowMaker.js:45 +msgid "On Failure" +msgstr "Lors d'un échec" + +#: client/src/forms/WorkflowMaker.js:40 +msgid "On Success" +msgstr "Lors d'une réussite" + +#: client/src/forms/Credentials.js:377 +msgid "" +"OpenStack domains define administrative boundaries. It is only needed for " +"Keystone v3 authentication URLs. Common scenarios include:" +msgstr "" +"Les domaines OpenStack définissent les limites administratives. Ils sont " +"nécessaires seulement pour les URL d'authentification Keystone v3. Les " +"scénarios courants incluent :" + +#: client/src/forms/JobTemplates.js:347 +#: client/src/forms/Workflows.js:67 +msgid "" +"Optional labels that describe this job template, such as 'dev' or 'test'. " +"Labels can be used to group and filter job templates and completed jobs in " +"the Tower display." +msgstr "" +"Libellés facultatifs décrivant ce modèle de tâche, par exemple 'dev' ou " +"'test'. Les libellés peuvent être utilisés pour regrouper et filtrer les " +"modèles de tâche et les tâches terminées dans l'affichage de Tower." + +#: client/src/forms/JobTemplates.js:284 +#: client/src/notifications/notificationTemplates.form.js:391 +msgid "Options" +msgstr "Options" + +#: client/src/forms/Credentials.js:49 +#: client/src/forms/Credentials.js:55 +#: client/src/forms/Inventories.js:42 +#: client/src/forms/Projects.js:43 +#: client/src/forms/Projects.js:49 +#: client/src/forms/Teams.js:39 +#: client/src/forms/Users.js:59 +#: client/src/forms/Workflows.js:47 +#: client/src/forms/Workflows.js:53 +#: client/src/inventory-scripts/inventory-scripts.form.js:37 +#: client/src/inventory-scripts/inventory-scripts.list.js:30 +#: client/src/lists/Inventories.js:52 +#: client/src/lists/Teams.js:35 +#: client/src/notifications/notificationTemplates.form.js:41 +msgid "Organization" +msgstr "Organisation" + +#: client/src/forms/Users.js:129 +#: client/src/setup-menu/setup-menu.partial.html:4 +msgid "Organizations" +msgstr "Organisations" + +#: client/src/forms/Credentials.js:80 +msgid "Others (Cloud Providers)" +msgstr "Autres (fournisseurs cloud)" + +#: client/src/lists/Credentials.js:45 +msgid "Owners" +msgstr "Propriétaires" + +#: client/src/login/loginModal/loginModal.partial.html:68 +msgid "PASSWORD" +msgstr "MOT DE PASSE" + +#: client/src/organizations/list/organizations-list.partial.html:44 +#: client/src/shared/form-generator.js:1880 +#: client/src/shared/list-generator/list-generator.factory.js:245 +msgid "PLEASE ADD ITEMS TO THIS LIST" +msgstr "AJOUTEZ DES ÉLÉMENTS À CETTE LISTE" + +#: client/src/main-menu/main-menu.partial.html:67 +msgid "PORTAL MODE" +msgstr "MODE PORTAIL" + +#: client/src/main-menu/main-menu.partial.html:19 +#: client/src/main-menu/main-menu.partial.html:95 +msgid "PROJECTS" +msgstr "PROJETS" + +#: client/src/notifications/notificationTemplates.form.js:237 +msgid "Pagerduty subdomain" +msgstr "Sous-domaine Pagerduty" + +#: client/src/forms/JobTemplates.js:358 +#: client/src/forms/Workflows.js:78 +msgid "" +"Pass extra command line variables to the playbook. This is the %s or %s " +"command line parameter for %s. Provide key/value pairs using either YAML or " +"JSON." +msgstr "" +"Transmettez des variables de ligne de commande supplémentaires au playbook. " +"Il s'agit du paramètre de ligne de commande %s ou %s pour %s. Entrez des " +"paires clé/valeur avec la syntaxe YAML ou JSON." + +#: client/src/forms/Credentials.js:227 +#: client/src/forms/Users.js:70 +#: client/src/helpers/Credentials.js:119 +#: client/src/helpers/Credentials.js:127 +#: client/src/helpers/Credentials.js:147 +#: client/src/helpers/Credentials.js:156 +#: client/src/helpers/Credentials.js:165 +#: client/src/helpers/Credentials.js:45 +#: client/src/helpers/Credentials.js:94 +#: client/src/notifications/shared/type-change.service.js:28 +msgid "Password" +msgstr "Mot de passe" + +#: client/src/helpers/Credentials.js:73 +msgid "Password (API Key)" +msgstr "Mot de passe (clé API)" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:20 +msgid "Past 24 Hours" +msgstr "Après 24 heures" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:15 +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:26 +msgid "Past Month" +msgstr "Le mois dernier" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:23 +msgid "Past Week" +msgstr "La semaine dernière" + +#: client/src/helpers/Credentials.js:102 +msgid "" +"Paste the contents of the PEM file associated with the service account email." +"" +msgstr "" +"Collez le contenu du fichier PEM associé à l'adresse électronique du compte " +"de service." + +#: client/src/helpers/Credentials.js:114 +msgid "" +"Paste the contents of the PEM file that corresponds to the certificate you " +"uploaded in the Microsoft Azure console." +msgstr "" +"Collez le contenu du fichier PEM correspondant au certificat que vous avez " +"chargé dans la console Microsoft Azure." + +#: client/src/helpers/Credentials.js:66 +msgid "Paste the contents of the SSH private key file." +msgstr "Collez le contenu du fichier de clé privée SSH." + +#: client/src/helpers/Credentials.js:41 +msgid "Paste the contents of the SSH private key file.%s or click to close%s" +msgstr "" +"Collez le contenu du fichier de clé privée SSH.%s ou cliquez pour fermer%s" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:8 +msgid "Period" +msgstr "Période" + +#: client/src/controllers/Projects.js:284 +#: client/src/controllers/Users.js:141 +msgid "Permission Error" +msgstr "Erreur de permission" + +#: client/src/forms/Credentials.js:432 +#: client/src/forms/Inventories.js:142 +#: client/src/forms/JobTemplates.js:403 +#: client/src/forms/Organizations.js:64 +#: client/src/forms/Projects.js:227 +#: client/src/forms/Workflows.js:116 +msgid "Permissions" +msgstr "Permissions" + +#: client/src/forms/JobTemplates.js:120 +#: client/src/forms/JobTemplates.js:131 +msgid "Playbook" +msgstr "Playbook" + +#: client/src/forms/Projects.js:89 +msgid "Playbook Directory" +msgstr "Répertoire de playbooks" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:52 +msgid "Playbook Run" +msgstr "Exécution du playbook" + +#: client/src/license/license.partial.html:84 +msgid "" +"Please click the button below to visit Ansible's website to get a Tower " +"license key." +msgstr "" +"Cliquez sur le bouton ci-dessous pour visiter le site Web d'Ansible afin " +"d'obtenir une clé de licence Tower." + +#: client/src/shared/form-generator.js:828 +#: client/src/shared/form-generator.js:953 +msgid "" +"Please enter a URL that begins with ssh, http or https. The URL may not " +"contain the '@' character." +msgstr "" +"Veuillez saisir une URL commençant par ssh, http ou https. L'URL ne doit pas " +"contenir le caractère '@'." + +#: client/src/shared/form-generator.js:1189 +msgid "Please enter a number greater than %d and less than %d." +msgstr "Entrez un nombre supérieur à %d et inférieur à %d." + +#: client/src/shared/form-generator.js:1191 +msgid "Please enter a number greater than %d." +msgstr "Entrez un nombre supérieur à %d." + +#: client/src/shared/form-generator.js:1183 +msgid "Please enter a number." +msgstr "Entrez un nombre." + +#: client/src/login/loginModal/loginModal.partial.html:78 +msgid "Please enter a password." +msgstr "Entrez un mot de passe." + +#: client/src/login/loginModal/loginModal.partial.html:58 +msgid "Please enter a username." +msgstr "Entrez un nom d'utilisateur." + +#: client/src/shared/form-generator.js:818 +#: client/src/shared/form-generator.js:943 +msgid "Please enter a valid email address." +msgstr "Entrez une adresse électronique valide." + +#: client/src/shared/form-generator.js:1044 +#: client/src/shared/form-generator.js:813 +#: client/src/shared/form-generator.js:938 +msgid "Please enter a value." +msgstr "Entrez une valeur." + +#: client/src/lists/CompletedJobs.js:13 +msgid "Please save and run a job to view" +msgstr "Veuillez enregistrer et exécuter une tâche à afficher" + +#: client/src/notifications/notifications.list.js:15 +msgid "Please save before adding notifications" +msgstr "Veuillez enregistrer avant d'ajouter des notifications" + +#: client/src/forms/Teams.js:69 +msgid "Please save before adding users" +msgstr "Veuillez enregistrer avant d'ajouter des utilisateurs" + +#: client/src/forms/Inventories.js:138 +#: client/src/forms/Inventories.js:91 +#: client/src/forms/JobTemplates.js:396 +#: client/src/forms/Organizations.js:57 +#: client/src/forms/Projects.js:219 +#: client/src/forms/Teams.js:110 +#: client/src/forms/Workflows.js:109 +msgid "Please save before assigning permissions" +msgstr "Veuillez enregistrer avant d'attribuer des permissions" + +#: client/src/forms/Users.js:122 +#: client/src/forms/Users.js:179 +msgid "Please save before assigning to organizations" +msgstr "Veuillez enregistrer avant l'attribution à des organisations" + +#: client/src/forms/Users.js:148 +msgid "Please save before assigning to teams" +msgstr "Veuillez enregistrer avant l'attribution à des équipes" + +#: client/src/forms/Workflows.js:185 +msgid "Please save before defining the workflow graph" +msgstr "Veuillez enregistrer avant de définir le graphique du workflow" + +#: client/src/forms/WorkflowMaker.js:65 +msgid "Please select a Credential." +msgstr "Sélectionnez des informations d'identification." + +#: client/src/forms/JobTemplates.js:150 +msgid "" +"Please select a Machine Credential or check the Prompt on launch option." +msgstr "" +"Sélectionnez les informations d'identification de la machine ou cochez " +"l'option Me le demander au lancement." + +#: client/src/shared/form-generator.js:1224 +msgid "Please select a number between" +msgstr "Sélectionnez un nombre compris entre" + +#: client/src/shared/form-generator.js:1220 +msgid "Please select a number." +msgstr "Sélectionnez un nombre." + +#: client/src/shared/form-generator.js:1111 +#: client/src/shared/form-generator.js:1180 +#: client/src/shared/form-generator.js:1298 +#: client/src/shared/form-generator.js:1403 +msgid "Please select a value." +msgstr "Sélectionnez une valeur." + +#: client/src/forms/JobTemplates.js:83 +msgid "Please select an Inventory or check the Prompt on launch option." +msgstr "" +"Sélectionnez un inventaire ou cochez l'option Me le demander au lancement." + +#: client/src/forms/WorkflowMaker.js:86 +msgid "Please select an Inventory." +msgstr "Sélectionnez un inventaire." + +#: client/src/shared/form-generator.js:1217 +msgid "Please select at least one value." +msgstr "Sélectionnez une valeur au moins." + +#: client/src/notifications/shared/type-change.service.js:27 +msgid "Port" +msgstr "Port" + +#: client/src/forms/Credentials.js:257 +#: client/src/helpers/Credentials.js:36 +#: client/src/helpers/Credentials.js:60 +msgid "Private Key" +msgstr "Clé privée" + +#: client/src/forms/Credentials.js:264 +msgid "Private Key Passphrase" +msgstr "Phrase de passe pour la clé privée" + +#: client/src/forms/Credentials.js:279 +#: client/src/forms/Credentials.js:283 +msgid "Privilege Escalation" +msgstr "Élévation des privilèges" + +#: client/src/helpers/Credentials.js:90 +msgid "Privilege Escalation Password" +msgstr "Mot de passe pour l'élévation des privilèges" + +#: client/src/helpers/Credentials.js:89 +msgid "Privilege Escalation Username" +msgstr "Nom d'utilisateur pour l'élévation des privilèges" + +#: client/src/forms/JobTemplates.js:114 +#: client/src/forms/JobTemplates.js:97 +#: client/src/helpers/Credentials.js:103 +msgid "Project" +msgstr "Projet" + +#: client/src/helpers/Credentials.js:132 +msgid "Project (Tenant Name)" +msgstr "Projet (nom du client)" + +#: client/src/forms/Projects.js:75 +#: client/src/forms/Projects.js:83 +msgid "Project Base Path" +msgstr "Chemin de base du projet" + +#: client/src/forms/Credentials.js:363 +msgid "Project Name" +msgstr "Nom du projet" + +#: client/src/forms/Projects.js:100 +msgid "Project Path" +msgstr "Chemin du projet" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:66 +msgid "Project Sync Failures" +msgstr "Erreurs de synchronisation du projet" + +#: client/src/controllers/Projects.js:134 +msgid "Project lookup failed. GET returned:" +msgstr "La recherche de projet n'a pas abouti. GET renvoyé :" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:61 +#: client/src/lists/Projects.js:16 +#: client/src/lists/Projects.js:17 +msgid "Projects" +msgstr "Projets" + +#: client/src/forms/JobTemplates.js:159 +#: client/src/forms/JobTemplates.js:230 +#: client/src/forms/JobTemplates.js:261 +#: client/src/forms/JobTemplates.js:279 +#: client/src/forms/JobTemplates.js:369 +#: client/src/forms/JobTemplates.js:68 +#: client/src/forms/JobTemplates.js:92 +msgid "Prompt on launch" +msgstr "Me le demander au lancement" + +#: client/src/forms/JobTemplates.js:253 +#: client/src/forms/JobTemplates.js:271 +#: client/src/forms/WorkflowMaker.js:139 +#: client/src/forms/WorkflowMaker.js:154 +msgid "Provide a comma separated list of tags." +msgstr "Entrez une liste de balises séparées par des virgules." + +#: client/src/forms/JobTemplates.js:221 +#: client/src/forms/WorkflowMaker.js:123 +msgid "" +"Provide a host pattern to further constrain the list of hosts that will be " +"managed or affected by the playbook. Multiple patterns can be separated by " +"%s %s or %s" +msgstr "" +"Entrez un modèle d'hôte pour limiter davantage la liste des hôtes qui seront " +"gérés ou attribués par le playbook. Plusieurs modèles peuvent être séparés " +"par des % s% s ou des % s" + +#: client/src/forms/JobTemplates.js:313 +#: client/src/forms/JobTemplates.js:321 +msgid "Provisioning Callback URL" +msgstr "URL de rappel d'exécution de Tower job_template" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:107 +msgid "RADIUS" +msgstr "RADIUS" + +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:4 +msgid "RECENT JOB RUNS" +msgstr "RÉCENTES EXÉCUTIONS DE TÂCHE" + +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:42 +msgid "RECENTLY RUN JOBS" +msgstr "TÂCHES RÉCEMMENT EXÉCUTÉES" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:4 +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:52 +msgid "RECENTLY USED JOB TEMPLATES" +msgstr "MODÈLES DE TÂCHE RÉCEMMENT UTILISÉS" + +#: client/src/lists/Projects.js:76 +#: client/src/partials/jobs.html:15 +#: client/src/portal-mode/portal-mode-jobs.partial.html:12 +msgid "REFRESH" +msgstr "ACTUALISER" + +#: client/src/forms/JobTemplates.js:99 +msgid "RESET" +msgstr "RÉINITIALISER" + +#: client/src/helpers/Credentials.js:98 +msgid "RSA Private Key" +msgstr "Clé privée RSA" + +#: client/src/notifications/notificationTemplates.form.js:94 +#: client/src/notifications/notificationTemplates.form.js:99 +msgid "Recipient List" +msgstr "Liste de destinataires" + +#: client/src/bread-crumb/bread-crumb.partial.html:6 +#: client/src/lists/Projects.js:72 +msgid "Refresh the page" +msgstr "Actualiser la page" + +#: client/src/lists/CompletedJobs.js:75 +msgid "Relaunch using the same parameters" +msgstr "Relancer en utilisant les mêmes paramètres" + +#: client/src/forms/Teams.js:144 +#: client/src/forms/Users.js:214 +msgid "Remove" +msgstr "Supprimer" + +#: client/src/forms/Projects.js:153 +msgid "Remove any local modifications prior to performing an update." +msgstr "" +"Supprimez toutes les modifications locales avant d'effectuer une mise à jour." +"" + +#: client/src/license/license.partial.html:89 +msgid "Request License" +msgstr "Demander une licence" + +#: client/src/configuration/auth-form/sub-forms/auth-azure.form.js:41 +#: client/src/configuration/auth-form/sub-forms/auth-github-org.form.js:31 +#: client/src/configuration/auth-form/sub-forms/auth-github-team.form.js:31 +#: client/src/configuration/auth-form/sub-forms/auth-github.form.js:27 +#: client/src/configuration/auth-form/sub-forms/auth-google-oauth2.form.js:39 +#: client/src/configuration/auth-form/sub-forms/auth-ldap.form.js:87 +#: client/src/configuration/auth-form/sub-forms/auth-radius.form.js:32 +#: client/src/configuration/auth-form/sub-forms/auth-saml.form.js:59 +#: client/src/configuration/jobs-form/configuration-jobs.form.js:67 +#: client/src/configuration/system-form/configuration-system.form.js:41 +#: client/src/configuration/system-form/sub-forms/system-activity-stream.form.js:25 +#: client/src/configuration/system-form/sub-forms/system-logging.form.js:50 +#: client/src/configuration/system-form/sub-forms/system-misc.form.js:29 +#: client/src/configuration/ui-form/configuration-ui.form.js:35 +msgid "Reset All" +msgstr "Tout réinitialiser" + +#: client/src/lists/Projects.js:42 +msgid "Revision" +msgstr "Révision" + +#: client/src/controllers/Projects.js:657 +msgid "Revision #" +msgstr "Révision n°" + +#: client/src/forms/Credentials.js:454 +#: client/src/forms/Inventories.js:120 +#: client/src/forms/Inventories.js:166 +#: client/src/forms/Organizations.js:88 +#: client/src/forms/Projects.js:249 +#: client/src/forms/Teams.js:137 +#: client/src/forms/Teams.js:99 +#: client/src/forms/Users.js:201 +msgid "Role" +msgstr "Rôle" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:108 +msgid "SAML" +msgstr "SAML" + +#: client/src/controllers/Projects.js:657 +msgid "SCM Branch" +msgstr "Branche SCM" + +#: client/src/forms/Projects.js:154 +msgid "SCM Clean" +msgstr "Nettoyage SCM" + +#: client/src/forms/Projects.js:130 +msgid "SCM Credential" +msgstr "Information d'identification SCM" + +#: client/src/forms/Projects.js:165 +msgid "SCM Delete" +msgstr "Suppression SCM" + +#: client/src/helpers/Credentials.js:93 +msgid "SCM Private Key" +msgstr "Clé privée SCM" + +#: client/src/forms/Projects.js:56 +msgid "SCM Type" +msgstr "Type SCM" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:49 +#: client/src/forms/Projects.js:175 +msgid "SCM Update" +msgstr "Mise à jour SCM" + +#: client/src/controllers/Projects.js:176 +msgid "SCM Update Cancel" +msgstr "Annulation de la mise à jour SCM" + +#: client/src/forms/Projects.js:145 +msgid "SCM Update Options" +msgstr "Options de mise à jour SCM" + +#: client/src/controllers/Projects.js:543 +#: client/src/controllers/Projects.js:57 +msgid "SCM update currently running" +msgstr "Mise à jour SCM en cours" + +#: client/src/main-menu/main-menu.partial.html:59 +msgid "SETTINGS" +msgstr "PARAMÈTRES" + +#: client/src/login/loginModal/loginModal.partial.html:97 +msgid "SIGN IN" +msgstr "SE CONNECTER" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.partial.html:2 +msgid "SIGN IN WITH" +msgstr "SE CONNECTER AVEC" + +#: client/src/app.js:513 +msgid "SOCKETS" +msgstr "SOCKETS" + +#: client/src/helpers/Credentials.js:166 +msgid "SSH Key" +msgstr "Clé SSH" + +#: client/src/forms/Credentials.js:255 +msgid "SSH key description" +msgstr "Description de la clé SSH" + +#: client/src/notifications/notificationTemplates.form.js:384 +msgid "SSL Connection" +msgstr "Connexion SSL" + +#: client/src/forms/Credentials.js:120 +#: client/src/forms/Credentials.js:128 +msgid "STS Token" +msgstr "Token STS" + +#: client/src/dashboard/graphs/job-status/job-status-graph.directive.js:64 +msgid "SUCCESSFUL" +msgstr "RÉUSSI" + +#: client/src/helpers/Credentials.js:149 +msgid "Satellite 6 Host" +msgstr "Hôte Satellite 6" + +#: client/src/shared/form-generator.js:1687 +msgid "Save" +msgstr "Enregistrer" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:81 +#: client/src/configuration/configuration.controller.js:181 +#: client/src/configuration/configuration.controller.js:240 +#: client/src/configuration/system-form/configuration-system.controller.js:60 +msgid "Save changes" +msgstr "Enregistrer les modifications" + +#: client/src/license/license.partial.html:122 +msgid "Save successful!" +msgstr "Enregistrement réussi" + +#: client/src/lists/Templates.js:92 +msgid "Schedule" +msgstr "Planifier" + +#: client/src/management-jobs/card/card.partial.html:26 +msgid "Schedule Management Job" +msgstr "Planifier la tâche de gestion" + +#: client/src/controllers/Projects.js:49 +msgid "Schedule future SCM updates" +msgstr "Planifier les prochaines mises à jour SCM" + +#: client/src/lists/Templates.js:95 +msgid "Schedule future job template runs" +msgstr "Planifier les prochaines exécutions de modèle de tâche" + +#: client/src/lists/ScheduledJobs.js:15 +msgid "Scheduled Jobs" +msgstr "Tâches planifiées" + +#: client/src/partials/jobs.html:10 +msgid "Schedules" +msgstr "Calendriers" + +#: client/src/inventory-scripts/inventory-scripts.form.js:59 +msgid "Script must begin with a hashbang sequence: i.e.... %s" +msgstr "Le script doit commencer par une séquence hashbang : c.-à-d. ....%s" + +#: client/src/forms/Credentials.js:105 +msgid "Secret Key" +msgstr "Clé secrète" + +#: client/src/forms/Credentials.js:125 +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 "" +"Le service de jeton de sécurité (STS) est un service Web qui permet de " +"demander des informations d'identification provisoires avec des privilèges " +"limités pour les utilisateurs d'AWS Identity and Access Management (IAM)." + +#: client/src/shared/form-generator.js:1691 +msgid "Select" +msgstr "Sélectionner" + +#: client/src/configuration/jobs-form/configuration-jobs.controller.js:87 +#: client/src/configuration/ui-form/configuration-ui.controller.js:82 +msgid "Select commands" +msgstr "Sélectionner des commandes" + +#: client/src/forms/Projects.js:98 +msgid "" +"Select from the list of directories found in the Project Base Path. Together " +"the base path and the playbook directory provide the full path used to " +"locate playbooks." +msgstr "" +"Faites une sélection à partir de la liste des répertoires trouvés dans le " +"chemin de base du projet. Le chemin de base et le répertoire de playbook " +"fournissent ensemble le chemin complet servant à localiser les playbooks." + +#: client/src/configuration/auth-form/configuration-auth.controller.js:226 +msgid "Select group types" +msgstr "Sélectionner des types de groupe" + +#: client/src/forms/JobTemplates.js:152 +#: client/src/forms/WorkflowMaker.js:67 +msgid "" +"Select the credential you want the job to use when accessing the remote " +"hosts. Choose the credential containing the username and SSH key or " +"password that Ansible will need to log into the remote hosts." +msgstr "" +"Sélectionnez les informations d'identification que la tâche doit utiliser " +"lors de l'accès à des hôtes distants. Choisissez les informations " +"d'identification contenant le nom d'utilisateur et la clé SSH ou le mot de " +"passe dont Ansible aura besoin pour se connecter aux hôtes distants." + +#: client/src/forms/JobTemplates.js:85 +#: client/src/forms/WorkflowMaker.js:88 +msgid "Select the inventory containing the hosts you want this job to manage." +msgstr "" +"Sélectionnez l'inventaire contenant les hôtes que vous souhaitez gérer." + +#: client/src/forms/JobTemplates.js:130 +msgid "Select the playbook to be executed by this job." +msgstr "Sélectionnez le playbook qui devra être exécuté par cette tâche." + +#: client/src/forms/JobTemplates.js:113 +msgid "" +"Select the project containing the playbook you want this job to execute." +msgstr "" +"Sélectionnez le projet contenant le playbook que cette tâche devra exécuter." + +#: client/src/configuration/system-form/configuration-system.controller.js:167 +msgid "Select types" +msgstr "Sélectionner des types" + +#: client/src/forms/JobTemplates.js:174 +msgid "" +"Selecting an optional cloud credential in the job template will pass along " +"the access credentials to the running playbook, allowing provisioning into " +"the cloud without manually passing parameters to the included modules." +msgstr "" +"La sélection d'informations identification cloud facultatives dans le modèle " +"de tâche transmettra les informations d'identification d'accès au playbook " +"en cours d'exécution, ce qui permet une authentification dans le cloud sans " +"transmettre manuellement les paramètres aux modules inclus." + +#: client/src/notifications/notificationTemplates.form.js:83 +msgid "Sender Email" +msgstr "Adresse électronique de l'expéditeur" + +#: client/src/helpers/Credentials.js:97 +msgid "Service Account Email Address" +msgstr "Adresse électronique du compte de service" + +#: client/src/forms/JobTemplates.js:60 +#: client/src/forms/WorkflowMaker.js:108 +msgid "" +"Setting the type to %s will execute the playbook and store any scanned " +"facts for use with Tower's System Tracking feature." +msgstr "" +"La définition du type sur %s exécute le playbook et stocke tous les faits " +"scannés à utiliser avec la fonctionnalité de suivi System Tracking de Tower." + +#: client/src/forms/JobTemplates.js:57 +msgid "Setting the type to %s will not execute the playbook." +msgstr "La définition du type sur %s n'exécute pas le playbook." + +#: client/src/forms/WorkflowMaker.js:106 +msgid "" +"Setting the type to %s will not execute the playbook. Instead, %s will check " +"playbook syntax, test environment setup and report problems." +msgstr "" +"La définition du type sur %s n'exécute pas le playbook. À la place, %s " +"vérifie la syntaxe du playbook, teste la configuration de l'environnement et " +"signale les problèmes." + +#: client/src/main-menu/main-menu.partial.html:147 +msgid "Settings" +msgstr "Paramètres" + +#: client/src/shared/form-generator.js:843 +msgid "Show" +msgstr "Afficher" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:34 +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:45 +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:56 +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:77 +msgid "Sign in with %s" +msgstr "Se connecter avec %s" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:64 +msgid "Sign in with %s Organizations" +msgstr "Se connecter avec des organisations %s" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:62 +msgid "Sign in with %s Teams" +msgstr "Se connecter avec des équipes %s" + +#: client/src/forms/JobTemplates.js:266 +#: client/src/forms/JobTemplates.js:274 +#: client/src/forms/WorkflowMaker.js:149 +#: client/src/forms/WorkflowMaker.js:157 +msgid "Skip Tags" +msgstr "Balises de saut" + +#: client/src/forms/JobTemplates.js:272 +#: client/src/forms/WorkflowMaker.js:155 +msgid "" +"Skip tags are useful when you have a large playbook, and you want to skip " +"specific parts of a play or task." +msgstr "" +"Les balises de saut sont utiles si votre playbook est important et que vous " +"souhaitez ignorer certaines parties d'une scène ou d'une tâche." + +#: client/src/forms/Credentials.js:76 +msgid "Source Control" +msgstr "Contrôle de la source" + +#: client/src/forms/Projects.js:27 +msgid "Source Details" +msgstr "Détails de la source" + +#: client/src/notifications/notificationTemplates.form.js:196 +msgid "Source Phone Number" +msgstr "Numéro de téléphone de la source" + +#: client/src/notifications/notificationTemplates.form.js:332 +msgid "Specify HTTP Headers in JSON format" +msgstr "Spécifier les en-têtes HTTP au format JSON" + +#: client/src/forms/Credentials.js:285 +msgid "" +"Specify a method for %s operations. This is equivalent to specifying the %s " +"parameter, where %s could be %s" +msgstr "" +"Spécifiez une méthode pour les opérations %s. Cela équivaut à définir le " +"paramètre %s, où %s peut être %s" + +#: client/src/setup-menu/setup-menu.partial.html:17 +msgid "" +"Split up your organization to associate content and control permissions for " +"groups." +msgstr "" +"Divisez votre organisation afin d'associer du contenu et des permissions de " +"contrôle pour les groupes." + +#: client/src/lists/PortalJobTemplates.js:42 +#: client/src/lists/Templates.js:87 +msgid "Start a job using this template" +msgstr "Démarrer une tâche avec ce modèle" + +#: client/src/controllers/Projects.js:48 +#: client/src/controllers/Projects.js:540 +msgid "Start an SCM update" +msgstr "Démarrer une mise à jour SCM" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:49 +msgid "Status" +msgstr "État" + +#: client/src/license/license.partial.html:121 +msgid "Submit" +msgstr "Valider" + +#: client/src/license/license.partial.html:27 +msgid "Subscription" +msgstr "Abonnement" + +#: client/src/forms/Credentials.js:152 +#: client/src/forms/Credentials.js:163 +msgid "Subscription ID" +msgstr "ID d'abonnement" + +#: client/src/forms/Credentials.js:162 +msgid "Subscription ID is an Azure construct, which is mapped to a username." +msgstr "" +"L'ID d'abonnement est une construction Azure mappée à un nom d'utilisateur." + +#: client/src/notifications/notifications.list.js:38 +msgid "Success" +msgstr "Réussite" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:77 +msgid "Successful" +msgstr "Réussi" + +#: client/src/controllers/Users.js:18 +msgid "System Administrator" +msgstr "Administrateur système" + +#: client/src/controllers/Users.js:17 +msgid "System Auditor" +msgstr "Auditeur système" + +#: client/src/app.js:341 +msgid "TEAMS" +msgstr "ÉQUIPES" + +#: client/src/main-menu/main-menu.partial.html:113 +#: client/src/main-menu/main-menu.partial.html:35 +msgid "TEMPLATES" +msgstr "MODÈLES" + +#: client/src/dashboard/graphs/job-status/job-status-graph.directive.js:106 +msgid "TIME" +msgstr "DURÉE" + +#: client/src/forms/JobTemplates.js:254 +#: client/src/forms/WorkflowMaker.js:140 +msgid "" +"Tags are useful when you have a large playbook, and you want to run a " +"specific part of a play or task." +msgstr "" +"Les balises sont utiles si votre playbook est important et que vous " +"souhaitez exécuter une partie donnée d'une scène ou d'une tâche." + +#: client/src/notifications/notificationTemplates.form.js:313 +msgid "Target URL" +msgstr "URL cible" + +#: client/src/forms/Credentials.js:461 +#: client/src/forms/Inventories.js:126 +#: client/src/forms/Inventories.js:173 +#: client/src/forms/Organizations.js:95 +#: client/src/forms/Projects.js:255 +msgid "Team Roles" +msgstr "Rôles d'équipe" + +#: client/src/forms/Users.js:155 +#: client/src/lists/Teams.js:16 +#: client/src/lists/Teams.js:17 +#: client/src/setup-menu/setup-menu.partial.html:16 +msgid "Teams" +msgstr "Équipes" + +#: client/src/lists/Templates.js:16 +msgid "Template" +msgstr "Modèle" + +#: client/src/lists/Templates.js:17 +#: client/src/lists/Templates.js:18 +msgid "Templates" +msgstr "Modèles" + +#: client/src/forms/Credentials.js:335 +msgid "Tenant ID" +msgstr "ID Client" + +#: client/src/notifications/notificationTemplates.list.js:65 +msgid "Test notification" +msgstr "Notification test" + +#: client/src/shared/form-generator.js:1409 +msgid "That value was not found. Please enter or select a valid value." +msgstr "" +"Cette valeur n'a pas été trouvée. Veuillez entrer ou sélectionner une valeur " +"valide." + +#: client/src/helpers/Credentials.js:105 +msgid "" +"The Project ID is the GCE assigned identification. It is constructed as two " +"words followed by a three digit number. Such as:" +msgstr "" +"L'ID du projet est l'identifiant attribué par GCE. Il se compose de deux " +"mots suivis d'un nombre à trois chiffres. Exemple :" + +#: client/src/controllers/Projects.js:693 +msgid "The SCM update process is running." +msgstr "Le processus de mise à jour SCM est en cours d'exécution." + +#: client/src/forms/Credentials.js:191 +msgid "" +"The email address assigned to the Google Compute Engine %sservice account." +msgstr "" +"Adresse électronique attribuée au compte de service Google Compute Engine %s." +"" + +#: client/src/helpers/Credentials.js:141 +msgid "The host to authenticate with." +msgstr "Hôte avec lequel s'authentifier." + +#: client/src/helpers/Credentials.js:75 +msgid "The host value" +msgstr "Valeur de l'hôte" + +#: client/src/forms/JobTemplates.js:208 +msgid "" +"The number of parallel or simultaneous processes to use while executing the " +"playbook. 0 signifies the default value from the %sansible configuration " +"file%s." +msgstr "" +"Nombre de processus parallèles ou simultanés à utiliser lors de l'exécution " +"du playbook. 0 indique la valeur par défaut du %sfichier de configuration " +"ansible%s." + +#: client/src/helpers/Credentials.js:74 +msgid "The project value" +msgstr "Valeur du projet" + +#: client/src/controllers/Projects.js:123 +msgid "" +"The selected project is not configured for SCM. To configure for SCM, edit " +"the project and provide SCM settings, and then run an update." +msgstr "" +"Le projet sélectionné n'est pas configuré pour SCM. Afin de le configurer " +"pour SCM, modifiez le projet et définissez les paramètres SCM, puis lancez " +"une mise à jour." + +#: client/src/lists/PortalJobTemplates.js:20 +msgid "There are no job templates to display at this time" +msgstr "Aucun modèle de tâche à afficher pour le moment" + +#: client/src/lists/PortalJobs.js:20 +msgid "There are no jobs to display at this time" +msgstr "Aucune tâche à afficher pour le moment" + +#: client/src/controllers/Projects.js:114 +msgid "" +"There is no SCM update information available for this project. An update has " +"not yet been completed. If you have not already done so, start an update " +"for this project." +msgstr "" +"Aucune information de mise à jour SCM n'est disponible pour ce projet. Une " +"mise à jour n'est pas encore terminée. Si vous n'avez pas encore lancé une " +"mise à jour pour ce projet, faites-le." + +#: client/src/configuration/configuration.controller.js:293 +msgid "There was an error resetting value. Returned status:" +msgstr "" +"Une erreur s'est produite lors de la réinitialisation de la valeur. État " +"renvoyé :" + +#: client/src/configuration/configuration.controller.js:424 +msgid "There was an error resetting values. Returned status:" +msgstr "" +"Une erreur s'est produite lors de la réinitialisation des valeurs. État " +"renvoyé :" + +#: client/src/helpers/Credentials.js:138 +msgid "" +"This is the tenant name. This value is usually the same as the username." +msgstr "" +"Il s'agit du nom du client. Cette valeur est habituellement la même que " +"celle du nom d'utilisateur." + +#: client/src/notifications/notifications.list.js:21 +msgid "" +"This list is populated by notification templates added from the " +"%sNotifications%s section" +msgstr "" +"Cette liste contient des modèles de notification ajoutés à partir de la " +"section %sNotifications%s" + +#: client/src/notifications/notificationTemplates.form.js:199 +msgid "This must be of the form %s." +msgstr "Elle doit se présenter au format %s." + +#: client/src/forms/Users.js:160 +msgid "This user is not a member of any teams" +msgstr "Cet utilisateur n'est pas membre d'une équipe" + +#: client/src/shared/form-generator.js:823 +#: client/src/shared/form-generator.js:948 +msgid "" +"This value does not match the password you entered previously. Please " +"confirm that password." +msgstr "" +"Cette valeur ne correspond pas au mot de passe que vous avez entré " +"précédemment. Veuillez confirmer ce mot de passe." + +#: client/src/configuration/configuration.controller.js:449 +msgid "" +"This will reset all configuration values to their factory defaults. Are you " +"sure you want to proceed?" +msgstr "" +"Cette opération rétablit toutes les valeurs de configuration sur leurs " +"valeurs par défaut. Voulez-vous vraiment continuer ?" + +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:14 +msgid "Time" +msgstr "Durée" + +#: client/src/license/license.partial.html:45 +msgid "Time Remaining" +msgstr "Durée restante" + +#: client/src/forms/Projects.js:191 +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 "" +"Délai en secondes à prévoir pour qu'un projet soit actualisé. Durant " +"l'exécution des tâches et les rappels, le système de tâches évalue " +"l'horodatage de la dernière mise à jour du projet. Si elle est plus ancienne " +"que le délai d'expiration du cache, elle n'est pas considérée comme " +"actualisée, et une nouvelle mise à jour du projet sera effectuée." + +#: client/src/forms/Credentials.js:126 +msgid "" +"To learn more about the IAM STS Token, refer to the %sAmazon documentation%s." +"" +msgstr "" +"Pour en savoir plus sur le token STS d'IAM, reportez-vous à la documentation " +"d'%Amazon%s." + +#: client/src/shared/form-generator.js:848 +msgid "Toggle the display of plaintext." +msgstr "Bascule l'affichage du texte en clair." + +#: client/src/notifications/shared/type-change.service.js:34 +#: client/src/notifications/shared/type-change.service.js:40 +msgid "Token" +msgstr "Token" + +#: client/src/forms/Credentials.js:61 +#: client/src/forms/Credentials.js:85 +#: client/src/forms/Teams.js:132 +#: client/src/forms/Users.js:196 +#: client/src/forms/WorkflowMaker.js:34 +#: client/src/lists/CompletedJobs.js:50 +#: client/src/lists/Credentials.js:39 +#: client/src/lists/Projects.js:48 +#: client/src/lists/ScheduledJobs.js:42 +#: client/src/lists/Templates.js:31 +#: client/src/notifications/notificationTemplates.form.js:54 +#: client/src/notifications/notificationTemplates.list.js:38 +#: client/src/notifications/notifications.list.js:31 +msgid "Type" +msgstr "Type" + +#: client/src/forms/Credentials.js:25 +#: client/src/notifications/notificationTemplates.form.js:23 +msgid "Type Details" +msgstr "Détails sur le type" + +#: client/src/notifications/notificationTemplates.form.js:212 +#: client/src/notifications/notificationTemplates.form.js:97 +msgid "Type an option on each line." +msgstr "Tapez une option sur chaque ligne." + +#: client/src/notifications/notificationTemplates.form.js:141 +#: client/src/notifications/notificationTemplates.form.js:158 +#: client/src/notifications/notificationTemplates.form.js:370 +msgid "Type an option on each line. The pound symbol (#) is not required." +msgstr "" +"Tapez une option sur chaque ligne. Le symbole dièse (#) n'est pas nécessaire." +"" + +#: client/src/controllers/Projects.js:402 +#: client/src/controllers/Projects.js:684 +msgid "URL popover text" +msgstr "Texte popover de l'URL" + +#: client/src/login/loginModal/loginModal.partial.html:49 +msgid "USERNAME" +msgstr "NOM D'UTILISATEUR" + +#: client/src/app.js:365 +msgid "USERS" +msgstr "UTILISATEURS" + +#: client/src/controllers/Projects.js:220 +msgid "Update Not Found" +msgstr "Mise à jour introuvable" + +#: client/src/controllers/Projects.js:693 +msgid "Update in Progress" +msgstr "Mise à jour en cours" + +#: client/src/forms/Projects.js:172 +msgid "Update on Launch" +msgstr "Mettre à jour au lancement" + +#: client/src/license/license.partial.html:71 +msgid "Upgrade" +msgstr "Mettre à niveau" + +#: client/src/notifications/notificationTemplates.form.js:404 +msgid "Use SSL" +msgstr "Utiliser SSL" + +#: client/src/notifications/notificationTemplates.form.js:397 +msgid "Use TLS" +msgstr "Utiliser TLS" + +#: client/src/forms/Credentials.js:77 +msgid "" +"Used to check out and synchronize playbook repositories with a remote source " +"control management system such as Git, Subversion (svn), or Mercurial (hg). " +"These credentials are used by Projects." +msgstr "" +"Utilisé pour vérifier et synchroniser les référentiels de playbooks avec un " +"SCM à distance tel que Git, Subversion (svn) ou Mercurial (hg). Ces " +"informations d'identification sont utilisées par les Projets." + +#: client/src/forms/Credentials.js:449 +#: client/src/forms/Inventories.js:115 +#: client/src/forms/Inventories.js:161 +#: client/src/forms/Organizations.js:83 +#: client/src/forms/Projects.js:244 +#: client/src/forms/Teams.js:94 +msgid "User" +msgstr "Utilisateur" + +#: client/src/forms/Users.js:94 +msgid "User Type" +msgstr "Type d'utilisateur" + +#: client/src/forms/Users.js:49 +#: client/src/helpers/Credentials.js:117 +#: client/src/helpers/Credentials.js:32 +#: client/src/helpers/Credentials.js:56 +#: client/src/helpers/Credentials.js:88 +#: client/src/lists/Users.js:37 +#: client/src/notifications/notificationTemplates.form.js:64 +msgid "Username" +msgstr "Nom d'utilisateur" + +#: client/src/forms/Credentials.js:81 +msgid "" +"Usernames, passwords, and access keys for authenticating to the specified " +"cloud or infrastructure provider. These are used for dynamic inventory " +"sources and for cloud provisioning and deployment in playbook runs." +msgstr "" +"Noms d'utilisateur, mots de passe et clés d'accès pour s'authentifier auprès " +"du fournisseur de cloud ou d'infrastructure spécifié. Ceux-ci sont utilisés " +"pour les sources d'inventaire dynamique et pour l'authentification de " +"services dans le cloud et leur déploiement dans les playbooks." + +#: client/src/forms/Teams.js:75 +#: client/src/lists/Users.js:26 +#: client/src/lists/Users.js:27 +#: client/src/setup-menu/setup-menu.partial.html:10 +msgid "Users" +msgstr "Utilisateurs" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:7 +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:7 +msgid "VIEW ALL" +msgstr "TOUT AFFICHER" + +#: client/src/main-menu/main-menu.partial.html:75 +msgid "VIEW DOCUMENTATION" +msgstr "AFFICHER LA DOCUMENTATION" + +#: client/src/main-menu/main-menu.partial.html:51 +msgid "VIEW USER PAGE FOR {{ $root.current_user.username | uppercase }}" +msgstr "" +"AFFICHER LA PAGE UTILISATEUR POUR {{ $root.current_user.username | uppercase " +"}}" + +#: client/src/license/license.partial.html:10 +msgid "Valid License" +msgstr "Licence valide" + +#: client/src/forms/Inventories.js:55 +msgid "Variables" +msgstr "Variables" + +#: client/src/forms/Credentials.js:389 +msgid "Vault Password" +msgstr "Mot de passe Vault" + +#: client/src/forms/JobTemplates.js:235 +#: client/src/forms/JobTemplates.js:242 +msgid "Verbosity" +msgstr "Verbosité" + +#: client/src/about/about.controller.js:24 +#: client/src/license/license.partial.html:15 +msgid "Version" +msgstr "Version" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:58 +#: client/src/inventory-scripts/inventory-scripts.list.js:65 +#: client/src/lists/Credentials.js:80 +#: client/src/lists/Inventories.js:85 +#: client/src/lists/Teams.js:69 +#: client/src/lists/Templates.js:117 +#: client/src/lists/Users.js:78 +#: client/src/notifications/notificationTemplates.list.js:80 +msgid "View" +msgstr "Afficher" + +#: client/src/main-menu/main-menu.partial.html:173 +msgid "View Documentation" +msgstr "Afficher la documentation" + +#: client/src/forms/Inventories.js:65 +msgid "View JSON examples at %s" +msgstr "Afficher les exemples JSON à %s" + +#: client/src/forms/JobTemplates.js:450 +#: client/src/forms/Workflows.js:163 +#: client/src/shared/form-generator.js:1715 +msgid "View Survey" +msgstr "Afficher le questionnaire" + +#: client/src/forms/Inventories.js:66 +msgid "View YAML examples at %s" +msgstr "Afficher les exemples YAML à %s" + +#: client/src/setup-menu/setup-menu.partial.html:47 +msgid "View Your License" +msgstr "Afficher votre licence" + +#: client/src/setup-menu/setup-menu.partial.html:48 +msgid "View and edit your license information." +msgstr "Affichez et modifiez vos informations de licence." + +#: client/src/lists/Credentials.js:82 +msgid "View credential" +msgstr "Afficher les informations d'identification" + +#: client/src/setup-menu/setup-menu.partial.html:60 +msgid "View information about this version of Ansible Tower." +msgstr "Afficher les informations sur cette version d'Ansible Tower." + +#: client/src/lists/Inventories.js:87 +msgid "View inventory" +msgstr "Afficher l'inventaire" + +#: client/src/inventory-scripts/inventory-scripts.list.js:67 +msgid "View inventory script" +msgstr "Afficher le script d'inventaire" + +#: client/src/notifications/notificationTemplates.list.js:82 +msgid "View notification" +msgstr "Afficher la notification" + +#: client/src/lists/Teams.js:72 +msgid "View team" +msgstr "Afficher l'équipe" + +#: client/src/lists/Templates.js:119 +msgid "View template" +msgstr "Afficher le modèle" + +#: client/src/lists/Projects.js:108 +msgid "View the project" +msgstr "Afficher le projet" + +#: client/src/lists/ScheduledJobs.js:73 +msgid "View the schedule" +msgstr "Afficher le calendrier" + +#: client/src/lists/Users.js:81 +msgid "View user" +msgstr "Afficher l'utilisateur" + +#: client/src/forms/Workflows.js:22 +msgid "WORKFLOW" +msgstr "WORKFLOW" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:68 +#: client/src/configuration/configuration.controller.js:168 +#: client/src/configuration/configuration.controller.js:230 +#: client/src/configuration/system-form/configuration-system.controller.js:47 +msgid "Warning: Unsaved Changes" +msgstr "Avertissement : modifications non enregistrées" + +#: client/src/login/loginModal/loginModal.partial.html:17 +msgid "Welcome to Ansible Tower!  Please sign in." +msgstr "Bienvenue à Ansible Tower !  Veuillez vous connecter." + +#: client/src/license/license.partial.html:78 +msgid "" +"Welcome to Ansible Tower! Please complete the steps below to acquire a " +"license." +msgstr "" +"Bienvenue à Ansible Tower ! Veuillez suivre les étapes ci-dessous pour " +"obtenir une licence." + +#: client/src/forms/JobTemplates.js:55 +#: client/src/forms/WorkflowMaker.js:104 +msgid "" +"When this template is submitted as a job, setting the type to %s will " +"execute the playbook, running tasks on the selected hosts." +msgstr "" +"Lorsque ce modèle est validé en tant que tâche, le fait de définir le type " +"sur %s exécute le playbook en lançant les tâches sur les hôtes sélectionnés." + +#: client/src/forms/Workflows.js:187 +#: client/src/shared/form-generator.js:1719 +msgid "Workflow Editor" +msgstr "Workflow Editor" + +#: client/src/lists/Templates.js:70 +msgid "Workflow Job Template" +msgstr "Modèle de tâche Workflow" + +#: client/src/controllers/Projects.js:468 +msgid "You do not have access to view this property" +msgstr "Vous n'avez pas d'accès pour afficher cette propriété" + +#: client/src/controllers/Projects.js:284 +msgid "You do not have permission to add a project." +msgstr "Vous n'êtes pas autorisé à ajouter un projet." + +#: client/src/controllers/Users.js:141 +msgid "You do not have permission to add a user." +msgstr "Vous n'êtes pas autorisé à ajouter un utilisateur." + +#: client/src/configuration/auth-form/configuration-auth.controller.js:67 +#: client/src/configuration/configuration.controller.js:167 +#: client/src/configuration/configuration.controller.js:229 +#: client/src/configuration/system-form/configuration-system.controller.js:46 +msgid "" +"You have unsaved changes. Would you like to proceed without " +"saving?" +msgstr "" +"Des modifications n'ont pas été enregistrées. Voulez-vous continuer " +"sans les enregistrer ?" + +#: client/src/shared/form-generator.js:960 +msgid "Your password must be %d characters long." +msgstr "Votre mot de passe doit comporter %d caractères." + +#: client/src/shared/form-generator.js:965 +msgid "Your password must contain a lowercase letter." +msgstr "Votre mot de passe doit contenir une lettre minuscule." + +#: client/src/shared/form-generator.js:975 +msgid "Your password must contain a number." +msgstr "Votre mot de passe doit contenir un chiffre." + +#: client/src/shared/form-generator.js:970 +msgid "Your password must contain an uppercase letter." +msgstr "Votre mot de passe doit contenir une lettre majuscule." + +#: client/src/shared/form-generator.js:980 +msgid "Your password must contain one of the following characters: %s" +msgstr "Votre mot de passe doit contenir l'un des caractères suivants : %s" + +#: client/src/controllers/Projects.js:176 +msgid "Your request to cancel the update was submitted to the task manager." +msgstr "" +"Votre demande d'annulation de la mise à jour a été envoyée au gestionnaire " +"de tâches." + +#: client/src/login/loginModal/loginModal.partial.html:22 +msgid "Your session timed out due to inactivity. Please sign in." +msgstr "" +"Votre session a expiré en raison d'un temps d'inactivité. Veuillez vous " +"connecter." + +#: client/src/shared/form-generator.js:1224 +msgid "and" +msgstr "et" + +#: client/src/forms/Credentials.js:139 +#: client/src/forms/Credentials.js:362 +msgid "set in helpers/credentials" +msgstr "définir dans helpers/credentials" + +#: client/src/forms/Credentials.js:379 +msgid "v2 URLs%s - leave blank" +msgstr "v2 URLs%s - laisser vide" + +#: client/src/forms/Credentials.js:380 +msgid "v3 default%s - set to 'default'" +msgstr "v3 default%s - définir sur 'default'" + +#: client/src/forms/Credentials.js:381 +msgid "v3 multi-domain%s - your domain name" +msgstr "v3 multi-domain%s - votre nom de domaine" + diff --git a/awx/locale/fr/LC_MESSAGES/django.mo b/awx/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000000..7eb3f5d74c Binary files /dev/null and b/awx/locale/fr/LC_MESSAGES/django.mo differ diff --git a/awx/locale/fr/LC_MESSAGES/django.po b/awx/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 0000000000..cc83af8198 --- /dev/null +++ b/awx/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,4303 @@ +# Corina Roe , 2017. #zanata +# Sam Friedmann , 2017. #zanata +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-12-15 12:05+0530\n" +"PO-Revision-Date: 2017-01-11 01:57+0000\n" +"Last-Translator: Corina Roe \n" +"Language-Team: French\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" +"X-Generator: Zanata 3.9.6\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" + +#: api/authentication.py:67 +msgid "Invalid token header. No credentials provided." +msgstr "" +"En-tête de token non valide. Aucune information d'identification fournie." + +#: api/authentication.py:70 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" +"En-tête de token non valide. La chaîne token ne doit pas contenir d'espaces." + +#: api/authentication.py:105 +msgid "User inactive or deleted" +msgstr "Utilisateur inactif ou supprimé" + +#: api/authentication.py:161 +msgid "Invalid task token" +msgstr "Token de tâche non valide" + +#: api/conf.py:12 +msgid "Idle Time Force Log Out" +msgstr "Temps d'inactivité - Forcer la déconnexion" + +#: api/conf.py:13 +msgid "" +"Number of seconds that a user is inactive before they will need to login " +"again." +msgstr "" +"Délai en secondes pendant lequel un utilisateur peut rester inactif avant de " +"devoir se reconnecter." + +#: api/conf.py:14 +#: api/conf.py:24 +#: api/conf.py:33 +#: sso/conf.py:124 +#: sso/conf.py:135 +#: sso/conf.py:147 +#: sso/conf.py:162 +msgid "Authentication" +msgstr "Authentification" + +#: api/conf.py:22 +msgid "Maximum number of simultaneous logins" +msgstr "Nombre maximal de connexions simultanées" + +#: api/conf.py:23 +msgid "" +"Maximum number of simultaneous logins a user may have. To disable enter -1." +msgstr "" +"Nombre maximal de connexions simultanées dont un utilisateur peut disposer. " +"Pour désactiver cette option, entrez -1." + +#: api/conf.py:31 +msgid "Enable HTTP Basic Auth" +msgstr "Activer l'authentification HTTP de base" + +#: api/conf.py:32 +msgid "Enable HTTP Basic Auth for the API Browser." +msgstr "Activer l'authentification HTTP de base pour le navigateur d'API." + +#: api/generics.py:446 +msgid "\"id\" is required to disassociate" +msgstr "\"id\" est nécessaire pour dissocier" + +#: api/metadata.py:50 +msgid "Database ID for this {}." +msgstr "ID de base de données pour ce {}." + +#: api/metadata.py:51 +msgid "Name of this {}." +msgstr "Nom de ce {}." + +#: api/metadata.py:52 +msgid "Optional description of this {}." +msgstr "Description facultative de ce {}." + +#: api/metadata.py:53 +msgid "Data type for this {}." +msgstr "Type de données pour ce {}." + +#: api/metadata.py:54 +msgid "URL for this {}." +msgstr "URL de ce {}." + +#: api/metadata.py:55 +msgid "Data structure with URLs of related resources." +msgstr "Structure de données avec URL des ressources associées." + +#: api/metadata.py:56 +msgid "Data structure with name/description for related resources." +msgstr "Structure de données avec nom/description des ressources associées." + +#: api/metadata.py:57 +msgid "Timestamp when this {} was created." +msgstr "Horodatage lors de la création de ce {}." + +#: api/metadata.py:58 +msgid "Timestamp when this {} was last modified." +msgstr "Horodatage lors de la modification de ce {}." + +#: api/parsers.py:31 +#, python-format +msgid "JSON parse error - %s" +msgstr "Erreur d'analyse JSON - %s" + +#: api/serializers.py:248 +msgid "Playbook Run" +msgstr "Exécution du playbook" + +#: api/serializers.py:249 +msgid "Command" +msgstr "Commande" + +#: api/serializers.py:250 +msgid "SCM Update" +msgstr "Mise à jour SCM" + +#: api/serializers.py:251 +msgid "Inventory Sync" +msgstr "Synchronisation des inventaires" + +#: api/serializers.py:252 +msgid "Management Job" +msgstr "Tâche de gestion" + +#: api/serializers.py:253 +msgid "Workflow Job" +msgstr "Tâche de workflow" + +#: api/serializers.py:655 +#: api/serializers.py:713 +#: api/views.py:3914 +#, python-format +msgid "" +"Standard Output too large to display (%(text_size)d bytes), only download " +"supported for sizes over %(supported_size)d bytes" +msgstr "" +"Sortie standard trop grande pour pouvoir s'afficher (%(text_size)d octets). " +"Le téléchargement est pris en charge seulement pour une taille supérieure à " +"%(supported_size)d octets" + +#: api/serializers.py:728 +msgid "Write-only field used to change the password." +msgstr "Champ en écriture seule servant à modifier le mot de passe." + +#: api/serializers.py:730 +msgid "Set if the account is managed by an external service" +msgstr "À définir si le compte est géré par un service externe" + +#: api/serializers.py:754 +msgid "Password required for new User." +msgstr "Mot de passe requis pour le nouvel utilisateur." + +#: api/serializers.py:838 +#, python-format +msgid "Unable to change %s on user managed by LDAP." +msgstr "Impossible de redéfinir %s sur un utilisateur géré par LDAP." + +#: api/serializers.py:990 +msgid "Organization is missing" +msgstr "L'organisation est manquante" + +#: api/serializers.py:996 +msgid "Array of playbooks available within this project." +msgstr "Tableau des playbooks disponibles dans ce projet." + +#: api/serializers.py:1178 +#, python-format +msgid "Invalid port specification: %s" +msgstr "Spécification de port non valide : %s" + +#: api/serializers.py:1206 +#: main/validators.py:192 +msgid "Must be valid JSON or YAML." +msgstr "Syntaxe JSON ou YAML valide exigée." + +#: api/serializers.py:1263 +msgid "Invalid group name." +msgstr "Nom de groupe incorrect." + +#: api/serializers.py:1338 +msgid "" +"Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python" +msgstr "" +"Le script doit commencer par une séquence hashbang : c.-à-d. ... #!/usr/bin/" +"env python" + +#: api/serializers.py:1391 +msgid "If 'source' is 'custom', 'source_script' must be provided." +msgstr "Si la valeur 'source' est 'custom', 'source_script' doit être défini." + +#: api/serializers.py:1395 +msgid "" +"The 'source_script' does not belong to the same organization as the " +"inventory." +msgstr "" +"Le 'source_script' n'appartient pas à la même organisation que l'inventaire." + +#: api/serializers.py:1397 +msgid "'source_script' doesn't exist." +msgstr "'source_script' n'existe pas." + +#: api/serializers.py:1756 +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 "" +"Champ en écriture seule qui sert à ajouter un utilisateur au rôle de " +"propriétaire. Si vous le définissez, n'entrez ni équipe ni organisation. " +"Seulement valable pour la création." + +#: api/serializers.py:1761 +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 "" +"Champ en écriture seule qui sert à ajouter une équipe au rôle de " +"propriétaire. Si vous le définissez, n'entrez ni utilisateur ni organisation." +" Seulement valable pour la création." + +#: api/serializers.py:1766 +msgid "" +"Inherit permissions from organization roles. If provided on creation, do not " +"give either user or team." +msgstr "" +"Hériter des permissions à partir des rôles d'organisation. Si vous le " +"définissez lors de la création, n'entrez ni utilisateur ni équipe." + +#: api/serializers.py:1782 +msgid "Missing 'user', 'team', or 'organization'." +msgstr "Valeur 'utilisateur', 'équipe' ou 'organisation' manquante." + +#: api/serializers.py:1795 +msgid "" +"Credential organization must be set and match before assigning to a team" +msgstr "" +"L'organisation des informations d'identification doit être définie et mise " +"en correspondance avant de l'attribuer à une équipe" + +#: api/serializers.py:1887 +msgid "This field is required." +msgstr "Ce champ est obligatoire." + +#: api/serializers.py:1889 +#: api/serializers.py:1891 +msgid "Playbook not found for project." +msgstr "Playbook introuvable pour le projet." + +#: api/serializers.py:1893 +msgid "Must select playbook for project." +msgstr "Un playbook doit être sélectionné pour le project." + +#: api/serializers.py:1957 +#: main/models/jobs.py:280 +msgid "Scan jobs must be assigned a fixed inventory." +msgstr "Un inventaire fixe doit être assigné aux tâches de scan." + +#: api/serializers.py:1959 +#: main/models/jobs.py:283 +msgid "Job types 'run' and 'check' must have assigned a project." +msgstr "Un projet doit être assigné aux types de tâche 'run' et 'check'." + +#: api/serializers.py:1962 +msgid "Survey Enabled cannot be used with scan jobs." +msgstr "" +"L'option Questionnaire activé ne peut pas être utilisée avec les tâches de " +"scan." + +#: api/serializers.py:2024 +msgid "Invalid job template." +msgstr "Modèle de tâche non valide." + +#: api/serializers.py:2109 +msgid "Credential not found or deleted." +msgstr "Informations d'identification introuvables ou supprimées." + +#: api/serializers.py:2111 +msgid "Job Template Project is missing or undefined." +msgstr "Le projet de modèle de tâche est manquant ou non défini." + +#: api/serializers.py:2113 +msgid "Job Template Inventory is missing or undefined." +msgstr "Le projet de modèle d'inventaire est manquant ou non défini." + +#: api/serializers.py:2398 +#, python-format +msgid "%(job_type)s is not a valid job type. The choices are %(choices)s." +msgstr "" +"%(job_type)s n'est pas un type de tâche valide. Les choix sont %(choices)s." + +#: api/serializers.py:2403 +msgid "Workflow job template is missing during creation." +msgstr "Le modèle de tâche Workflow est manquant lors de la création." + +#: api/serializers.py:2408 +#, python-format +msgid "Cannot nest a %s inside a WorkflowJobTemplate" +msgstr "Impossible d'imbriquer %s dans un modèle de tâche Workflow." + +#: api/serializers.py:2646 +#, python-format +msgid "Job Template '%s' is missing or undefined." +msgstr "Le modèle de tâche '%s' est manquant ou non défini." + +#: api/serializers.py:2672 +msgid "Must be a valid JSON or YAML dictionary." +msgstr "Dictionnaire JSON ou YAML valide exigé." + +#: api/serializers.py:2817 +msgid "" +"Missing required fields for Notification Configuration: notification_type" +msgstr "" +"Champs obligatoires manquants pour la configuration des notifications : " +"notification_type" + +#: api/serializers.py:2840 +msgid "No values specified for field '{}'" +msgstr "Aucune valeur spécifiée pour le champ '{}'" + +#: api/serializers.py:2845 +msgid "Missing required fields for Notification Configuration: {}." +msgstr "" +"Champs obligatoires manquants pour la configuration des notifications : {}." + +#: api/serializers.py:2848 +msgid "Configuration field '{}' incorrect type, expected {}." +msgstr "Type de champ de configuration '{}' incorrect, {} attendu." + +#: api/serializers.py:2901 +msgid "Inventory Source must be a cloud resource." +msgstr "La source d'inventaire doit être une ressource cloud." + +#: api/serializers.py:2903 +msgid "Manual Project can not have a schedule set." +msgstr "Le projet manuel ne peut pas avoir de calendrier défini." + +#: api/serializers.py:2925 +msgid "" +"DTSTART required in rrule. Value should match: DTSTART:YYYYMMDDTHHMMSSZ" +msgstr "" +"DTSTART obligatoire dans rrule. La valeur doit correspondre à : DTSTART:" +"YYYYMMDDTHHMMSSZ" + +#: api/serializers.py:2927 +msgid "Multiple DTSTART is not supported." +msgstr "Une seule valeur DTSTART est prise en charge." + +#: api/serializers.py:2929 +msgid "RRULE require in rrule." +msgstr "RRULE obligatoire dans rrule." + +#: api/serializers.py:2931 +msgid "Multiple RRULE is not supported." +msgstr "Une seule valeur RRULE est prise en charge." + +#: api/serializers.py:2933 +msgid "INTERVAL required in rrule." +msgstr "INTERVAL obligatoire dans rrule." + +#: api/serializers.py:2935 +msgid "TZID is not supported." +msgstr "TZID n'est pas pris en charge." + +#: api/serializers.py:2937 +msgid "SECONDLY is not supported." +msgstr "SECONDLY n'est pas pris en charge." + +#: api/serializers.py:2939 +msgid "Multiple BYMONTHDAYs not supported." +msgstr "Une seule valeur BYMONTHDAY est prise en charge." + +#: api/serializers.py:2941 +msgid "Multiple BYMONTHs not supported." +msgstr "Une seule valeur BYMONTH est prise en charge." + +#: api/serializers.py:2943 +msgid "BYDAY with numeric prefix not supported." +msgstr "BYDAY avec un préfixe numérique non pris en charge." + +#: api/serializers.py:2945 +msgid "BYYEARDAY not supported." +msgstr "BYYEARDAY non pris en charge." + +#: api/serializers.py:2947 +msgid "BYWEEKNO not supported." +msgstr "BYWEEKNO non pris en charge." + +#: api/serializers.py:2951 +msgid "COUNT > 999 is unsupported." +msgstr "COUNT > 999 non pris en charge." + +#: api/serializers.py:2955 +msgid "rrule parsing failed validation." +msgstr "L'analyse rrule n'a pas pu être validée." + +#: api/serializers.py:2973 +msgid "" +"A summary of the new and changed values when an object is created, updated, " +"or deleted" +msgstr "" +"Un récapitulatif des valeurs nouvelles et modifiées lorsqu'un objet est " +"créé, mis à jour ou supprimé" + +#: api/serializers.py:2975 +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 "" +"Pour créer, mettre à jour et supprimer des événements, il s'agit du type " +"d'objet qui a été affecté. Pour associer et dissocier des événements, il " +"s'agit du type d'objet associé à ou dissocié de object2." + +#: api/serializers.py:2978 +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 "" +"Laisser vide pour créer, mettre à jour et supprimer des événements. Pour " +"associer et dissocier des événements, il s'agit du type d'objet auquel " +"object1 est associé." + +#: api/serializers.py:2981 +msgid "The action taken with respect to the given object(s)." +msgstr "Action appliquée par rapport à l'objet ou aux objets donnés." + +#: api/serializers.py:3081 +msgid "Unable to login with provided credentials." +msgstr "Connexion impossible avec les informations d'identification fournies." + +#: api/serializers.py:3083 +msgid "Must include \"username\" and \"password\"." +msgstr "Elles doivent inclure le nom d'utilisateur et le mot de passe." + +#: api/views.py:96 +msgid "Your license does not allow use of the activity stream." +msgstr "Votre licence ne permet pas l'utilisation du flux d'activité." + +#: api/views.py:106 +msgid "Your license does not permit use of system tracking." +msgstr "Votre licence ne permet pas l'utilisation du suivi du système." + +#: api/views.py:116 +msgid "Your license does not allow use of workflows." +msgstr "Votre licence ne permet pas l'utilisation de workflows." + +#: api/views.py:124 +#: templates/rest_framework/api.html:28 +msgid "REST API" +msgstr "API REST" + +#: api/views.py:131 +#: templates/rest_framework/api.html:4 +msgid "Ansible Tower REST API" +msgstr "API REST Ansible Tower" + +#: api/views.py:147 +msgid "Version 1" +msgstr "Version 1" + +#: api/views.py:198 +msgid "Ping" +msgstr "Ping" + +#: api/views.py:227 +#: conf/apps.py:12 +msgid "Configuration" +msgstr "Configuration" + +#: api/views.py:280 +msgid "Invalid license data" +msgstr "Données de licence non valides" + +#: api/views.py:282 +msgid "Missing 'eula_accepted' property" +msgstr "Propriété 'eula_accepted' manquante" + +#: api/views.py:286 +msgid "'eula_accepted' value is invalid" +msgstr "La valeur 'eula_accepted' n'est pas valide" + +#: api/views.py:289 +msgid "'eula_accepted' must be True" +msgstr "La valeur 'eula_accepted' doit être True" + +#: api/views.py:296 +msgid "Invalid JSON" +msgstr "Syntaxe JSON non valide" + +#: api/views.py:304 +msgid "Invalid License" +msgstr "Licence non valide" + +#: api/views.py:314 +msgid "Invalid license" +msgstr "Licence non valide" + +#: api/views.py:322 +#, python-format +msgid "Failed to remove license (%s)" +msgstr "Suppression de la licence (%s) impossible" + +#: api/views.py:327 +msgid "Dashboard" +msgstr "Tableau de bord" + +#: api/views.py:433 +msgid "Dashboard Jobs Graphs" +msgstr "Graphiques de tâches du tableau de bord" + +#: api/views.py:469 +#, python-format +msgid "Unknown period \"%s\"" +msgstr "Période \"%s\" inconnue" + +#: api/views.py:483 +msgid "Schedules" +msgstr "Calendriers" + +#: api/views.py:502 +msgid "Schedule Jobs List" +msgstr "Listes des tâches de planification" + +#: api/views.py:711 +msgid "Your Tower license only permits a single organization to exist." +msgstr "Votre licence Tower permet l'existence d'une seule organisation." + +#: api/views.py:932 +#: api/views.py:1284 +msgid "Role 'id' field is missing." +msgstr "Le champ \"id\" du rôle est manquant." + +#: api/views.py:938 +#: api/views.py:4182 +msgid "You cannot assign an Organization role as a child role for a Team." +msgstr "" +"Vous ne pouvez pas attribuer un rôle Organisation en tant que rôle enfant " +"pour une équipe." + +#: api/views.py:942 +#: api/views.py:4196 +msgid "You cannot grant system-level permissions to a team." +msgstr "" +"Vous ne pouvez pas accorder de permissions au niveau système à une équipe." + +#: api/views.py:949 +#: api/views.py:4188 +msgid "" +"You cannot grant credential access to a team when the Organization field " +"isn't set, or belongs to a different organization" +msgstr "" +"Vous ne pouvez pas accorder d'accès par informations d'identification à une " +"équipe lorsque le champ Organisation n'est pas défini ou qu'elle appartient " +"à une organisation différente" + +#: api/views.py:1039 +msgid "Cannot delete project." +msgstr "Suppression du projet impossible." + +#: api/views.py:1068 +msgid "Project Schedules" +msgstr "Calendriers des projets" + +#: api/views.py:1168 +#: api/views.py:2252 +#: api/views.py:3225 +msgid "Cannot delete job resource when associated workflow job is running." +msgstr "" +"Impossible de supprimer les ressources de tâche lorsqu'une tâche de workflow " +"associée est en cours d'exécution." + +#: api/views.py:1244 +msgid "Me" +msgstr "Moi-même" + +#: api/views.py:1288 +#: api/views.py:4137 +msgid "You may not perform any action with your own admin_role." +msgstr "Vous ne pouvez pas effectuer d'action avec votre propre admin_role." + +#: api/views.py:1294 +#: api/views.py:4141 +msgid "You may not change the membership of a users admin_role" +msgstr "" +"Vous ne pouvez pas modifier l'appartenance de l'admin_role d'un utilisateur" + +#: api/views.py:1299 +#: api/views.py:4146 +msgid "" +"You cannot grant credential access to a user not in the credentials' " +"organization" +msgstr "" +"Vous ne pouvez pas accorder d'accès par informations d'identification à un " +"utilisateur ne figurant pas dans l'organisation d'informations " +"d'identification." + +#: api/views.py:1303 +#: api/views.py:4150 +msgid "You cannot grant private credential access to another user" +msgstr "" +"Vous ne pouvez pas accorder d'accès privé par informations d'identification " +"à un autre utilisateur" + +#: api/views.py:1401 +#, python-format +msgid "Cannot change %s." +msgstr "Impossible de modifier %s." + +#: api/views.py:1407 +msgid "Cannot delete user." +msgstr "Impossible de supprimer l'utilisateur." + +#: api/views.py:1553 +msgid "Cannot delete inventory script." +msgstr "Impossible de supprimer le script d'inventaire." + +#: api/views.py:1788 +msgid "Fact not found." +msgstr "Fait introuvable." + +#: api/views.py:2108 +msgid "Inventory Source List" +msgstr "Liste des sources d'inventaire" + +#: api/views.py:2136 +msgid "Cannot delete inventory source." +msgstr "Impossible de supprimer la source d'inventaire." + +#: api/views.py:2144 +msgid "Inventory Source Schedules" +msgstr "Calendriers des sources d'inventaire" + +#: api/views.py:2173 +msgid "Notification Templates can only be assigned when source is one of {}." +msgstr "" +"Les modèles de notification ne peuvent être attribués que lorsque la source " +"est l'une des {}." + +#: api/views.py:2380 +msgid "Job Template Schedules" +msgstr "Calendriers des modèles de tâche" + +#: api/views.py:2399 +#: api/views.py:2409 +msgid "Your license does not allow adding surveys." +msgstr "Votre licence ne permet pas l'ajout de questionnaires." + +#: api/views.py:2416 +msgid "'name' missing from survey spec." +msgstr "'name' manquant dans la spécification du questionnaire." + +#: api/views.py:2418 +msgid "'description' missing from survey spec." +msgstr "'description' manquante dans la spécification du questionnaire." + +#: api/views.py:2420 +msgid "'spec' missing from survey spec." +msgstr "'spec' manquante dans la spécification du questionnaire." + +#: api/views.py:2422 +msgid "'spec' must be a list of items." +msgstr "'spec' doit être une liste d'éléments" + +#: api/views.py:2424 +msgid "'spec' doesn't contain any items." +msgstr "'spec' ne contient aucun élément." + +#: api/views.py:2429 +#, python-format +msgid "Survey question %s is not a json object." +msgstr "La question %s n'est pas un objet json." + +#: api/views.py:2431 +#, python-format +msgid "'type' missing from survey question %s." +msgstr "'type' est manquant dans la question %s." + +#: api/views.py:2433 +#, python-format +msgid "'question_name' missing from survey question %s." +msgstr "'question_name' est manquant dans la question %s." + +#: api/views.py:2435 +#, python-format +msgid "'variable' missing from survey question %s." +msgstr "'variable' est manquant dans la question %s." + +#: api/views.py:2437 +#, python-format +msgid "'variable' '%(item)s' duplicated in survey question %(survey)s." +msgstr "'variable' '%(item)s' en double dans la question %(survey)s." + +#: api/views.py:2442 +#, python-format +msgid "'required' missing from survey question %s." +msgstr "'required' est manquant dans la question %s." + +#: api/views.py:2641 +msgid "No matching host could be found!" +msgstr "Aucun hôte correspondant n'a été trouvé." + +#: api/views.py:2644 +msgid "Multiple hosts matched the request!" +msgstr "Plusieurs hôtes correspondent à la requête." + +#: api/views.py:2649 +msgid "Cannot start automatically, user input required!" +msgstr "" +"Impossible de démarrer automatiquement, saisie de l'utilisateur obligatoire." + +#: api/views.py:2656 +msgid "Host callback job already pending." +msgstr "La tâche de rappel de l'hôte est déjà en attente." + +#: api/views.py:2669 +msgid "Error starting job!" +msgstr "Erreur lors du démarrage de la tâche." + +#: api/views.py:2995 +msgid "Workflow Job Template Schedules" +msgstr "Calendriers des modèles de tâche Workflow" + +#: api/views.py:3131 +#: api/views.py:3853 +msgid "Superuser privileges needed." +msgstr "Privilèges de superutilisateur requis." + +#: api/views.py:3161 +msgid "System Job Template Schedules" +msgstr "Calendriers des modèles de tâche Système" + +#: api/views.py:3344 +msgid "Job Host Summaries List" +msgstr "Liste récapitulative des hôtes de la tâche" + +#: api/views.py:3386 +msgid "Job Event Children List" +msgstr "Liste des enfants d'événement de la tâche" + +#: api/views.py:3395 +msgid "Job Event Hosts List" +msgstr "Liste des hôtes d'événement de la tâche" + +#: api/views.py:3404 +msgid "Job Events List" +msgstr "Liste des événements de la tâche" + +#: api/views.py:3436 +msgid "Job Plays List" +msgstr "Liste des activités de lecture de la tâche" + +#: api/views.py:3513 +msgid "Job Play Tasks List" +msgstr "Liste des activités de lecture de la tâche" + +#: api/views.py:3529 +msgid "Job not found." +msgstr "Tâche introuvable." + +#: api/views.py:3533 +msgid "'event_id' not provided." +msgstr "'event_id' non défini." + +#: api/views.py:3537 +msgid "Parent event not found." +msgstr "Événement parent introuvable." + +#: api/views.py:3809 +msgid "Ad Hoc Command Events List" +msgstr "Liste d'événements de la commande ad hoc" + +#: api/views.py:3963 +#, python-format +msgid "Error generating stdout download file: %s" +msgstr "Erreur lors de la génération du fichier de téléchargement stdout : %s" + +#: api/views.py:4009 +msgid "Delete not allowed while there are pending notifications" +msgstr "Suppression non autorisée tant que des notifications sont en attente" + +#: api/views.py:4016 +msgid "NotificationTemplate Test" +msgstr "Test de modèle de notification" + +#: api/views.py:4131 +msgid "User 'id' field is missing." +msgstr "Le champ \"id\" de l'utilisateur est manquant." + +#: api/views.py:4174 +msgid "Team 'id' field is missing." +msgstr "Le champ \"id\" de l'équipe est manquant." + +#: conf/conf.py:20 +msgid "Bud Frogs" +msgstr "Bud Frogs" + +#: conf/conf.py:21 +msgid "Bunny" +msgstr "Bunny" + +#: conf/conf.py:22 +msgid "Cheese" +msgstr "Cheese" + +#: conf/conf.py:23 +msgid "Daemon" +msgstr "Daemon" + +#: conf/conf.py:24 +msgid "Default Cow" +msgstr "Default Cow" + +#: conf/conf.py:25 +msgid "Dragon" +msgstr "Dragon" + +#: conf/conf.py:26 +msgid "Elephant in Snake" +msgstr "Elephant in Snake" + +#: conf/conf.py:27 +msgid "Elephant" +msgstr "Elephant" + +#: conf/conf.py:28 +msgid "Eyes" +msgstr "Eyes" + +#: conf/conf.py:29 +msgid "Hello Kitty" +msgstr "Hello Kitty" + +#: conf/conf.py:30 +msgid "Kitty" +msgstr "Kitty" + +#: conf/conf.py:31 +msgid "Luke Koala" +msgstr "Luke Koala" + +#: conf/conf.py:32 +msgid "Meow" +msgstr "Meow" + +#: conf/conf.py:33 +msgid "Milk" +msgstr "Milk" + +#: conf/conf.py:34 +msgid "Moofasa" +msgstr "Moofasa" + +#: conf/conf.py:35 +msgid "Moose" +msgstr "Moose" + +#: conf/conf.py:36 +msgid "Ren" +msgstr "Ren" + +#: conf/conf.py:37 +msgid "Sheep" +msgstr "Sheep" + +#: conf/conf.py:38 +msgid "Small Cow" +msgstr "Small Cow" + +#: conf/conf.py:39 +msgid "Stegosaurus" +msgstr "Stegosaurus" + +#: conf/conf.py:40 +msgid "Stimpy" +msgstr "Stimpy" + +#: conf/conf.py:41 +msgid "Super Milker" +msgstr "Super Milker" + +#: conf/conf.py:42 +msgid "Three Eyes" +msgstr "Three Eyes" + +#: conf/conf.py:43 +msgid "Turkey" +msgstr "Turkey" + +#: conf/conf.py:44 +msgid "Turtle" +msgstr "Turtle" + +#: conf/conf.py:45 +msgid "Tux" +msgstr "Tux" + +#: conf/conf.py:46 +msgid "Udder" +msgstr "Udder" + +#: conf/conf.py:47 +msgid "Vader Koala" +msgstr "Vader Koala" + +#: conf/conf.py:48 +msgid "Vader" +msgstr "Vader" + +#: conf/conf.py:49 +msgid "WWW" +msgstr "WWW" + +#: conf/conf.py:52 +msgid "Cow Selection" +msgstr "Sélection cow" + +#: conf/conf.py:53 +msgid "Select which cow to use with cowsay when running jobs." +msgstr "" +"Sélectionnez quel cow utiliser avec cowsay lors de l'exécution de tâches." + +#: conf/conf.py:54 +#: conf/conf.py:75 +msgid "Cows" +msgstr "Cows" + +#: conf/conf.py:73 +msgid "Example Read-Only Setting" +msgstr "Exemple de paramètre en lecture seule" + +#: conf/conf.py:74 +msgid "Example setting that cannot be changed." +msgstr "L'exemple de paramètre ne peut pas être modifié." + +#: conf/conf.py:93 +msgid "Example Setting" +msgstr "Exemple de paramètre" + +#: conf/conf.py:94 +msgid "Example setting which can be different for each user." +msgstr "Exemple de paramètre qui peut être différent pour chaque utilisateur." + +#: conf/conf.py:95 +#: conf/registry.py:67 +#: conf/views.py:46 +msgid "User" +msgstr "Utilisateur" + +#: conf/fields.py:38 +msgid "Enter a valid URL" +msgstr "Entez une URL valide" + +#: conf/license.py:19 +msgid "Your Tower license does not allow that." +msgstr "Votre licence Tower ne vous y autorise pas." + +#: conf/management/commands/migrate_to_database_settings.py:41 +msgid "Only show which settings would be commented/migrated." +msgstr "" +"Afficher seulement les paramètres qui pourraient être commentés/migrés." + +#: conf/management/commands/migrate_to_database_settings.py:48 +msgid "" +"Skip over settings that would raise an error when commenting/migrating." +msgstr "" +"Ignorer les paramètres qui pourraient provoquer une erreur lors de la saisie " +"de commentaires/de la migration." + +#: conf/management/commands/migrate_to_database_settings.py:55 +msgid "Skip commenting out settings in files." +msgstr "Ignorer la saisie de commentaires de paramètres dans les fichiers." + +#: conf/management/commands/migrate_to_database_settings.py:61 +msgid "Backup existing settings files with this suffix." +msgstr "Sauvegardez les fichiers de paramètres existants avec ce suffixe." + +#: conf/registry.py:55 +msgid "All" +msgstr "Tous" + +#: conf/registry.py:56 +msgid "Changed" +msgstr "Modifié" + +#: conf/registry.py:68 +msgid "User-Defaults" +msgstr "Paramètres utilisateur par défaut" + +#: conf/views.py:38 +msgid "Setting Categories" +msgstr "Catégories de paramètre" + +#: conf/views.py:61 +msgid "Setting Detail" +msgstr "Détails du paramètre" + +#: main/access.py:255 +#, python-format +msgid "Bad data found in related field %s." +msgstr "Données incorrectes trouvées dans le champ %s associé." + +#: main/access.py:296 +msgid "License is missing." +msgstr "La licence est manquante." + +#: main/access.py:298 +msgid "License has expired." +msgstr "La licence est arrivée à expiration." + +#: main/access.py:303 +#, python-format +msgid "License count of %s instances has been reached." +msgstr "Le nombre de licences d'instances %s a été atteint." + +#: main/access.py:305 +#, python-format +msgid "License count of %s instances has been exceeded." +msgstr "Le nombre de licences d'instances %s a été dépassé." + +#: main/access.py:307 +msgid "Host count exceeds available instances." +msgstr "Le nombre d'hôtes dépasse celui des instances disponibles." + +#: main/access.py:311 +#, python-format +msgid "Feature %s is not enabled in the active license." +msgstr "La fonctionnalité %s n'est pas activée dans la licence active." + +#: main/access.py:313 +msgid "Features not found in active license." +msgstr "Fonctionnalités introuvables dans la licence active." + +#: main/access.py:507 +#: main/access.py:574 +#: main/access.py:694 +#: main/access.py:957 +#: main/access.py:1198 +#: main/access.py:1587 +msgid "Resource is being used by running jobs" +msgstr "La ressource est utilisée par des tâches en cours d'exécution" + +#: main/access.py:618 +msgid "Unable to change inventory on a host." +msgstr "Impossible de modifier l'inventaire sur un hôte." + +#: main/access.py:630 +#: main/access.py:675 +msgid "Cannot associate two items from different inventories." +msgstr "Impossible d'associer deux éléments d'inventaires différents." + +#: main/access.py:663 +msgid "Unable to change inventory on a group." +msgstr "Impossible de modifier l'inventaire sur un groupe." + +#: main/access.py:877 +msgid "Unable to change organization on a team." +msgstr "Impossible de modifier l'organisation d'une équipe." + +#: main/access.py:890 +msgid "The {} role cannot be assigned to a team" +msgstr "Le rôle {} ne peut pas être attribué à une équipe" + +#: main/access.py:892 +msgid "The admin_role for a User cannot be assigned to a team" +msgstr "L'admin_role d'un utilisateur ne peut pas être attribué à une équipe" + +#: main/apps.py:9 +msgid "Main" +msgstr "Principal" + +#: main/conf.py:17 +msgid "Enable Activity Stream" +msgstr "Activer le flux d'activité" + +#: main/conf.py:18 +msgid "Enable capturing activity for the Tower activity stream." +msgstr "Activer la capture d'activités pour le flux d'activité Tower." + +#: main/conf.py:19 +#: main/conf.py:29 +#: main/conf.py:39 +#: main/conf.py:48 +#: main/conf.py:60 +#: main/conf.py:78 +#: main/conf.py:103 +msgid "System" +msgstr "Système" + +#: main/conf.py:27 +msgid "Enable Activity Stream for Inventory Sync" +msgstr "Activer le flux d'activité pour la synchronisation des inventaires" + +#: main/conf.py:28 +msgid "" +"Enable capturing activity for the Tower activity stream when running " +"inventory sync." +msgstr "" +"Activer la capture d'activités pour le flux d'activité Tower lors de la " +"synchronisation des inventaires." + +#: main/conf.py:37 +msgid "All Users Visible to Organization Admins" +msgstr "" +"Tous les utilisateurs visibles pour les administrateurs de l'organisation" + +#: main/conf.py:38 +msgid "" +"Controls whether any Organization Admin can view all users, even those not " +"associated with their Organization." +msgstr "" +"Contrôle si un administrateur d'organisation peut ou non afficher tous les " +"utilisateurs, même ceux qui ne sont pas associés à son organisation." + +#: main/conf.py:46 +msgid "Enable Tower Administrator Alerts" +msgstr "Activer les alertes administrateur de Tower" + +#: main/conf.py:47 +msgid "" +"Allow Tower to email Admin users for system events that may require " +"attention." +msgstr "" +"Autoriser Tower à alerter les administrateurs par email concernant des " +"événements système susceptibles de mériter leur attention." + +#: main/conf.py:57 +msgid "Base URL of the Tower host" +msgstr "URL de base pour l'hôte Tower" + +#: main/conf.py:58 +msgid "" +"This setting is used by services like notifications to render a valid url to " +"the Tower host." +msgstr "" +"Ce paramètre est utilisé par des services sous la forme de notifications " +"permettant de rendre valide une URL pour l'hôte Tower." + +#: main/conf.py:67 +msgid "Remote Host Headers" +msgstr "En-têtes d'hôte distant" + +#: main/conf.py:68 +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 " +"behind a reverse proxy.\n" +"\n" +"Note: The headers will be searched in order and the first found remote host " +"name or IP will be used.\n" +"\n" +"In the below example 8.8.8.7 would be the chosen IP address.\n" +"X-Forwarded-For: 8.8.8.7, 192.168.2.1, 127.0.0.1\n" +"Host: 127.0.0.1\n" +"REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST']" +msgstr "" +"En-têtes HTTP et méta-clés à rechercher afin de déterminer le nom ou " +"l'adresse IP d'un hôte distant. Ajoutez des éléments supplémentaires à cette " +"liste, tels que \"HTTP_X_FORWARDED_FOR\", en présence d'un proxy inverse.\n" +"\n" +"Remarque : les en-têtes seront recherchés dans l'ordre, et le premier nom ou " +"la première adresse IP d'hôte distant trouvé(e) sera utilisé(e).\n" +"\n" +"Dans l'exemple ci-dessous 8.8.8.7 est l'adresse IP choisie. \n" +"X-Forwarded-For : 8.8.8.7, 192.168.2.1, 127.0.0.1\n" +"Hôte : 127.0.0.1\n" +"REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST']" + +#: main/conf.py:99 +msgid "Tower License" +msgstr "Licence Tower" + +#: main/conf.py:100 +msgid "" +"The license controls which features and functionality are enabled in Tower. " +"Use /api/v1/config/ to update or change the license." +msgstr "" +"La licence détermine les fonctionnalités et les fonctions qui sont activées " +"dans Tower. Utilisez /api/v1/config/ pour mettre à jour ou modifier la " +"licence." + +#: main/conf.py:110 +msgid "Ansible Modules Allowed for Ad Hoc Jobs" +msgstr "Modules Ansible autorisés pour des tâches ad hoc" + +#: main/conf.py:111 +msgid "List of modules allowed to be used by ad-hoc jobs." +msgstr "Liste des modules que des tâches ad hoc sont autorisées à utiliser." + +#: main/conf.py:112 +#: main/conf.py:121 +#: main/conf.py:130 +#: main/conf.py:139 +#: main/conf.py:148 +#: main/conf.py:158 +#: main/conf.py:168 +#: main/conf.py:178 +#: main/conf.py:187 +#: main/conf.py:199 +#: main/conf.py:211 +#: main/conf.py:223 +msgid "Jobs" +msgstr "Tâches" + +#: main/conf.py:119 +msgid "Enable job isolation" +msgstr "Activer l'isolement des tâches" + +#: main/conf.py:120 +msgid "" +"Isolates an Ansible job from protected parts of the Tower system to prevent " +"exposing sensitive information." +msgstr "" +"Permet d'isoler une tâche Ansible des parties protégées du système Tower " +"pour éviter l'exposition d'informations sensibles." + +#: main/conf.py:128 +msgid "Job isolation execution path" +msgstr "Chemin d'exécution pour l'isolement des tâches" + +#: main/conf.py:129 +msgid "" +"Create temporary working directories for isolated jobs in this location." +msgstr "" +"Créez des répertoires de travail temporaires pour les tâches isolées à cet " +"emplacement." + +#: main/conf.py:137 +msgid "Paths to hide from isolated jobs" +msgstr "Chemins à dissimuler des tâches isolées" + +#: main/conf.py:138 +msgid "Additional paths to hide from isolated processes." +msgstr "Chemins supplémentaires à dissimuler des processus isolés." + +#: main/conf.py:146 +msgid "Paths to expose to isolated jobs" +msgstr "Chemins à exposer aux tâches isolées" + +#: main/conf.py:147 +msgid "" +"Whitelist of paths that would otherwise be hidden to expose to isolated jobs." +"" +msgstr "" +"Liste blanche des chemins qui seraient autrement dissimulés de façon à ne " +"pas être exposés aux tâches isolées." + +#: main/conf.py:156 +msgid "Standard Output Maximum Display Size" +msgstr "Taille d'affichage maximale pour une sortie standard" + +#: main/conf.py:157 +msgid "" +"Maximum Size of Standard Output in bytes to display before requiring the " +"output be downloaded." +msgstr "" +"Taille maximale d'une sortie standard en octets à afficher avant de demander " +"le téléchargement de la sortie." + +#: main/conf.py:166 +msgid "Job Event Standard Output Maximum Display Size" +msgstr "" +"Taille d'affichage maximale pour une sortie standard d'événement de tâche" + +#: main/conf.py:167 +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 "" +"Taille maximale de la sortie standard en octets à afficher pour une seule " +"tâche ou pour un seul événement de commande ad hoc. `stdout` se terminera " +"par `...` quand il sera tronqué." + +#: main/conf.py:176 +msgid "Maximum Scheduled Jobs" +msgstr "Nombre max. de tâches planifiées" + +#: main/conf.py:177 +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 "" +"Nombre maximal du même modèle de tâche qui peut être mis en attente " +"d'exécution lors de son lancement à partir d'un calendrier, avant que " +"d'autres ne soient créés." + +#: main/conf.py:185 +msgid "Ansible Callback Plugins" +msgstr "Plug-ins de rappel Ansible" + +#: main/conf.py:186 +msgid "" +"List of paths to search for extra callback plugins to be used when running " +"jobs." +msgstr "" +"Liste des chemins servant à rechercher d'autres plug-ins de rappel qui " +"serviront lors de l'exécution de tâches." + +#: main/conf.py:196 +msgid "Default Job Timeout" +msgstr "Délai d'attente par défaut des tâches" + +#: main/conf.py:197 +msgid "" +"Maximum time 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 "" +"Délai maximal d'exécution des tâches. Utilisez la valeur 0 pour indiquer " +"qu'aucun délai ne doit être imposé. Un délai d'attente défini sur celui d'un " +"modèle de tâche précis écrasera cette valeur." + +#: main/conf.py:208 +msgid "Default Inventory Update Timeout" +msgstr "Délai d'attente par défaut pour la mise à jour d'inventaire" + +#: main/conf.py:209 +msgid "" +"Maximum time 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 "" +"Délai maximal d'exécution des mises à jour d'inventaire. Utilisez la valeur " +"0 pour indiquer qu'aucun délai ne doit être imposé. Un délai d'attente " +"défini sur celui d'une source d'inventaire précise écrasera cette valeur." + +#: main/conf.py:220 +msgid "Default Project Update Timeout" +msgstr "Délai d'attente par défaut pour la mise à jour de projet" + +#: main/conf.py:221 +msgid "" +"Maximum time 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 "" +"Délai maximal d'exécution des mises à jour de projet. Utilisez la valeur 0 " +"pour indiquer qu'aucun délai ne doit être imposé. Un délai d'attente défini " +"sur celui d'un projet précis écrasera cette valeur." + +#: main/conf.py:231 +msgid "Logging Aggregator Receiving Host" +msgstr "Agrégateur de journalisation - Hôte destinataire" + +#: main/conf.py:232 +msgid "External host maintain a log collector to send logs to" +msgstr "" +"L'hôte externe conserve un collecteur de journaux à qui envoyer des journaux" + +#: main/conf.py:233 +#: main/conf.py:242 +#: main/conf.py:252 +#: main/conf.py:261 +#: main/conf.py:271 +#: main/conf.py:286 +#: main/conf.py:297 +#: main/conf.py:306 +msgid "Logging" +msgstr "Journalisation" + +#: main/conf.py:240 +msgid "Logging Aggregator Receiving Port" +msgstr "Agrégateur de journalisation - Port destinataire" + +#: main/conf.py:241 +msgid "Port that the log collector is listening on" +msgstr "Port sur lequel le collecteur de journaux écoute" + +#: main/conf.py:250 +msgid "Logging Aggregator Type: Logstash, Loggly, Datadog, etc" +msgstr "Type d'agrégateur de journalisation : Logstash, Loggly, Datadog, etc" + +#: main/conf.py:251 +msgid "The type of log aggregator service to format messages for" +msgstr "" +"Type de service d'agrégation de journaux pour lequel mettre en forme les " +"messages" + +#: main/conf.py:259 +msgid "Logging Aggregator Username to Authenticate With" +msgstr "" +"Nom d'utilisateur de l'agrégateur de journalisation avec lequel " +"s'authentifier" + +#: main/conf.py:260 +msgid "Username for Logstash or others (basic auth)" +msgstr "Nom d'utilisateur pour Logstash ou autres (authentification de base)" + +#: main/conf.py:269 +msgid "Logging Aggregator Password to Authenticate With" +msgstr "" +"Mot de passe de l'agrégateur de journalisation avec lequel s'authentifier" + +#: main/conf.py:270 +msgid "Password for Logstash or others (basic auth)" +msgstr "Mot de passe pour Logstash ou autres (authentification de base)" + +#: main/conf.py:278 +msgid "Loggers to send data to the log aggregator from" +msgstr "" +"Journaliseurs à partir duquel envoyer des données à l'agrégateur de journaux" + +#: main/conf.py:279 +msgid "" +"List of loggers that will send HTTP logs to the collector, these can include " +"any or all of: \n" +"activity_stream - logs duplicate to records entered in activity stream\n" +"job_events - callback data from Ansible job events\n" +"system_tracking - data generated from scan jobs\n" +"Sending generic Tower logs must be configured through local_settings." +"pyinstead of this mechanism." +msgstr "" +"Liste des journaliseurs qui enverront des journaux HTTP au collecteur " +"notamment (tous les types ou certains seulement) : \n" +"activity_stream - journaux en double pour les enregistrements entrés dans le " +"flux d'activité\n" +"job_events - données de rappel issues d'événements de tâche Ansible\n" +"system_tracking - données générées par des tâches de scan\n" +"L'envoi de journaux Tower génériques doit être configuré via local_settings." +"py sans l'utilisation de ce mécanisme." + +#: main/conf.py:293 +msgid "" +"Flag denoting to send individual messages for each fact in system tracking" +msgstr "" +"Marqueur indiquant l'envoi de messages distincts pour chaque fait dans le " +"suivi du système" + +#: main/conf.py:294 +msgid "" +"If not set, the data from system tracking will be sent inside of a single " +"dictionary, but if set, separate requests will be sent for each package, " +"service, etc. that is found in the scan." +msgstr "" +"Si aucun n'est défini, les données de suivi du système seront envoyées à " +"l'intérieur d'un seul dictionnaire. Si un marqueur est défini, des demandes " +"distinctes sont envoyées pour chaque paquetage, service, etc., détecté dans " +"le scan." + +#: main/conf.py:304 +msgid "Flag denoting whether to use the external logger system" +msgstr "" +"Marqueur indiquant s'il faut ou non utiliser le système de journalisation " +"externe" + +#: main/conf.py:305 +msgid "" +"If not set, only normal settings data will be used to configure loggers." +msgstr "" +"Si aucun n'est défini, seules les données de paramètres normales seront " +"utilisées pour configurer les journaliseurs." + +#: main/models/activity_stream.py:22 +msgid "Entity Created" +msgstr "Entité créée" + +#: main/models/activity_stream.py:23 +msgid "Entity Updated" +msgstr "Entité mise à jour" + +#: main/models/activity_stream.py:24 +msgid "Entity Deleted" +msgstr "Entité supprimée" + +#: main/models/activity_stream.py:25 +msgid "Entity Associated with another Entity" +msgstr "Entité associée à une autre entité" + +#: main/models/activity_stream.py:26 +msgid "Entity was Disassociated with another Entity" +msgstr "Entité dissociée d'une autre entité" + +#: main/models/ad_hoc_commands.py:96 +msgid "No valid inventory." +msgstr "Aucun inventaire valide." + +#: main/models/ad_hoc_commands.py:103 +#: main/models/jobs.py:163 +msgid "You must provide a machine / SSH credential." +msgstr "Vous devez fournir des informations d'identification machine / SSH." + +#: main/models/ad_hoc_commands.py:114 +#: main/models/ad_hoc_commands.py:122 +msgid "Invalid type for ad hoc command" +msgstr "Type non valide pour la commande ad hoc" + +#: main/models/ad_hoc_commands.py:117 +msgid "Unsupported module for ad hoc commands." +msgstr "Module non pris en charge pour les commandes ad hoc." + +#: main/models/ad_hoc_commands.py:125 +#, python-format +msgid "No argument passed to %s module." +msgstr "Aucun argument transmis au module %s." + +#: main/models/ad_hoc_commands.py:220 +#: main/models/jobs.py:767 +msgid "Host Failed" +msgstr "Échec de l'hôte" + +#: main/models/ad_hoc_commands.py:221 +#: main/models/jobs.py:768 +msgid "Host OK" +msgstr "Hôte OK" + +#: main/models/ad_hoc_commands.py:222 +#: main/models/jobs.py:771 +msgid "Host Unreachable" +msgstr "Hôte inaccessible" + +#: main/models/ad_hoc_commands.py:227 +#: main/models/jobs.py:770 +msgid "Host Skipped" +msgstr "Hôte ignoré" + +#: main/models/ad_hoc_commands.py:237 +#: main/models/jobs.py:798 +msgid "Debug" +msgstr "Déboguer" + +#: main/models/ad_hoc_commands.py:238 +#: main/models/jobs.py:799 +msgid "Verbose" +msgstr "Verbeux" + +#: main/models/ad_hoc_commands.py:239 +#: main/models/jobs.py:800 +msgid "Deprecated" +msgstr "Obsolète" + +#: main/models/ad_hoc_commands.py:240 +#: main/models/jobs.py:801 +msgid "Warning" +msgstr "Avertissement" + +#: main/models/ad_hoc_commands.py:241 +#: main/models/jobs.py:802 +msgid "System Warning" +msgstr "Avertissement système" + +#: main/models/ad_hoc_commands.py:242 +#: main/models/jobs.py:803 +#: main/models/unified_jobs.py:62 +msgid "Error" +msgstr "Erreur" + +#: main/models/base.py:45 +#: main/models/base.py:51 +#: main/models/base.py:56 +msgid "Run" +msgstr "Exécuter" + +#: main/models/base.py:46 +#: main/models/base.py:52 +#: main/models/base.py:57 +msgid "Check" +msgstr "Vérifier" + +#: main/models/base.py:47 +msgid "Scan" +msgstr "Scanner" + +#: main/models/base.py:61 +msgid "Read Inventory" +msgstr "Lire l'inventaire" + +#: main/models/base.py:62 +msgid "Edit Inventory" +msgstr "Modifier l'inventaire" + +#: main/models/base.py:63 +msgid "Administrate Inventory" +msgstr "Administrer l'inventaire" + +#: main/models/base.py:64 +msgid "Deploy To Inventory" +msgstr "Déployer dans l'inventaire" + +#: main/models/base.py:65 +msgid "Deploy To Inventory (Dry Run)" +msgstr "Déployer dans l'inventaire (test uniquement)" + +#: main/models/base.py:66 +msgid "Scan an Inventory" +msgstr "Scanner un inventaire" + +#: main/models/base.py:67 +msgid "Create a Job Template" +msgstr "Créer un modèle de tâche" + +#: main/models/credential.py:33 +msgid "Machine" +msgstr "Machine" + +#: main/models/credential.py:34 +msgid "Network" +msgstr "Réseau" + +#: main/models/credential.py:35 +msgid "Source Control" +msgstr "Contrôle de la source" + +#: main/models/credential.py:36 +msgid "Amazon Web Services" +msgstr "Amazon Web Services" + +#: main/models/credential.py:37 +msgid "Rackspace" +msgstr "Rackspace" + +#: main/models/credential.py:38 +#: main/models/inventory.py:713 +msgid "VMware vCenter" +msgstr "VMware vCenter" + +#: main/models/credential.py:39 +#: main/models/inventory.py:714 +msgid "Red Hat Satellite 6" +msgstr "Red Hat Satellite 6" + +#: main/models/credential.py:40 +#: main/models/inventory.py:715 +msgid "Red Hat CloudForms" +msgstr "Red Hat CloudForms" + +#: main/models/credential.py:41 +#: main/models/inventory.py:710 +msgid "Google Compute Engine" +msgstr "Google Compute Engine" + +#: main/models/credential.py:42 +#: main/models/inventory.py:711 +msgid "Microsoft Azure Classic (deprecated)" +msgstr "Microsoft Azure Classic (obsolète)" + +#: main/models/credential.py:43 +#: main/models/inventory.py:712 +msgid "Microsoft Azure Resource Manager" +msgstr "Microsoft Azure Resource Manager" + +#: main/models/credential.py:44 +#: main/models/inventory.py:716 +msgid "OpenStack" +msgstr "OpenStack" + +#: main/models/credential.py:48 +msgid "None" +msgstr "Aucun" + +#: main/models/credential.py:49 +msgid "Sudo" +msgstr "Sudo" + +#: main/models/credential.py:50 +msgid "Su" +msgstr "Su" + +#: main/models/credential.py:51 +msgid "Pbrun" +msgstr "Pbrun" + +#: main/models/credential.py:52 +msgid "Pfexec" +msgstr "Pfexec" + +#: main/models/credential.py:101 +msgid "Host" +msgstr "Hôte" + +#: main/models/credential.py:102 +msgid "The hostname or IP address to use." +msgstr "Nom d'hôte ou adresse IP à utiliser." + +#: main/models/credential.py:108 +msgid "Username" +msgstr "Nom d'utilisateur" + +#: main/models/credential.py:109 +msgid "Username for this credential." +msgstr "Nom d'utilisateur pour ces informations d'identification." + +#: main/models/credential.py:115 +msgid "Password" +msgstr "Mot de passe" + +#: main/models/credential.py:116 +msgid "" +"Password for this credential (or \"ASK\" to prompt the user for machine " +"credentials)." +msgstr "" +"Mot de passe pour ces informations d'identification (ou \"ASK\" pour " +"demander à l'utilisateur les informations d'identification de la machine)." + +#: main/models/credential.py:123 +msgid "Security Token" +msgstr "Token de sécurité" + +#: main/models/credential.py:124 +msgid "Security Token for this credential" +msgstr "Token de sécurité pour ces informations d'identification" + +#: main/models/credential.py:130 +msgid "Project" +msgstr "Projet" + +#: main/models/credential.py:131 +msgid "The identifier for the project." +msgstr "Identifiant du projet." + +#: main/models/credential.py:137 +msgid "Domain" +msgstr "Domaine" + +#: main/models/credential.py:138 +msgid "The identifier for the domain." +msgstr "Identifiant du domaine." + +#: main/models/credential.py:143 +msgid "SSH private key" +msgstr "Clé privée SSH" + +#: main/models/credential.py:144 +msgid "RSA or DSA private key to be used instead of password." +msgstr "Clé privée RSA ou DSA à utiliser au lieu du mot de passe." + +#: main/models/credential.py:150 +msgid "SSH key unlock" +msgstr "Déverrouillage de la clé SSH" + +#: main/models/credential.py:151 +msgid "" +"Passphrase to unlock SSH private key if encrypted (or \"ASK\" to prompt the " +"user for machine credentials)." +msgstr "" +"Phrase de passe servant à déverrouiller la clé privée SSH si elle est " +"chiffrée (ou \"ASK\" pour demander à l'utilisateur les informations " +"d'identification de la machine)." + +#: main/models/credential.py:159 +msgid "Privilege escalation method." +msgstr "Méthode d'élévation des privilèges." + +#: main/models/credential.py:165 +msgid "Privilege escalation username." +msgstr "Nom d'utilisateur pour l'élévation des privilèges" + +#: main/models/credential.py:171 +msgid "Password for privilege escalation method." +msgstr "Mot de passe pour la méthode d'élévation des privilèges." + +#: main/models/credential.py:177 +msgid "Vault password (or \"ASK\" to prompt the user)." +msgstr "Mot de passe Vault (ou \"ASK\" pour le demander à l'utilisateur)." + +#: main/models/credential.py:181 +msgid "Whether to use the authorize mechanism." +msgstr "Indique s'il faut ou non utiliser le mécanisme d'autorisation." + +#: main/models/credential.py:187 +msgid "Password used by the authorize mechanism." +msgstr "Mot de passe utilisé par le mécanisme d'autorisation." + +#: main/models/credential.py:193 +msgid "Client Id or Application Id for the credential" +msgstr "" +"ID du client ou de l'application pour les informations d'identification" + +#: main/models/credential.py:199 +msgid "Secret Token for this credential" +msgstr "Token secret pour ces informations d'identification" + +#: main/models/credential.py:205 +msgid "Subscription identifier for this credential" +msgstr "ID d'abonnement pour ces informations d'identification" + +#: main/models/credential.py:211 +msgid "Tenant identifier for this credential" +msgstr "ID de tenant pour ces informations d'identification" + +#: main/models/credential.py:281 +msgid "Host required for VMware credential." +msgstr "Hôte requis pour les informations d'identification VMware." + +#: main/models/credential.py:283 +msgid "Host required for OpenStack credential." +msgstr "Hôte requis pour les informations d'identification OpenStack." + +#: main/models/credential.py:292 +msgid "Access key required for AWS credential." +msgstr "Clé d'accès requise pour les informations d'identification AWS." + +#: main/models/credential.py:294 +msgid "Username required for Rackspace credential." +msgstr "" +"Nom d'utilisateur requis pour les informations d'identification Rackspace." + +#: main/models/credential.py:297 +msgid "Username required for VMware credential." +msgstr "" +"Nom d'utilisateur requis pour les informations d'identification VMware." + +#: main/models/credential.py:299 +msgid "Username required for OpenStack credential." +msgstr "" +"Nom d'utilisateur requis pour les informations d'identification OpenStack." + +#: main/models/credential.py:305 +msgid "Secret key required for AWS credential." +msgstr "Clé secrète requise pour les informations d'identification AWS." + +#: main/models/credential.py:307 +msgid "API key required for Rackspace credential." +msgstr "Clé API requise pour les informations d'identification Rackspace." + +#: main/models/credential.py:309 +msgid "Password required for VMware credential." +msgstr "Mot de passe requis pour les informations d'identification VMware." + +#: main/models/credential.py:311 +msgid "Password or API key required for OpenStack credential." +msgstr "" +"Mot de passe ou clé API requis(e) pour les informations d'identification " +"OpenStack." + +#: main/models/credential.py:317 +msgid "Project name required for OpenStack credential." +msgstr "" +"Nom de projet requis pour les informations d'identification OpenStack." + +#: main/models/credential.py:344 +msgid "SSH key unlock must be set when SSH key is encrypted." +msgstr "" +"Le déverrouillage de la clé SSH doit être défini lorsque la clé SSH est " +"chiffrée." + +#: main/models/credential.py:350 +msgid "Credential cannot be assigned to both a user and team." +msgstr "" +"Les informations d'identification ne peuvent pas être attribuées à la fois à " +"un utilisateur et une équipe." + +#: main/models/fact.py:21 +msgid "Host for the facts that the fact scan captured." +msgstr "Hôte pour les faits que le scan de faits a capturés." + +#: main/models/fact.py:26 +msgid "Date and time of the corresponding fact scan gathering time." +msgstr "" +"Date et heure du scan de faits correspondant au moment de la collecte des " +"faits." + +#: main/models/fact.py:29 +msgid "" +"Arbitrary JSON structure of module facts captured at timestamp for a single " +"host." +msgstr "" +"Structure JSON arbitraire des faits de module capturés au moment de " +"l'horodatage pour un seul hôte." + +#: main/models/inventory.py:45 +msgid "inventories" +msgstr "inventaires" + +#: main/models/inventory.py:52 +msgid "Organization containing this inventory." +msgstr "Organisation contenant cet inventaire." + +#: main/models/inventory.py:58 +msgid "Inventory variables in JSON or YAML format." +msgstr "Variables d'inventaire au format JSON ou YAML." + +#: main/models/inventory.py:63 +msgid "Flag indicating whether any hosts in this inventory have failed." +msgstr "Marqueur indiquant si les hôtes de cet inventaire ont échoué." + +#: main/models/inventory.py:68 +msgid "Total number of hosts in this inventory." +msgstr "Nombre total d'hôtes dans cet inventaire." + +#: main/models/inventory.py:73 +msgid "Number of hosts in this inventory with active failures." +msgstr "Nombre d'hôtes dans cet inventaire avec des échecs non résolus." + +#: main/models/inventory.py:78 +msgid "Total number of groups in this inventory." +msgstr "Nombre total de groupes dans cet inventaire." + +#: main/models/inventory.py:83 +msgid "Number of groups in this inventory with active failures." +msgstr "Nombre de groupes dans cet inventaire avec des échecs non résolus." + +#: main/models/inventory.py:88 +msgid "" +"Flag indicating whether this inventory has any external inventory sources." +msgstr "" +"Marqueur indiquant si cet inventaire contient des sources d'inventaire " +"externes." + +#: main/models/inventory.py:93 +msgid "" +"Total number of external inventory sources configured within this inventory." +msgstr "" +"Nombre total de sources d'inventaire externes configurées dans cet " +"inventaire." + +#: main/models/inventory.py:98 +msgid "Number of external inventory sources in this inventory with failures." +msgstr "" +"Nombre total de sources d'inventaire externes en échec dans cet inventaire." + +#: main/models/inventory.py:339 +msgid "Is this host online and available for running jobs?" +msgstr "Cet hôte est-il en ligne et disponible pour exécuter des tâches ?" + +#: main/models/inventory.py:345 +msgid "" +"The value used by the remote inventory source to uniquely identify the host" +msgstr "" +"Valeur utilisée par la source d'inventaire distante pour identifier l'hôte " +"de façon unique" + +#: main/models/inventory.py:350 +msgid "Host variables in JSON or YAML format." +msgstr "Variables d'hôte au format JSON ou YAML." + +#: main/models/inventory.py:372 +msgid "Flag indicating whether the last job failed for this host." +msgstr "Marqueur indiquant si la dernière tâche a échoué pour cet hôte." + +#: main/models/inventory.py:377 +msgid "" +"Flag indicating whether this host was created/updated from any external " +"inventory sources." +msgstr "" +"Marqueur indiquant si cet hôte a été créé/mis à jour à partir de sources " +"d'inventaire externes." + +#: main/models/inventory.py:383 +msgid "Inventory source(s) that created or modified this host." +msgstr "Sources d'inventaire qui ont créé ou modifié cet hôte." + +#: main/models/inventory.py:474 +msgid "Group variables in JSON or YAML format." +msgstr "Variables de groupe au format JSON ou YAML." + +#: main/models/inventory.py:480 +msgid "Hosts associated directly with this group." +msgstr "Hôtes associés directement à ce groupe." + +#: main/models/inventory.py:485 +msgid "Total number of hosts directly or indirectly in this group." +msgstr "" +"Nombre total d'hôtes associés directement ou indirectement à ce groupe." + +#: main/models/inventory.py:490 +msgid "Flag indicating whether this group has any hosts with active failures." +msgstr "" +"Marqueur indiquant si ce groupe possède ou non des hôtes avec des échecs non " +"résolus." + +#: main/models/inventory.py:495 +msgid "Number of hosts in this group with active failures." +msgstr "Nombre d'hôtes dans ce groupe avec des échecs non résolus." + +#: main/models/inventory.py:500 +msgid "Total number of child groups contained within this group." +msgstr "Nombre total de groupes enfants compris dans ce groupe." + +#: main/models/inventory.py:505 +msgid "Number of child groups within this group that have active failures." +msgstr "Nombre de groupes enfants dans ce groupe avec des échecs non résolus." + +#: main/models/inventory.py:510 +msgid "" +"Flag indicating whether this group was created/updated from any external " +"inventory sources." +msgstr "" +"Marqueur indiquant si ce groupe a été créé/mis à jour à partir de sources " +"d'inventaire externes." + +#: main/models/inventory.py:516 +msgid "Inventory source(s) that created or modified this group." +msgstr "Sources d'inventaire qui ont créé ou modifié ce groupe." + +#: main/models/inventory.py:706 +#: main/models/projects.py:42 +#: main/models/unified_jobs.py:386 +msgid "Manual" +msgstr "Manuel" + +#: main/models/inventory.py:707 +msgid "Local File, Directory or Script" +msgstr "Fichier local, répertoire ou script" + +#: main/models/inventory.py:708 +msgid "Rackspace Cloud Servers" +msgstr "Serveurs cloud Rackspace" + +#: main/models/inventory.py:709 +msgid "Amazon EC2" +msgstr "Amazon EC2" + +#: main/models/inventory.py:717 +msgid "Custom Script" +msgstr "Script personnalisé" + +#: main/models/inventory.py:828 +msgid "Inventory source variables in YAML or JSON format." +msgstr "Variables de source d'inventaire au format JSON ou YAML." + +#: main/models/inventory.py:847 +msgid "" +"Comma-separated list of filter expressions (EC2 only). Hosts are imported " +"when ANY of the filters match." +msgstr "" +"Liste d'expressions de filtre séparées par des virgules (EC2 uniquement). " +"Les hôtes sont importés lorsque l'UN des filtres correspondent." + +#: main/models/inventory.py:853 +msgid "Limit groups automatically created from inventory source (EC2 only)." +msgstr "" +"Limiter automatiquement les groupes créés à partir de la source d'inventaire " +"(EC2 uniquement)." + +#: main/models/inventory.py:857 +msgid "Overwrite local groups and hosts from remote inventory source." +msgstr "" +"Écraser les groupes locaux et les hôtes de la source d'inventaire distante." + +#: main/models/inventory.py:861 +msgid "Overwrite local variables from remote inventory source." +msgstr "Écraser les variables locales de la source d'inventaire distante." + +#: main/models/inventory.py:893 +msgid "Availability Zone" +msgstr "Zone de disponibilité" + +#: main/models/inventory.py:894 +msgid "Image ID" +msgstr "ID d'image" + +#: main/models/inventory.py:895 +msgid "Instance ID" +msgstr "ID d'instance" + +#: main/models/inventory.py:896 +msgid "Instance Type" +msgstr "Type d'instance" + +#: main/models/inventory.py:897 +msgid "Key Name" +msgstr "Nom de la clé" + +#: main/models/inventory.py:898 +msgid "Region" +msgstr "Région" + +#: main/models/inventory.py:899 +msgid "Security Group" +msgstr "Groupe de sécurité" + +#: main/models/inventory.py:900 +msgid "Tags" +msgstr "Balises" + +#: main/models/inventory.py:901 +msgid "VPC ID" +msgstr "ID VPC" + +#: main/models/inventory.py:902 +msgid "Tag None" +msgstr "Ne rien baliser" + +#: main/models/inventory.py:973 +#, python-format +msgid "" +"Cloud-based inventory sources (such as %s) require credentials for the " +"matching cloud service." +msgstr "" +"Les sources d'inventaire cloud (telles que% s) requièrent des informations " +"d'identification pour le service cloud correspondant." + +#: main/models/inventory.py:980 +msgid "Credential is required for a cloud source." +msgstr "" +"Les informations d'identification sont requises pour une source cloud." + +#: main/models/inventory.py:1005 +#, python-format +msgid "Invalid %(source)s region%(plural)s: %(region)s" +msgstr "Région %(source)s non valide%(plural)s : %(region)s" + +#: main/models/inventory.py:1031 +#, python-format +msgid "Invalid filter expression%(plural)s: %(filter)s" +msgstr "Expression de filtre non valide %(plural)s : %(filter)s" + +#: main/models/inventory.py:1050 +#, python-format +msgid "Invalid group by choice%(plural)s: %(choice)s" +msgstr "Choix de regroupement non valide %(plural)s : %(choice)s" + +#: main/models/inventory.py:1198 +#, python-format +msgid "" +"Unable to configure this item for cloud sync. It is already managed by %s." +msgstr "" +"Impossible de configurer cet élément pour la synchronisation dans le cloud. " +"Il est déjà géré par %s." + +#: main/models/inventory.py:1293 +msgid "Inventory script contents" +msgstr "Contenus des scripts d'inventaire" + +#: main/models/inventory.py:1298 +msgid "Organization owning this inventory script" +msgstr "Organisation propriétaire de ce script d'inventaire." + +#: main/models/jobs.py:171 +msgid "You must provide a network credential." +msgstr "Vous devez fournir des informations d'identification réseau." + +#: main/models/jobs.py:179 +msgid "" +"Must provide a credential for a cloud provider, such as Amazon Web Services " +"or Rackspace." +msgstr "" +"Entrez les informations d'identification d'un fournisseur de services cloud " +"comme Amazon Web Services ou Rackspace." + +#: main/models/jobs.py:271 +msgid "Job Template must provide 'inventory' or allow prompting for it." +msgstr "" +"Le modèle de tâche doit fournir un inventaire ou permettre d'en demander un." + +#: main/models/jobs.py:275 +msgid "Job Template must provide 'credential' or allow prompting for it." +msgstr "" +"Le modèle de tâche doit fournir des informations d'identification ou " +"permettre d'en demander." + +#: main/models/jobs.py:364 +msgid "Cannot override job_type to or from a scan job." +msgstr "Impossible de remplacer job_type vers ou depuis une tâche de scan." + +#: main/models/jobs.py:367 +msgid "Inventory cannot be changed at runtime for scan jobs." +msgstr "" +"L'inventaire ne peut pas être modifié à l'exécution pour les tâches de scan." + +#: main/models/jobs.py:433 +#: main/models/projects.py:243 +msgid "SCM Revision" +msgstr "Révision SCM" + +#: main/models/jobs.py:434 +msgid "The SCM Revision from the Project used for this job, if available" +msgstr "Révision SCM du projet utilisé pour cette tâche, le cas échéant" + +#: main/models/jobs.py:442 +msgid "" +"The SCM Refresh task used to make sure the playbooks were available for the " +"job run" +msgstr "" +"Activité d'actualisation du SCM qui permet de s'assurer que les playbooks " +"étaient disponibles pour l'exécution de la tâche" + +#: main/models/jobs.py:666 +msgid "job host summaries" +msgstr "récapitulatifs des hôtes pour la tâche" + +#: main/models/jobs.py:769 +msgid "Host Failure" +msgstr "Échec de l'hôte" + +#: main/models/jobs.py:772 +#: main/models/jobs.py:786 +msgid "No Hosts Remaining" +msgstr "Aucun hôte restant" + +#: main/models/jobs.py:773 +msgid "Host Polling" +msgstr "Interrogation de l'hôte" + +#: main/models/jobs.py:774 +msgid "Host Async OK" +msgstr "Désynchronisation des hôtes OK" + +#: main/models/jobs.py:775 +msgid "Host Async Failure" +msgstr "Échec de désynchronisation des hôtes" + +#: main/models/jobs.py:776 +msgid "Item OK" +msgstr "Élément OK" + +#: main/models/jobs.py:777 +msgid "Item Failed" +msgstr "Échec de l'élément" + +#: main/models/jobs.py:778 +msgid "Item Skipped" +msgstr "Élément ignoré" + +#: main/models/jobs.py:779 +msgid "Host Retry" +msgstr "Nouvel essai de l'hôte" + +#: main/models/jobs.py:781 +msgid "File Difference" +msgstr "Écart entre les fichiers" + +#: main/models/jobs.py:782 +msgid "Playbook Started" +msgstr "Playbook démarré" + +#: main/models/jobs.py:783 +msgid "Running Handlers" +msgstr "Descripteurs d'exécution" + +#: main/models/jobs.py:784 +msgid "Including File" +msgstr "Ajout de fichier" + +#: main/models/jobs.py:785 +msgid "No Hosts Matched" +msgstr "Aucun hôte correspondant" + +#: main/models/jobs.py:787 +msgid "Task Started" +msgstr "Tâche démarrée" + +#: main/models/jobs.py:789 +msgid "Variables Prompted" +msgstr "Variables demandées" + +#: main/models/jobs.py:790 +msgid "Gathering Facts" +msgstr "Collecte des faits" + +#: main/models/jobs.py:791 +msgid "internal: on Import for Host" +msgstr "interne : à l'importation pour l'hôte" + +#: main/models/jobs.py:792 +msgid "internal: on Not Import for Host" +msgstr "interne : à la non-importation pour l'hôte" + +#: main/models/jobs.py:793 +msgid "Play Started" +msgstr "Scène démarrée" + +#: main/models/jobs.py:794 +msgid "Playbook Complete" +msgstr "Playbook terminé" + +#: main/models/jobs.py:1240 +msgid "Remove jobs older than a certain number of days" +msgstr "Supprimer les tâches plus anciennes qu'un certain nombre de jours" + +#: main/models/jobs.py:1241 +msgid "Remove activity stream entries older than a certain number of days" +msgstr "" +"Supprimer les entrées du flux d'activité plus anciennes qu'un certain nombre " +"de jours" + +#: main/models/jobs.py:1242 +msgid "Purge and/or reduce the granularity of system tracking data" +msgstr "Purger et/ou réduire la granularité des données de suivi du système" + +#: main/models/label.py:29 +msgid "Organization this label belongs to." +msgstr "Organisation à laquelle appartient ce libellé." + +#: main/models/notifications.py:31 +msgid "Email" +msgstr "Email" + +#: main/models/notifications.py:32 +msgid "Slack" +msgstr "Slack" + +#: main/models/notifications.py:33 +msgid "Twilio" +msgstr "Twilio" + +#: main/models/notifications.py:34 +msgid "Pagerduty" +msgstr "Pagerduty" + +#: main/models/notifications.py:35 +msgid "HipChat" +msgstr "HipChat" + +#: main/models/notifications.py:36 +msgid "Webhook" +msgstr "Webhook" + +#: main/models/notifications.py:37 +msgid "IRC" +msgstr "IRC" + +#: main/models/notifications.py:127 +#: main/models/unified_jobs.py:57 +msgid "Pending" +msgstr "En attente" + +#: main/models/notifications.py:128 +#: main/models/unified_jobs.py:60 +msgid "Successful" +msgstr "Réussi" + +#: main/models/notifications.py:129 +#: main/models/unified_jobs.py:61 +msgid "Failed" +msgstr "Échec" + +#: main/models/organization.py:157 +msgid "Execute Commands on the Inventory" +msgstr "Exécuter des commandes sur l'inventaire" + +#: main/models/organization.py:211 +msgid "Token not invalidated" +msgstr "Token non invalidé" + +#: main/models/organization.py:212 +msgid "Token is expired" +msgstr "Token arrivé à expiration" + +#: main/models/organization.py:213 +msgid "Maximum per-user sessions reached" +msgstr "Nombre maximum de sessions par utilisateur atteint." + +#: main/models/organization.py:216 +msgid "Invalid token" +msgstr "Token non valide" + +#: main/models/organization.py:233 +msgid "Reason the auth token was invalidated." +msgstr "" +"Raison pour laquelle le token d'authentification a été rendu non valide." + +#: main/models/organization.py:272 +msgid "Invalid reason specified" +msgstr "Raison de non validité spécifiée" + +#: main/models/projects.py:43 +msgid "Git" +msgstr "Git" + +#: main/models/projects.py:44 +msgid "Mercurial" +msgstr "Mercurial" + +#: main/models/projects.py:45 +msgid "Subversion" +msgstr "Subversion" + +#: main/models/projects.py:71 +msgid "" +"Local path (relative to PROJECTS_ROOT) containing playbooks and related " +"files for this project." +msgstr "" +"Chemin local (relatif à PROJECTS_ROOT) contenant des playbooks et des " +"fichiers associés pour ce projet." + +#: main/models/projects.py:80 +msgid "SCM Type" +msgstr "Type de SCM" + +#: main/models/projects.py:81 +msgid "Specifies the source control system used to store the project." +msgstr "" +"Spécifie le système de contrôle des sources utilisé pour stocker le projet." + +#: main/models/projects.py:87 +msgid "SCM URL" +msgstr "URL du SCM" + +#: main/models/projects.py:88 +msgid "The location where the project is stored." +msgstr "Emplacement où le projet est stocké." + +#: main/models/projects.py:94 +msgid "SCM Branch" +msgstr "Branche SCM" + +#: main/models/projects.py:95 +msgid "Specific branch, tag or commit to checkout." +msgstr "Branche, balise ou validation spécifique à valider." + +#: main/models/projects.py:99 +msgid "Discard any local changes before syncing the project." +msgstr "Ignorez les modifications locales avant de synchroniser le projet." + +#: main/models/projects.py:103 +msgid "Delete the project before syncing." +msgstr "Supprimez le projet avant la synchronisation." + +#: main/models/projects.py:116 +msgid "The amount of time to run before the task is canceled." +msgstr "Délai écoulé avant que la tâche ne soit annulée." + +#: main/models/projects.py:130 +msgid "Invalid SCM URL." +msgstr "URL du SCM incorrecte." + +#: main/models/projects.py:133 +msgid "SCM URL is required." +msgstr "L'URL du SCM est requise." + +#: main/models/projects.py:142 +msgid "Credential kind must be 'scm'." +msgstr "Le type d'informations d'identification doit être 'scm'." + +#: main/models/projects.py:157 +msgid "Invalid credential." +msgstr "Informations d'identification non valides." + +#: main/models/projects.py:229 +msgid "Update the project when a job is launched that uses the project." +msgstr "Mettez à jour le projet lorsqu'une tâche qui l'utilise est lancée." + +#: main/models/projects.py:234 +msgid "" +"The number of seconds after the last project update ran that a newproject " +"update will be launched as a job dependency." +msgstr "" +"Délai écoulé (en secondes) entre la dernière mise à jour du projet et le " +"lancement d'une nouvelle mise à jour en tant que dépendance de la tâche." + +#: main/models/projects.py:244 +msgid "The last revision fetched by a project update" +msgstr "Dernière révision récupérée par une mise à jour du projet" + +#: main/models/projects.py:251 +msgid "Playbook Files" +msgstr "Fichiers de playbook" + +#: main/models/projects.py:252 +msgid "List of playbooks found in the project" +msgstr "Liste des playbooks trouvés dans le projet" + +#: main/models/rbac.py:122 +msgid "roles" +msgstr "rôles" + +#: main/models/rbac.py:438 +msgid "role_ancestors" +msgstr "role_ancestors" + +#: main/models/schedules.py:69 +msgid "Enables processing of this schedule by Tower." +msgstr "Active le traitement de ce calendrier par Tower." + +#: main/models/schedules.py:75 +msgid "The first occurrence of the schedule occurs on or after this time." +msgstr "" +"La première occurrence du calendrier se produit à ce moment précis ou " +"ultérieurement." + +#: main/models/schedules.py:81 +msgid "" +"The last occurrence of the schedule occurs before this time, aftewards the " +"schedule expires." +msgstr "" +"La dernière occurrence du calendrier se produit avant ce moment précis. " +"Passé ce délai, le calendrier arrive à expiration." + +#: main/models/schedules.py:85 +msgid "A value representing the schedules iCal recurrence rule." +msgstr "Valeur représentant la règle de récurrence iCal des calendriers." + +#: main/models/schedules.py:91 +msgid "The next time that the scheduled action will run." +msgstr "La prochaine fois que l'action planifiée s'exécutera." + +#: main/models/unified_jobs.py:56 +msgid "New" +msgstr "Nouveau" + +#: main/models/unified_jobs.py:58 +msgid "Waiting" +msgstr "En attente" + +#: main/models/unified_jobs.py:59 +msgid "Running" +msgstr "En cours d'exécution" + +#: main/models/unified_jobs.py:63 +msgid "Canceled" +msgstr "Annulé" + +#: main/models/unified_jobs.py:67 +msgid "Never Updated" +msgstr "Jamais mis à jour" + +#: main/models/unified_jobs.py:71 +#: ui/templates/ui/index.html:85 +#: ui/templates/ui/index.html.py:104 +msgid "OK" +msgstr "OK" + +#: main/models/unified_jobs.py:72 +msgid "Missing" +msgstr "Manquant" + +#: main/models/unified_jobs.py:76 +msgid "No External Source" +msgstr "Aucune source externe" + +#: main/models/unified_jobs.py:83 +msgid "Updating" +msgstr "Mise à jour en cours" + +#: main/models/unified_jobs.py:387 +msgid "Relaunch" +msgstr "Relancer" + +#: main/models/unified_jobs.py:388 +msgid "Callback" +msgstr "Rappeler" + +#: main/models/unified_jobs.py:389 +msgid "Scheduled" +msgstr "Planifié" + +#: main/models/unified_jobs.py:390 +msgid "Dependency" +msgstr "Dépendance" + +#: main/models/unified_jobs.py:391 +msgid "Workflow" +msgstr "Workflow" + +#: main/models/unified_jobs.py:437 +msgid "The Tower node the job executed on." +msgstr "Nœud Tower sur lequel la tâche s'est exécutée." + +#: main/models/unified_jobs.py:463 +msgid "The date and time the job was queued for starting." +msgstr "" +"Date et heure auxquelles la tâche a été mise en file d'attente pour le " +"démarrage." + +#: main/models/unified_jobs.py:469 +msgid "The date and time the job finished execution." +msgstr "Date et heure de fin d'exécution de la tâche." + +#: main/models/unified_jobs.py:475 +msgid "Elapsed time in seconds that the job ran." +msgstr "Délai écoulé (en secondes) pendant lequel la tâche s'est exécutée." + +#: main/models/unified_jobs.py:497 +msgid "" +"A status field to indicate the state of the job if it wasn't able to run and " +"capture stdout" +msgstr "" +"Champ d'état indiquant l'état de la tâche si elle n'a pas pu s'exécuter et " +"capturer stdout" + +#: main/notifications/base.py:17 +#: main/notifications/email_backend.py:28 +msgid "{} #{} had status {} on Ansible Tower, view details at {}\n" +"\n" +msgstr "{} #{} était à l'état {} sur Ansible Tower, voir les détails sur {}\n" +"\n" + +#: main/notifications/hipchat_backend.py:46 +msgid "Error sending messages: {}" +msgstr "Erreur lors de l'envoi de messages : {}" + +#: main/notifications/hipchat_backend.py:48 +msgid "Error sending message to hipchat: {}" +msgstr "Erreur lors de l'envoi d'un message à hipchat : {}" + +#: main/notifications/irc_backend.py:54 +msgid "Exception connecting to irc server: {}" +msgstr "Exception lors de la connexion au serveur irc : {}" + +#: main/notifications/pagerduty_backend.py:39 +msgid "Exception connecting to PagerDuty: {}" +msgstr "Exception lors de la connexion à PagerDuty : {}" + +#: main/notifications/pagerduty_backend.py:48 +#: main/notifications/slack_backend.py:52 +#: main/notifications/twilio_backend.py:46 +msgid "Exception sending messages: {}" +msgstr "Exception lors de l'envoi de messages : {}" + +#: main/notifications/twilio_backend.py:36 +msgid "Exception connecting to Twilio: {}" +msgstr "Exception lors de la connexion à Twilio : {}" + +#: main/notifications/webhook_backend.py:38 +#: main/notifications/webhook_backend.py:40 +msgid "Error sending notification webhook: {}" +msgstr "Erreur lors de l'envoi d'un webhook de notification : {}" + +#: main/tasks.py:139 +msgid "Ansible Tower host usage over 90%" +msgstr "Utilisation d'hôtes Ansible Tower supérieure à 90 %" + +#: main/tasks.py:144 +msgid "Ansible Tower license will expire soon" +msgstr "La licence Ansible Tower expirera bientôt" + +#: main/tasks.py:197 +msgid "status_str must be either succeeded or failed" +msgstr "status_str doit être une réussite ou un échec" + +#: main/utils/common.py:88 +#, python-format +msgid "Unable to convert \"%s\" to boolean" +msgstr "Impossible de convertir \"% s\" en booléen" + +#: main/utils/common.py:242 +#, python-format +msgid "Unsupported SCM type \"%s\"" +msgstr "Type de SCM \"%s\" non pris en charge" + +#: main/utils/common.py:249 +#: main/utils/common.py:261 +#: main/utils/common.py:280 +#, python-format +msgid "Invalid %s URL" +msgstr "URL %s non valide." + +#: main/utils/common.py:251 +#: main/utils/common.py:289 +#, python-format +msgid "Unsupported %s URL" +msgstr "URL %s non prise en charge" + +#: main/utils/common.py:291 +#, python-format +msgid "Unsupported host \"%s\" for file:// URL" +msgstr "Hôte \"%s\" non pris en charge pour le fichier ://URL" + +#: main/utils/common.py:293 +#, python-format +msgid "Host is required for %s URL" +msgstr "L'hôte est requis pour l'URL %s" + +#: main/utils/common.py:311 +#, python-format +msgid "Username must be \"git\" for SSH access to %s." +msgstr "Le nom d'utilisateur doit être \"git\" pour l'accès SSH à %s." + +#: main/utils/common.py:317 +#, python-format +msgid "Username must be \"hg\" for SSH access to %s." +msgstr "Le nom d'utilisateur doit être \"hg\" pour l'accès SSH à %s." + +#: main/validators.py:60 +#, python-format +msgid "Invalid certificate or key: %r..." +msgstr "Certificat ou clé non valide : %r..." + +#: main/validators.py:74 +#, python-format +msgid "Invalid private key: unsupported type \"%s\"" +msgstr "Clé privée non valide : type \"%s\" non pris en charge" + +#: main/validators.py:78 +#, python-format +msgid "Unsupported PEM object type: \"%s\"" +msgstr "Type d'objet PEM non pris en charge : \"%s\"" + +#: main/validators.py:103 +msgid "Invalid base64-encoded data" +msgstr "Données codées en base64 non valides" + +#: main/validators.py:122 +msgid "Exactly one private key is required." +msgstr "Une clé privée uniquement est nécessaire." + +#: main/validators.py:124 +msgid "At least one private key is required." +msgstr "Une clé privée au moins est nécessaire." + +#: main/validators.py:126 +#, python-format +msgid "" +"At least %(min_keys)d private keys are required, only %(key_count)d provided." +"" +msgstr "" +"%(min_keys)d clés privées au moins sont requises, mais %(key_count)d " +"uniquement ont été fournies." + +#: main/validators.py:129 +#, python-format +msgid "Only one private key is allowed, %(key_count)d provided." +msgstr "Une seule clé privée est autorisée, %(key_count)d ont été fournies." + +#: main/validators.py:131 +#, python-format +msgid "" +"No more than %(max_keys)d private keys are allowed, %(key_count)d provided." +msgstr "" +"Pas plus de %(max_keys)d clés privées sont autorisées, %(key_count)d ont été " +"fournies." + +#: main/validators.py:136 +msgid "Exactly one certificate is required." +msgstr "Un certificat uniquement est nécessaire." + +#: main/validators.py:138 +msgid "At least one certificate is required." +msgstr "Un certificat au moins est nécessaire." + +#: main/validators.py:140 +#, python-format +msgid "" +"At least %(min_certs)d certificates are required, only %(cert_count)d " +"provided." +msgstr "" +"%(min_certs)d certificats au moins sont requis, mais %(cert_count)d " +"uniquement ont été fournis." + +#: main/validators.py:143 +#, python-format +msgid "Only one certificate is allowed, %(cert_count)d provided." +msgstr "Un seul certificat est autorisé, %(cert_count)d ont été fournis." + +#: main/validators.py:145 +#, python-format +msgid "" +"No more than %(max_certs)d certificates are allowed, %(cert_count)d provided." +"" +msgstr "" +"Pas plus de %(max_certs)d certificats sont autorisés, %(cert_count)d ont été " +"fournis." + +#: main/views.py:20 +msgid "API Error" +msgstr "Erreur API" + +#: main/views.py:49 +msgid "Bad Request" +msgstr "Requête incorrecte" + +#: main/views.py:50 +msgid "The request could not be understood by the server." +msgstr "La requête n'a pas pu être comprise par le serveur." + +#: main/views.py:57 +msgid "Forbidden" +msgstr "Interdiction" + +#: main/views.py:58 +msgid "You don't have permission to access the requested resource." +msgstr "Vous n'êtes pas autorisé à accéder à la ressource demandée." + +#: main/views.py:65 +msgid "Not Found" +msgstr "Introuvable" + +#: main/views.py:66 +msgid "The requested resource could not be found." +msgstr "Impossible de trouver la ressource demandée." + +#: main/views.py:73 +msgid "Server Error" +msgstr "Erreur serveur" + +#: main/views.py:74 +msgid "A server error has occurred." +msgstr "Une erreur serveur s'est produite." + +#: settings/defaults.py:593 +msgid "Chicago" +msgstr "Chicago" + +#: settings/defaults.py:594 +msgid "Dallas/Ft. Worth" +msgstr "Dallas/Ft. Worth" + +#: settings/defaults.py:595 +msgid "Northern Virginia" +msgstr "Virginie du Nord" + +#: settings/defaults.py:596 +msgid "London" +msgstr "Londres" + +#: settings/defaults.py:597 +msgid "Sydney" +msgstr "Sydney" + +#: settings/defaults.py:598 +msgid "Hong Kong" +msgstr "Hong Kong" + +#: settings/defaults.py:625 +msgid "US East (Northern Virginia)" +msgstr "Est des États-Unis (Virginie du Nord)" + +#: settings/defaults.py:626 +msgid "US East (Ohio)" +msgstr "Est des États-Unis (Ohio)" + +#: settings/defaults.py:627 +msgid "US West (Oregon)" +msgstr "Ouest des États-Unis (Oregon)" + +#: settings/defaults.py:628 +msgid "US West (Northern California)" +msgstr "Ouest des États-Unis (Nord de la Californie)" + +#: settings/defaults.py:629 +msgid "EU (Frankfurt)" +msgstr "UE (Francfort)" + +#: settings/defaults.py:630 +msgid "EU (Ireland)" +msgstr "UE (Irlande)" + +#: settings/defaults.py:631 +msgid "Asia Pacific (Singapore)" +msgstr "Asie-Pacifique (Singapour)" + +#: settings/defaults.py:632 +msgid "Asia Pacific (Sydney)" +msgstr "Asie-Pacifique (Sydney)" + +#: settings/defaults.py:633 +msgid "Asia Pacific (Tokyo)" +msgstr "Asie-Pacifique (Tokyo)" + +#: settings/defaults.py:634 +msgid "Asia Pacific (Seoul)" +msgstr "Asie-Pacifique (Séoul)" + +#: settings/defaults.py:635 +msgid "Asia Pacific (Mumbai)" +msgstr "Asie-Pacifique (Mumbai)" + +#: settings/defaults.py:636 +msgid "South America (Sao Paulo)" +msgstr "Amérique du Sud (Sao Paulo)" + +#: settings/defaults.py:637 +msgid "US West (GovCloud)" +msgstr "Ouest des États-Unis (GovCloud)" + +#: settings/defaults.py:638 +msgid "China (Beijing)" +msgstr "Chine (Pékin)" + +#: settings/defaults.py:687 +msgid "US East (B)" +msgstr "Est des États-Unis (B)" + +#: settings/defaults.py:688 +msgid "US East (C)" +msgstr "Est des États-Unis (C)" + +#: settings/defaults.py:689 +msgid "US East (D)" +msgstr "Est des États-Unis (D)" + +#: settings/defaults.py:690 +msgid "US Central (A)" +msgstr "Centre des États-Unis (A)" + +#: settings/defaults.py:691 +msgid "US Central (B)" +msgstr "Centre des États-Unis (B)" + +#: settings/defaults.py:692 +msgid "US Central (C)" +msgstr "Centre des États-Unis (C)" + +#: settings/defaults.py:693 +msgid "US Central (F)" +msgstr "Centre des États-Unis (F)" + +#: settings/defaults.py:694 +msgid "Europe West (B)" +msgstr "Europe de l'Ouest (B)" + +#: settings/defaults.py:695 +msgid "Europe West (C)" +msgstr "Europe de l'Ouest (C)" + +#: settings/defaults.py:696 +msgid "Europe West (D)" +msgstr "Europe de l'Ouest (D)" + +#: settings/defaults.py:697 +msgid "Asia East (A)" +msgstr "Asie de l'Est (A)" + +#: settings/defaults.py:698 +msgid "Asia East (B)" +msgstr "Asie de l'Est (B)" + +#: settings/defaults.py:699 +msgid "Asia East (C)" +msgstr "Asie de l'Est (C)" + +#: settings/defaults.py:723 +msgid "US Central" +msgstr "Centre des États-Unis" + +#: settings/defaults.py:724 +msgid "US East" +msgstr "Est des États-Unis" + +#: settings/defaults.py:725 +msgid "US East 2" +msgstr "Est des États-Unis 2" + +#: settings/defaults.py:726 +msgid "US North Central" +msgstr "Centre-Nord des États-Unis" + +#: settings/defaults.py:727 +msgid "US South Central" +msgstr "Centre-Sud des États-Unis" + +#: settings/defaults.py:728 +msgid "US West" +msgstr "Ouest des États-Unis" + +#: settings/defaults.py:729 +msgid "Europe North" +msgstr "Europe du Nord" + +#: settings/defaults.py:730 +msgid "Europe West" +msgstr "Europe de l'Ouest" + +#: settings/defaults.py:731 +msgid "Asia Pacific East" +msgstr "Asie-Pacifique Est" + +#: settings/defaults.py:732 +msgid "Asia Pacific Southeast" +msgstr "Asie-Pacifique Sud-Est" + +#: settings/defaults.py:733 +msgid "Japan East" +msgstr "Est du Japon" + +#: settings/defaults.py:734 +msgid "Japan West" +msgstr "Ouest du Japon" + +#: settings/defaults.py:735 +msgid "Brazil South" +msgstr "Sud du Brésil" + +#: sso/apps.py:9 +msgid "Single Sign-On" +msgstr "Single Sign-On" + +#: sso/conf.py:27 +msgid "" +"Mapping to organization admins/users from social auth accounts. This setting\n" +"controls which users are placed into which Tower organizations based on\n" +"their username and email address. Dictionary keys are organization names.\n" +"organizations will be created if not present if the license allows for\n" +"multiple organizations, otherwise the single default organization is used\n" +"regardless of the key. Values are dictionaries defining the options for\n" +"each organization's membership. For each organization it is possible to\n" +"specify which users are automatically users of the organization and also\n" +"which users can administer the organization. \n" +"\n" +"- admins: None, True/False, string or list of strings.\n" +" If None, organization admins will not be updated.\n" +" If True, all users using social auth will automatically be added as admins\n" +" of the organization.\n" +" If False, no social auth users will be automatically added as admins of\n" +" the organization.\n" +" If a string or list of strings, specifies the usernames and emails for\n" +" users who will be added to the organization. Strings in the format\n" +" \"//\" will be interpreted as JavaScript regular " +"expressions and\n" +" may also be used instead of string literals; only \"i\" and \"m\" are " +"supported\n" +" for flags.\n" +"- remove_admins: True/False. Defaults to True.\n" +" If True, a user who does not match will be removed from the organization's\n" +" administrative list.\n" +"- users: None, True/False, string or list of strings. Same rules apply as " +"for\n" +" admins.\n" +"- remove_users: True/False. Defaults to True. Same rules as apply for \n" +" remove_admins." +msgstr "" +"Mappage avec des administrateurs/utilisateurs d'organisation appartenant à " +"des comptes d'authentification sociale. Ce paramètre\n" +"contrôle les utilisateurs qui sont placés dans les organisations Tower en " +"fonction de\n" +"leur nom d'utilisateur et adresse électronique. Les clés de dictionnaire " +"sont des noms d'organisation.\n" +"Des organisations seront créées si elles ne sont pas présentes dans le cas " +"où la licence autoriserait\n" +"plusieurs organisations, sinon l'organisation par défaut est utilisée\n" +"indépendamment de la clé. Les valeurs sont des dictionnaires définissant les " +"options\n" +"d'appartenance de chaque organisation. Pour chaque organisation, il est " +"possible de\n" +"préciser les utilisateurs qui sont automatiquement utilisateurs de " +"l'organisation et\n" +"ceux qui peuvent administrer l'organisation. \n" +"\n" +"- admins : None, True/False, chaîne ou liste de chaînes.\n" +" Si défini sur None, les administrateurs de l'organisation ne sont pas mis à " +"jour.\n" +" Si défini sur True, tous les utilisateurs se servant de l'authentification " +"sociale sont automatiquement ajoutés en tant qu'administrateurs\n" +" de l'organisation.\n" +" Si défini sur False, aucun utilisateur d'authentification sociale n'est " +"automatiquement ajouté en tant qu'administrateur de\n" +" l'organisation.\n" +" Si une chaîne ou une liste de chaînes est entrée, elle spécifie les noms " +"d'utilisateur et les adresses électroniques des\n" +" utilisateurs qui seront ajoutés à l'organisation. Les chaînes au format\n" +" \"//\" sont interprétées comme des expressions JavaScript " +"normales et\n" +" peuvent également être utilisées à la place de littéraux de chaîne ; seuls " +"\"i\" et \"m\" sont pris en charge\n" +" pour les marqueurs.\n" +"- remove_admins : True/False. Par défaut défini sur True.\n" +" Si défini sur True, l'utilisateur qui ne correspond pas est supprimé de la " +"liste administrative\n" +" de l'organisation.\n" +"- users : None, True/False, chaîne ou liste de chaînes. Les mêmes règles " +"s'appliquent que pour\n" +" admins.\n" +"- remove_users : True/False. Par défaut défini sur True. Les mêmes règles " +"s'appliquent que pour \n" +" remove_admins." + +#: sso/conf.py:76 +msgid "" +"Mapping of team members (users) from social auth accounts. Keys are team\n" +"names (will be created if not present). Values are dictionaries of options\n" +"for each team's membership, where each can contain the following parameters:\n" +"\n" +"- organization: string. The name of the organization to which the team\n" +" belongs. The team will be created if the combination of organization and\n" +" team name does not exist. The organization will first be created if it\n" +" does not exist. If the license does not allow for multiple organizations,\n" +" the team will always be assigned to the single default organization.\n" +"- users: None, True/False, string or list of strings.\n" +" If None, team members will not be updated.\n" +" If True/False, all social auth users will be added/removed as team\n" +" members.\n" +" If a string or list of strings, specifies expressions used to match users.\n" +" User will be added as a team member if the username or email matches.\n" +" Strings in the format \"//\" will be interpreted as " +"JavaScript\n" +" regular expressions and may also be used instead of string literals; only " +"\"i\"\n" +" and \"m\" are supported for flags.\n" +"- remove: True/False. Defaults to True. If True, a user who does not match\n" +" the rules above will be removed from the team." +msgstr "" +"Mappage des membres d'équipe (utilisateurs) de compte d'authentification " +"sociale. Les clés sont des \n" +"noms d'équipe (seront créés s'ils ne sont pas présents). Les valeurs sont " +"des dictionnaires d'options\n" +"d'appartenance à chaque équipe, où chacune peut contenir les paramètres " +"suivants :\n" +"\n" +"-organization : chaîne. Nom de l'organisation à laquelle l'équipe\n" +" appartient. Une équipe est créée si la combinaison nom de l'organisation/" +"nom de \n" +"l'équipe n'existe pas. L'organisation sera d'abord créée \n" +"si elle n'existe pas. Si la licence n'autorise pas plusieurs organisations, \n" +"l'équipe est toujours attribuée à l'organisation par défaut. \n" +"- users : None, True/False, chaîne ou liste de chaînes.\n" +" Si défini sur None, les membres de l'équipe ne sont pas mis à jour.\n" +" Si défini sur True/False, tous les utilisateurs d'authentification sociale " +"sont ajoutés/supprimés en tant que membres\n" +" d'équipe.\n" +" Si une chaîne ou une liste de chaînes est entrée, elle spécifie les " +"expressions utilisées pour comparer les utilisateurs. \n" +"L'utilisateur est ajouté en tant que membre d'équipe si son nom " +"d'utilisateur ou son adresse électronique correspond.\n" +" Les chaînes au format \"//\" sont interprétées comme des " +"expressions JavaScript\n" +" normales et peuvent également être utilisées à la place de littéraux de " +"chaîne ; Seuls \"i\"\n" +" et \"m\" sont pris en charge pour les marqueurs.\n" +"- remove : True/False. Par défaut défini sur True. Si défini sur True, tout " +"utilisateur qui ne correspond\n" +" pas aux règles ci-dessus est supprimé de l'équipe." + +#: sso/conf.py:119 +msgid "Authentication Backends" +msgstr "Backends d'authentification" + +#: sso/conf.py:120 +msgid "" +"List of authentication backends that are enabled based on license features " +"and other authentication settings." +msgstr "" +"Liste des backends d'authentification activés en fonction des " +"caractéristiques des licences et d'autres paramètres d'authentification." + +#: sso/conf.py:133 +msgid "Social Auth Organization Map" +msgstr "Authentification sociale - Mappage des organisations" + +#: sso/conf.py:145 +msgid "Social Auth Team Map" +msgstr "Authentification sociale - Mappage des équipes" + +#: sso/conf.py:157 +msgid "Social Auth User Fields" +msgstr "Authentification sociale - Champs d'utilisateurs" + +#: sso/conf.py:158 +msgid "" +"When set to an empty list `[]`, this setting prevents new user accounts from " +"being created. Only users who have previously logged in using social auth or " +"have a user account with a matching email address will be able to login." +msgstr "" +"Lorsqu'il est défini sur une liste vide `[]`, ce paramètre empêche la " +"création de nouveaux comptes d'utilisateur. Seuls les utilisateurs ayant " +"déjà ouvert une session au moyen de l'authentification sociale ou disposant " +"d'un compte utilisateur avec une adresse électronique correspondante " +"pourront se connecter." + +#: sso/conf.py:176 +msgid "LDAP Server URI" +msgstr "URI du serveur LDAP" + +#: sso/conf.py:177 +msgid "" +"URI to connect to LDAP server, such as \"ldap://ldap.example.com:389\" (non-" +"SSL) or \"ldaps://ldap.example.com:636\" (SSL). Multiple LDAP servers may be " +"specified by separating with spaces or commas. LDAP authentication is " +"disabled if this parameter is empty." +msgstr "" +"URI de connexion au serveur LDAP, tel que \"ldap://ldap.exemple.com:389\" " +"(non SSL) ou \"ldaps://ldap.exemple.com:636\" (SSL). Plusieurs serveurs LDAP " +"peuvent être définis en les séparant par des espaces ou des virgules. " +"L'authentification LDAP est désactivée si ce paramètre est vide." + +#: sso/conf.py:181 +#: sso/conf.py:199 +#: sso/conf.py:211 +#: sso/conf.py:223 +#: sso/conf.py:239 +#: sso/conf.py:258 +#: sso/conf.py:279 +#: sso/conf.py:295 +#: sso/conf.py:314 +#: sso/conf.py:331 +#: sso/conf.py:347 +#: sso/conf.py:362 +#: sso/conf.py:379 +#: sso/conf.py:417 +#: sso/conf.py:458 +msgid "LDAP" +msgstr "LDAP" + +#: sso/conf.py:193 +msgid "LDAP Bind DN" +msgstr "ND de la liaison LDAP" + +#: sso/conf.py:194 +msgid "" +"DN (Distinguished Name) of user to bind for all search queries. Normally in " +"the format \"CN=Some User,OU=Users,DC=example,DC=com\" but may also be " +"specified as \"DOMAIN\\username\" for Active Directory. This is the system " +"user account we will use to login to query LDAP for other user information." +msgstr "" +"ND (nom distinctif) de l'utilisateur à lier pour toutes les requêtes de " +"recherche. Normalement, au format \"CN = Certains utilisateurs, OU = " +"Utilisateurs, DC = exemple, DC = com\" mais peut aussi être entré au format " +"\"DOMAINE\\nom d'utilisateur\" pour Active Directory. Il s'agit du compte " +"utilisateur système que nous utiliserons pour nous connecter afin " +"d'interroger LDAP et obtenir d'autres informations utilisateur." + +#: sso/conf.py:209 +msgid "LDAP Bind Password" +msgstr "Mot de passe de la liaison LDAP" + +#: sso/conf.py:210 +msgid "Password used to bind LDAP user account." +msgstr "Mot de passe utilisé pour lier le compte utilisateur LDAP." + +#: sso/conf.py:221 +msgid "LDAP Start TLS" +msgstr "LDAP - Lancer TLS" + +#: sso/conf.py:222 +msgid "Whether to enable TLS when the LDAP connection is not using SSL." +msgstr "Pour activer ou non TLS lorsque la connexion LDAP n'utilise pas SSL." + +#: sso/conf.py:232 +msgid "LDAP Connection Options" +msgstr "Options de connexion à LDAP" + +#: sso/conf.py:233 +msgid "" +"Additional options to set for the LDAP connection. LDAP referrals are " +"disabled by default (to prevent certain LDAP queries from hanging with AD). " +"Option names should be strings (e.g. \"OPT_REFERRALS\"). Refer to https://" +"www.python-ldap.org/doc/html/ldap.html#options for possible options and " +"values that can be set." +msgstr "" +"Options supplémentaires à définir pour la connexion LDAP. Les références " +"LDAP sont désactivées par défaut (pour empêcher certaines requêtes LDAP de " +"se bloquer avec AD). Les noms d'options doivent être des chaînes (par " +"exemple \"OPT_REFERRALS\"). Reportez-vous à https://www.python-ldap.org/doc/" +"html/ldap.html#options afin de connaître les options possibles et les " +"valeurs que vous pouvez définir." + +#: sso/conf.py:251 +msgid "LDAP User Search" +msgstr "Recherche d'utilisateurs LDAP" + +#: sso/conf.py:252 +msgid "" +"LDAP search query to find users. Any user that matches the given pattern " +"will be able to login to Tower. The user should also be mapped into an " +"Tower organization (as defined in the AUTH_LDAP_ORGANIZATION_MAP setting). " +"If multiple search queries need to be supported use of \"LDAPUnion\" is " +"possible. See python-ldap documentation as linked at the top of this section." +"" +msgstr "" +"Requête de recherche LDAP servant à retrouver des utilisateurs. Tout " +"utilisateur qui correspond au modèle donné pourra se connecter à Tower. " +"L'utilisateur doit également être mappé dans une organisation Tower (tel que " +"défini dans le paramètre AUTH_LDAP_ORGANIZATION_MAP). Si plusieurs requêtes " +"de recherche doivent être prises en charge, l'utilisation de \"LDAPUnion\" " +"est possible. Se reporter à la documentation sur python-ldap en suivant le " +"lien indiqué en haut de cette section." + +#: sso/conf.py:273 +msgid "LDAP User DN Template" +msgstr "Modèle de ND pour les utilisateurs LDAP" + +#: sso/conf.py:274 +msgid "" +"Alternative to user search, if user DNs are all of the same format. This " +"approach will be more efficient for user lookups than searching if it is " +"usable in your organizational environment. If this setting has a value it " +"will be used instead of AUTH_LDAP_USER_SEARCH." +msgstr "" +"Autre méthode de recherche d'utilisateurs, si les ND d'utilisateur se " +"présentent tous au même format. Cette approche est plus efficace qu'une " +"recherche d'utilisateurs si vous pouvez l'utiliser dans votre environnement " +"organisationnel. Si ce paramètre est défini, sa valeur sera utilisée à la " +"place de AUTH_LDAP_USER_SEARCH." + +#: sso/conf.py:289 +msgid "LDAP User Attribute Map" +msgstr "Mappe des attributs d'utilisateurs LDAP" + +#: sso/conf.py:290 +msgid "" +"Mapping of LDAP user schema to Tower API user attributes (key is user " +"attribute name, value is LDAP attribute name). The default setting is valid " +"for ActiveDirectory but users with other LDAP configurations may need to " +"change the values (not the keys) of the dictionary/hash-table." +msgstr "" +"Mappage du schéma utilisateur LDAP avec les attributs utilisateur d'API " +"Tower (la clé est le nom de l'attribut utilisateur, la valeur est le nom de " +"l'attribut LDAP). Le paramètre par défaut est valide pour ActiveDirectory, " +"mais les utilisateurs ayant d'autres configurations LDAP peuvent être amenés " +"à modifier les valeurs (et non les clés) du dictionnaire/de la table de " +"hachage." + +#: sso/conf.py:309 +msgid "LDAP Group Search" +msgstr "Recherche de groupes LDAP" + +#: sso/conf.py:310 +msgid "" +"Users in Tower are mapped to organizations based on their membership in LDAP " +"groups. This setting defines the LDAP search query to find groups. Note that " +"this, unlike the user search above, does not support LDAPSearchUnion." +msgstr "" +"Les utilisateurs de Tower sont mappés à des organisations en fonction de " +"leur appartenance à des groupes LDAP. Ce paramètre définit la requête de " +"recherche LDAP servant à rechercher des groupes. Notez que cette méthode, " +"contrairement à la recherche d'utilisateurs LDAP, ne prend pas en charge " +"LDAPSearchUnion." + +#: sso/conf.py:327 +msgid "LDAP Group Type" +msgstr "Type de groupe LDAP" + +#: sso/conf.py:328 +msgid "" +"The group type may need to be changed based on the type of the LDAP server. " +"Values are listed at: http://pythonhosted.org/django-auth-ldap/groups." +"html#types-of-groups" +msgstr "" +"Il convient parfois de modifier le type de groupe en fonction du type de " +"serveur LDAP. Les valeurs sont répertoriées à l'adresse suivante : http://" +"pythonhosted.org/django-auth-ldap/groups.html#types-of-groups" + +#: sso/conf.py:342 +msgid "LDAP Require Group" +msgstr "Groupe LDAP obligatoire" + +#: sso/conf.py:343 +msgid "" +"Group DN required to login. If specified, user must be a member of this " +"group to login via LDAP. If not set, everyone in LDAP that matches the user " +"search will be able to login via Tower. Only one require group is supported." +msgstr "" +"Le NDD du groupe d'utilisateurs qui doit se connecter. S'il est spécifié, " +"l'utilisateur doit être membre de ce groupe pour pouvoir se connecter via " +"LDAP. S'il n'est pas défini, tout utilisateur LDAP qui correspond à la " +"recherche d'utilisateurs pourra se connecter via Tower. Un seul groupe est " +"pris en charge." + +#: sso/conf.py:358 +msgid "LDAP Deny Group" +msgstr "Groupe LDAP refusé" + +#: sso/conf.py:359 +msgid "" +"Group DN denied from login. If specified, user will not be allowed to login " +"if a member of this group. Only one deny group is supported." +msgstr "" +"NDD du groupe dont la connexion est refusée. S'il est spécifié, " +"l'utilisateur n'est pas autorisé à se connecter s'il est membre de ce groupe." +" Un seul groupe refusé est pris en charge." + +#: sso/conf.py:372 +msgid "LDAP User Flags By Group" +msgstr "Marqueurs d'utilisateur LDAP par groupe" + +#: sso/conf.py:373 +msgid "" +"User profile flags updated from group membership (key is user attribute " +"name, value is group DN). These are boolean fields that are matched based " +"on whether the user is a member of the given group. So far only " +"is_superuser is settable via this method. This flag is set both true and " +"false at login time based on current LDAP settings." +msgstr "" +"Marqueurs de profil utilisateur mis à jour selon l'appartenance au groupe " +"(la clé est le nom de l'attribut utilisateur, la valeur est le NDD du " +"groupe). Il s'agit de champs booléens qui sont associés selon que " +"l'utilisateur est ou non membre du groupe donné. Jusqu'à présent, seul " +"is_superuser peut être défini avec cette méthode. Ce marqueur est défini à " +"la fois sur True et False au moment de la connexion, en fonction des " +"paramètres LDAP actifs." + +#: sso/conf.py:391 +msgid "LDAP Organization Map" +msgstr "Mappe d'organisations LDAP" + +#: sso/conf.py:392 +msgid "" +"Mapping between organization admins/users and LDAP groups. This controls " +"what users are placed into what Tower organizations relative to their LDAP " +"group memberships. Keys are organization names. Organizations will be " +"created if not present. Values are dictionaries defining the options for " +"each organization's membership. For each organization it is possible to " +"specify what groups are automatically users of the organization and also " +"what groups can administer the organization.\n" +"\n" +" - admins: None, True/False, string or list of strings.\n" +" If None, organization admins will not be updated based on LDAP values.\n" +" If True, all users in LDAP will automatically be added as admins of the " +"organization.\n" +" If False, no LDAP users will be automatically added as admins of the " +"organization.\n" +" If a string or list of strings, specifies the group DN(s) that will be " +"added of the organization if they match any of the specified groups.\n" +" - remove_admins: True/False. Defaults to True.\n" +" If True, a user who is not an member of the given groups will be removed " +"from the organization's administrative list.\n" +" - users: None, True/False, string or list of strings. Same rules apply as " +"for admins.\n" +" - remove_users: True/False. Defaults to True. Same rules apply as for " +"remove_admins." +msgstr "" +"Mappage entre les administrateurs/utilisateurs de l'organisation et les " +"groupes LDAP. Ce paramètre détermine les utilisateurs qui sont placés dans " +"les organisations Tower par rapport à leurs appartenances à un groupe LDAP. " +"Les clés sont les noms d'organisation. Les organisations seront créées si " +"elles ne sont pas présentes. Les valeurs sont des dictionnaires définissant " +"les options d'appartenance à chaque organisation. Pour chaque organisation, " +"il est possible de spécifier les groupes qui sont automatiquement des " +"utilisateurs de l'organisation et ceux qui peuvent administrer " +"l'organisation.\n" +"\n" +" - admins : None, True/False, chaîne ou liste de chaînes.\n" +"Si défini sur None, les administrateurs de l'organisation ne sont pas mis à " +"jour en fonction des valeurs LDAP.\n" +" Si défini sur True, tous les utilisateurs LDAP sont automatiquement ajoutés " +"en tant qu'administrateurs de l'organisation.\n" +" Si défini sur False, aucun utilisateur LDAP n'est automatiquement ajouté en " +"tant qu'administrateur de l'organisation.\n" +" Si une chaîne ou une liste de chaînes est entrée, elle spécifie le ou les " +"NDD de groupe qui seront ajoutés à l'organisation s'ils correspondent à l'un " +"des groupes spécifiés.\n" +" - remove_admins : True/False. Par défaut défini sur True.\n" +" Si défini sur True, tout utilisateur qui n'est pas membre des groupes " +"donnés est supprimé de la liste administrative de l'organisation.\n" +" - users : None, True/False, chaîne ou liste de chaînes. Les mêmes règles " +"s'appliquent que pour admins.\n" +" - remove_users : True/False. Par défaut défini sur True. Les mêmes règles " +"s'appliquent que pour remove_admins." + +#: sso/conf.py:440 +msgid "LDAP Team Map" +msgstr "Mappe d'équipes LDAP" + +#: sso/conf.py:441 +msgid "" +"Mapping between team members (users) and LDAP groups. Keys are team names " +"(will be created if not present). Values are dictionaries of options for " +"each team's membership, where each can contain the following parameters:\n" +"\n" +" - organization: string. The name of the organization to which the team " +"belongs. The team will be created if the combination of organization and " +"team name does not exist. The organization will first be created if it does " +"not exist.\n" +" - users: None, True/False, string or list of strings.\n" +" If None, team members will not be updated.\n" +" If True/False, all LDAP users will be added/removed as team members.\n" +" If a string or list of strings, specifies the group DN(s). User will be " +"added as a team member if the user is a member of ANY of these groups.\n" +"- remove: True/False. Defaults to True. If True, a user who is not a member " +"of the given groups will be removed from the team." +msgstr "" +"Mappage entre les membres d'équipe (utilisateurs) et les groupes LDAP. Les " +"clés sont des noms d'équipe (seront créés s'ils ne sont pas présents). Les " +"valeurs sont des dictionnaires d'options d'appartenance à chaque équipe, où " +"chacune peut contenir les paramètres suivants :\n" +"\n" +" - organization : chaîne. Nom de l'organisation à laquelle l'équipe " +"appartient. Une équipe est créée si la combinaison nom de l'organisation/nom " +"de l'équipe n'existe pas. L'organisation sera d'abord créée si elle n'existe " +"pas.\n" +" - users : None, True/False, chaîne ou liste de chaînes.\n" +" Si défini sur None, les membres de l'équipe ne sont pas mis à jour.\n" +" Si défini sur True/False, tous les utilisateurs LDAP seront ajoutés/" +"supprimés en tant que membres d'équipe.\n" +" Si une chaîne ou une liste de chaînes est entrée, elle spécifie les NDD des " +"groupes. L'utilisateur est ajouté en tant que membre d'équipe s'il est " +"membre de l'UN de ces groupes.\n" +"- remove : True/False. Par défaut défini sur True. Si défini sur True, tout " +"utilisateur qui n'est pas membre des groupes donnés est supprimé de l'équipe." +"" + +#: sso/conf.py:484 +msgid "RADIUS Server" +msgstr "Serveur RADIUS" + +#: sso/conf.py:485 +msgid "" +"Hostname/IP of RADIUS server. RADIUS authentication will be disabled if this " +"setting is empty." +msgstr "" +"Nom d'hôte/IP du serveur RADIUS. L'authentification RADIUS est désactivée si " +"ce paramètre est vide." + +#: sso/conf.py:487 +#: sso/conf.py:501 +#: sso/conf.py:513 +msgid "RADIUS" +msgstr "RADIUS" + +#: sso/conf.py:499 +msgid "RADIUS Port" +msgstr "Port RADIUS" + +#: sso/conf.py:500 +msgid "Port of RADIUS server." +msgstr "Port du serveur RADIUS." + +#: sso/conf.py:511 +msgid "RADIUS Secret" +msgstr "Secret RADIUS" + +#: sso/conf.py:512 +msgid "Shared secret for authenticating to RADIUS server." +msgstr "Secret partagé pour l'authentification sur le serveur RADIUS." + +#: sso/conf.py:528 +msgid "Google OAuth2 Callback URL" +msgstr "URL de rappel OAuth2 pour Google" + +#: sso/conf.py:529 +msgid "" +"Create a project at https://console.developers.google.com/ to obtain an " +"OAuth2 key and secret for a web application. Ensure that the Google+ API is " +"enabled. Provide this URL as the callback URL for your application." +msgstr "" +"Créez un projet sur https://console.developers.google.com/ afin d'obtenir " +"une clé OAuth2 et un secret pour une application Web. Assurez-vous que l'API " +"Google+ est activée. Entrez cette URL comme URL de rappel de votre " +"application." + +#: sso/conf.py:533 +#: sso/conf.py:544 +#: sso/conf.py:555 +#: sso/conf.py:568 +#: sso/conf.py:582 +#: sso/conf.py:594 +#: sso/conf.py:606 +msgid "Google OAuth2" +msgstr "OAuth2 pour Google" + +#: sso/conf.py:542 +msgid "Google OAuth2 Key" +msgstr "Clé OAuth2 pour Google" + +#: sso/conf.py:543 +msgid "" +"The OAuth2 key from your web application at https://console.developers." +"google.com/." +msgstr "" +"Clé OAuth2 de votre application Web sur https://console.developers.google." +"com/." + +#: sso/conf.py:553 +msgid "Google OAuth2 Secret" +msgstr "Secret OAuth2 pour Google" + +#: sso/conf.py:554 +msgid "" +"The OAuth2 secret from your web application at https://console.developers." +"google.com/." +msgstr "" +"Secret OAuth2 de votre application Web sur https://console.developers.google." +"com/." + +#: sso/conf.py:565 +msgid "Google OAuth2 Whitelisted Domains" +msgstr "Domaines sur liste blanche OAuth2 pour Google" + +#: sso/conf.py:566 +msgid "" +"Update this setting to restrict the domains who are allowed to login using " +"Google OAuth2." +msgstr "" +"Mettez à jour ce paramètre pour limiter les domaines qui sont autorisés à se " +"connecter à l'aide de l'authentification OAuth2 avec un compte Google." + +#: sso/conf.py:577 +msgid "Google OAuth2 Extra Arguments" +msgstr "Arguments OAuth2 supplémentaires pour Google" + +#: sso/conf.py:578 +msgid "" +"Extra arguments for Google OAuth2 login. When only allowing a single domain " +"to authenticate, set to `{\"hd\": \"yourdomain.com\"}` and Google will not " +"display any other accounts even if the user is logged in with multiple " +"Google accounts." +msgstr "" +"Arguments supplémentaires pour l'authentification OAuth2 avec un compte " +"Google. Lorsque vous autorisez un seul domaine à s'authentifier, définissez " +"ce paramètre sur {{\"hd\": \"votredomaine.com\"}. Google n'affichera aucun " +"autre compte même si l'utilisateur est connecté avec plusieurs comptes " +"Google." + +#: sso/conf.py:592 +msgid "Google OAuth2 Organization Map" +msgstr "Mappe d'organisations OAuth2 pour Google" + +#: sso/conf.py:604 +msgid "Google OAuth2 Team Map" +msgstr "Mappe d'équipes OAuth2 pour Google" + +#: sso/conf.py:620 +msgid "GitHub OAuth2 Callback URL" +msgstr "URL de rappel OAuth2 pour GitHub" + +#: sso/conf.py:621 +msgid "" +"Create a developer application at https://github.com/settings/developers to " +"obtain an OAuth2 key (Client ID) and secret (Client Secret). Provide this " +"URL as the callback URL for your application." +msgstr "" +"Créez une application de développeur sur https://github.com/settings/" +"developers pour obtenir une clé OAuth2 (ID client) et un secret (secret " +"client). Entrez cette URL comme URL de rappel de votre application." + +#: sso/conf.py:625 +#: sso/conf.py:636 +#: sso/conf.py:646 +#: sso/conf.py:658 +#: sso/conf.py:670 +msgid "GitHub OAuth2" +msgstr "OAuth2 pour GitHub" + +#: sso/conf.py:634 +msgid "GitHub OAuth2 Key" +msgstr "Clé OAuth2 pour GitHub" + +#: sso/conf.py:635 +msgid "The OAuth2 key (Client ID) from your GitHub developer application." +msgstr "Clé OAuth2 (ID client) de votre application de développeur GitHub." + +#: sso/conf.py:644 +msgid "GitHub OAuth2 Secret" +msgstr "Secret OAuth2 pour GitHub" + +#: sso/conf.py:645 +msgid "" +"The OAuth2 secret (Client Secret) from your GitHub developer application." +msgstr "" +"Secret OAuth2 (secret client) de votre application de développeur GitHub." + +#: sso/conf.py:656 +msgid "GitHub OAuth2 Organization Map" +msgstr "Mappe d'organisations OAuth2 pour GitHub" + +#: sso/conf.py:668 +msgid "GitHub OAuth2 Team Map" +msgstr "Mappe d'équipes OAuth2 pour GitHub" + +#: sso/conf.py:684 +msgid "GitHub Organization OAuth2 Callback URL" +msgstr "URL de rappel OAuth2 pour les organisations GitHub" + +#: sso/conf.py:685 +#: sso/conf.py:760 +msgid "" +"Create an organization-owned application at https://github.com/organizations/" +"/settings/applications and obtain an OAuth2 key (Client ID) and " +"secret (Client Secret). Provide this URL as the callback URL for your " +"application." +msgstr "" +"Créez une application appartenant à une organisation sur https://github.com/" +"organizations//settings/applications et obtenez une clé OAuth2 (ID " +"client) et un secret (secret client). Entrez cette URL comme URL de rappel " +"de votre application." + +#: sso/conf.py:689 +#: sso/conf.py:700 +#: sso/conf.py:710 +#: sso/conf.py:722 +#: sso/conf.py:733 +#: sso/conf.py:745 +msgid "GitHub Organization OAuth2" +msgstr "OAuth2 pour les organisations GitHub" + +#: sso/conf.py:698 +msgid "GitHub Organization OAuth2 Key" +msgstr "Clé OAuth2 pour les organisations GitHub" + +#: sso/conf.py:699 +#: sso/conf.py:774 +msgid "The OAuth2 key (Client ID) from your GitHub organization application." +msgstr "Clé OAuth2 (ID client) de votre application d'organisation GitHub." + +#: sso/conf.py:708 +msgid "GitHub Organization OAuth2 Secret" +msgstr "Secret OAuth2 pour les organisations GitHub" + +#: sso/conf.py:709 +#: sso/conf.py:784 +msgid "" +"The OAuth2 secret (Client Secret) from your GitHub organization application." +msgstr "" +"Secret OAuth2 (secret client) de votre application d'organisation GitHub." + +#: sso/conf.py:719 +msgid "GitHub Organization Name" +msgstr "Nom de l'organisation GitHub" + +#: sso/conf.py:720 +msgid "" +"The name of your GitHub organization, as used in your organization's URL: " +"https://github.com//." +msgstr "" +"Nom de votre organisation GitHub, tel qu'utilisé dans l'URL de votre " +"organisation : https://github.com//." + +#: sso/conf.py:731 +msgid "GitHub Organization OAuth2 Organization Map" +msgstr "Mappe d'organisations OAuth2 pour les organisations GitHub" + +#: sso/conf.py:743 +msgid "GitHub Organization OAuth2 Team Map" +msgstr "Mappe d'équipes OAuth2 pour les organisations GitHub" + +#: sso/conf.py:759 +msgid "GitHub Team OAuth2 Callback URL" +msgstr "URL de rappel OAuth2 pour les équipes GitHub" + +#: sso/conf.py:764 +#: sso/conf.py:775 +#: sso/conf.py:785 +#: sso/conf.py:797 +#: sso/conf.py:808 +#: sso/conf.py:820 +msgid "GitHub Team OAuth2" +msgstr "OAuth2 pour les équipes GitHub" + +#: sso/conf.py:773 +msgid "GitHub Team OAuth2 Key" +msgstr "Clé OAuth2 pour les équipes GitHub" + +#: sso/conf.py:783 +msgid "GitHub Team OAuth2 Secret" +msgstr "Secret OAuth2 pour les équipes GitHub" + +#: sso/conf.py:794 +msgid "GitHub Team ID" +msgstr "ID d'équipe GitHub" + +#: sso/conf.py:795 +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 "" +"Recherchez votre ID d'équipe numérique à l'aide de l'API Github : http://" +"fabian-kostadinov.github.io/2015/01/16/how-to-find-a-github-team-id/." + +#: sso/conf.py:806 +msgid "GitHub Team OAuth2 Organization Map" +msgstr "Mappe d'organisations OAuth2 pour les équipes GitHub" + +#: sso/conf.py:818 +msgid "GitHub Team OAuth2 Team Map" +msgstr "Mappe d'équipes OAuth2 pour les équipes GitHub" + +#: sso/conf.py:834 +msgid "Azure AD OAuth2 Callback URL" +msgstr "URL de rappel OAuth2 pour Azure AD" + +#: sso/conf.py:835 +msgid "" +"Register an Azure AD application as described by https://msdn.microsoft.com/" +"en-us/library/azure/dn132599.aspx and obtain an OAuth2 key (Client ID) and " +"secret (Client Secret). Provide this URL as the callback URL for your " +"application." +msgstr "" +"Enregistrez une application AD Azure selon la procédure décrite sur https://" +"msdn.microsoft.com/en-us/library/azure/dn132599.aspx et obtenez une clé " +"OAuth2 (ID client) et un secret (secret client). Entrez cette URL comme URL " +"de rappel de votre application." + +#: sso/conf.py:839 +#: sso/conf.py:850 +#: sso/conf.py:860 +#: sso/conf.py:872 +#: sso/conf.py:884 +msgid "Azure AD OAuth2" +msgstr "OAuth2 pour Azure AD" + +#: sso/conf.py:848 +msgid "Azure AD OAuth2 Key" +msgstr "Clé OAuth2 pour Azure AD" + +#: sso/conf.py:849 +msgid "The OAuth2 key (Client ID) from your Azure AD application." +msgstr "Clé OAuth2 (ID client) de votre application Azure AD." + +#: sso/conf.py:858 +msgid "Azure AD OAuth2 Secret" +msgstr "Secret OAuth2 pour Azure AD" + +#: sso/conf.py:859 +msgid "The OAuth2 secret (Client Secret) from your Azure AD application." +msgstr "Secret OAuth2 (secret client) de votre application Azure AD." + +#: sso/conf.py:870 +msgid "Azure AD OAuth2 Organization Map" +msgstr "Mappe d'organisations OAuth2 pour Azure AD" + +#: sso/conf.py:882 +msgid "Azure AD OAuth2 Team Map" +msgstr "Mappe d'équipes OAuth2 pour Azure AD" + +#: sso/conf.py:903 +msgid "SAML Service Provider Callback URL" +msgstr "URL de rappel du fournisseur de services SAML" + +#: sso/conf.py:904 +msgid "" +"Register Tower as a service provider (SP) with each identity provider (IdP) " +"you have configured. Provide your SP Entity ID and this callback URL for " +"your application." +msgstr "" +"Enregistrez Tower en tant que fournisseur de services (SP) auprès de chaque " +"fournisseur d'identité (IdP) que vous avez configuré. Entrez votre ID " +"d'entité SP et cette URL de rappel pour votre application." + +#: sso/conf.py:907 +#: sso/conf.py:921 +#: sso/conf.py:934 +#: sso/conf.py:948 +#: sso/conf.py:962 +#: sso/conf.py:980 +#: sso/conf.py:1002 +#: sso/conf.py:1021 +#: sso/conf.py:1041 +#: sso/conf.py:1075 +#: sso/conf.py:1088 +msgid "SAML" +msgstr "SAML" + +#: sso/conf.py:918 +msgid "SAML Service Provider Metadata URL" +msgstr "URL de métadonnées du fournisseur de services SAML" + +#: sso/conf.py:919 +msgid "" +"If your identity provider (IdP) allows uploading an XML metadata file, you " +"can download one from this URL." +msgstr "" +"Si votre fournisseur d'identité (IdP) permet de télécharger un fichier de " +"métadonnées XML, vous pouvez le faire à partir de cette URL." + +#: sso/conf.py:931 +msgid "SAML Service Provider Entity ID" +msgstr "ID d'entité du fournisseur de services SAML" + +#: sso/conf.py:932 +msgid "" +"The application-defined unique identifier used as the audience of the SAML " +"service provider (SP) configuration." +msgstr "" +"Identifiant unique défini par l'application utilisé comme audience dans la " +"configuration du fournisseur de services (SP) SAML." + +#: sso/conf.py:945 +msgid "SAML Service Provider Public Certificate" +msgstr "Certificat public du fournisseur de services SAML" + +#: sso/conf.py:946 +msgid "" +"Create a keypair for Tower to use as a service provider (SP) and include the " +"certificate content here." +msgstr "" +"Créez une paire de clés pour que Tower puisse être utilisé comme fournisseur " +"de services (SP) et entrez le contenu du certificat ici." + +#: sso/conf.py:959 +msgid "SAML Service Provider Private Key" +msgstr "Clé privée du fournisseur de services SAML" + +#: sso/conf.py:960 +msgid "" +"Create a keypair for Tower to use as a service provider (SP) and include the " +"private key content here." +msgstr "" +"Créez une paire de clés pour que Tower puisse être utilisé comme fournisseur " +"de services (SP) et entrez le contenu de la clé privée ici." + +#: sso/conf.py:978 +msgid "SAML Service Provider Organization Info" +msgstr "Infos organisationnelles du fournisseur de services SAML" + +#: sso/conf.py:979 +msgid "Configure this setting with information about your app." +msgstr "" +"Configurez ce paramètre en vous servant des informations de votre " +"application." + +#: sso/conf.py:1000 +msgid "SAML Service Provider Technical Contact" +msgstr "Contact technique du fournisseur de services SAML" + +#: sso/conf.py:1001 +#: sso/conf.py:1020 +msgid "Configure this setting with your contact information." +msgstr "Configurez ce paramètre en vous servant de vos coordonnées." + +#: sso/conf.py:1019 +msgid "SAML Service Provider Support Contact" +msgstr "Contact support du fournisseur de services SAML" + +#: sso/conf.py:1034 +msgid "SAML Enabled Identity Providers" +msgstr "Fournisseurs d'identité compatibles SAML" + +#: sso/conf.py:1035 +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 " +"data using attribute names that differ from the default OIDs (https://github." +"com/omab/python-social-auth/blob/master/social/backends/saml.py#L16). " +"Attribute names may be overridden for each IdP." +msgstr "" +"Configurez l'ID d'entité, l'URL SSO et le certificat pour chaque fournisseur " +"d'identité (IdP) utilisé. Plusieurs IdP SAML sont pris en charge. Certains " +"IdP peuvent fournir des données utilisateur à l'aide de noms d'attributs qui " +"diffèrent des OID par défaut (https://github.com/omab/python-social-auth/" +"blob/master/social/backends/saml.py#L16). Les noms d'attributs peuvent être " +"remplacés pour chaque IdP." + +#: sso/conf.py:1073 +msgid "SAML Organization Map" +msgstr "Mappe d'organisations SAML" + +#: sso/conf.py:1086 +msgid "SAML Team Map" +msgstr "Mappe d'équipes SAML" + +#: sso/fields.py:123 +#, python-brace-format +msgid "Invalid connection option(s): {invalid_options}." +msgstr "Option(s) de connexion non valide(s) : {invalid_options}." + +#: sso/fields.py:182 +msgid "Base" +msgstr "Base" + +#: sso/fields.py:183 +msgid "One Level" +msgstr "Un niveau" + +#: sso/fields.py:184 +msgid "Subtree" +msgstr "Sous-arborescence" + +#: sso/fields.py:202 +#, python-brace-format +msgid "Expected a list of three items but got {length} instead." +msgstr "" +"Une liste de trois éléments était attendue, mais {length} a été obtenu à la " +"place." + +#: sso/fields.py:203 +#, python-brace-format +msgid "Expected an instance of LDAPSearch but got {input_type} instead." +msgstr "" +"Une instance de LDAPSearch était attendue, mais {input_type} a été obtenu à " +"la place." + +#: sso/fields.py:239 +#, python-brace-format +msgid "" +"Expected an instance of LDAPSearch or LDAPSearchUnion but got {input_type} " +"instead." +msgstr "" +"Une instance de LDAPSearch ou de LDAPSearchUnion était attendue, mais " +"{input_type} a été obtenu à la place." + +#: sso/fields.py:266 +#, python-brace-format +msgid "Invalid user attribute(s): {invalid_attrs}." +msgstr "Attribut(s) d'utilisateur non valide(s) : {invalid_attrs}." + +#: sso/fields.py:283 +#, python-brace-format +msgid "Expected an instance of LDAPGroupType but got {input_type} instead." +msgstr "" +"Une instance de LDAPGroupType était attendue, mais {input_type} a été obtenu " +"à la place." + +#: sso/fields.py:308 +#, python-brace-format +msgid "Invalid user flag: \"{invalid_flag}\"." +msgstr "Marqueur d'utilisateur non valide : \"{invalid_flag}\"." + +#: sso/fields.py:324 +#: sso/fields.py:491 +#, python-brace-format +msgid "" +"Expected None, True, False, a string or list of strings but got {input_type} " +"instead." +msgstr "" +"Les valeurs None, True, False, une chaîne ou une liste de chaînes étaient " +"attendues, mais {input_type} a été obtenu à la place." + +#: sso/fields.py:360 +#, python-brace-format +msgid "Missing key(s): {missing_keys}." +msgstr "Clé(s) manquante(s) : {missing_keys}." + +#: sso/fields.py:361 +#, python-brace-format +msgid "Invalid key(s): {invalid_keys}." +msgstr "Clé(s) non valide(s) : {invalid_keys}." + +#: sso/fields.py:410 +#: sso/fields.py:527 +#, python-brace-format +msgid "Invalid key(s) for organization map: {invalid_keys}." +msgstr "Clé(s) non valide(s) pour la mappe d'organisations : {invalid_keys}." + +#: sso/fields.py:428 +#, python-brace-format +msgid "Missing required key for team map: {invalid_keys}." +msgstr "Clé obligatoire manquante pour la mappe d'équipes : {invalid_keys}." + +#: sso/fields.py:429 +#: sso/fields.py:546 +#, python-brace-format +msgid "Invalid key(s) for team map: {invalid_keys}." +msgstr "Clé(s) non valide(s) pour la mappe d'équipes : {invalid_keys}." + +#: sso/fields.py:545 +#, python-brace-format +msgid "Missing required key for team map: {missing_keys}." +msgstr "Clé obligatoire manquante pour la mappe d'équipes : {missing_keys}." + +#: sso/fields.py:563 +#, python-brace-format +msgid "Missing required key(s) for org info record: {missing_keys}." +msgstr "" +"Clé(s) obligatoire(s) manquante(s) pour l'enregistrement des infos organis. :" +" {missing_keys}." + +#: sso/fields.py:576 +#, python-brace-format +msgid "Invalid language code(s) for org info: {invalid_lang_codes}." +msgstr "" +"Code(s) langage non valide(s) pour les infos organis. : {invalid_lang_codes}." +"" + +#: sso/fields.py:595 +#, python-brace-format +msgid "Missing required key(s) for contact: {missing_keys}." +msgstr "Clé(s) obligatoire(s) manquante(s) pour le contact : {missing_keys}." + +#: sso/fields.py:607 +#, python-brace-format +msgid "Missing required key(s) for IdP: {missing_keys}." +msgstr "Clé(s) obligatoire(s) manquante(s) pour l'IdP : {missing_keys}." + +#: sso/pipeline.py:24 +#, python-brace-format +msgid "An account cannot be found for {0}" +msgstr "Impossible de trouver un compte pour {0}" + +#: sso/pipeline.py:30 +msgid "Your account is inactive" +msgstr "Votre compte est inactif" + +#: sso/validators.py:19 +#: sso/validators.py:44 +#, python-format +msgid "DN must include \"%%(user)s\" placeholder for username: %s" +msgstr "" +"Le NDD doit inclure l'espace réservé \"%% (user)s\" pour le nom " +"d'utilisateur : % s" + +#: sso/validators.py:26 +#, python-format +msgid "Invalid DN: %s" +msgstr "NDD non valide : %s" + +#: sso/validators.py:56 +#, python-format +msgid "Invalid filter: %s" +msgstr "Filtre incorrect : %s" + +#: templates/error.html:4 +#: ui/templates/ui/index.html:8 +msgid "Ansible Tower" +msgstr "Ansible Tower" + +#: templates/rest_framework/api.html:39 +msgid "Ansible Tower API Guide" +msgstr "Guide pour les API d'Ansible Tower" + +#: templates/rest_framework/api.html:40 +msgid "Back to Ansible Tower" +msgstr "Retour à Ansible Tower" + +#: templates/rest_framework/api.html:41 +msgid "Resize" +msgstr "Redimensionner" + +#: templates/rest_framework/base.html:78 +#: templates/rest_framework/base.html:92 +#, python-format +msgid "Make a GET request on the %(name)s resource" +msgstr "Appliquez une requête GET sur la ressource %(name)s" + +#: templates/rest_framework/base.html:80 +msgid "Specify a format for the GET request" +msgstr "Spécifiez un format pour la requête GET" + +#: templates/rest_framework/base.html:86 +#, python-format +msgid "" +"Make a GET request on the %(name)s resource with the format set to " +"`%(format)s`" +msgstr "" +"Appliquez une requête GET sur la ressource %(name)s avec un format défini " +"sur`%(format)s`" + +#: templates/rest_framework/base.html:100 +#, python-format +msgid "Make an OPTIONS request on the %(name)s resource" +msgstr "Appliquez une requête OPTIONS sur la ressource %(name)s" + +#: templates/rest_framework/base.html:106 +#, python-format +msgid "Make a DELETE request on the %(name)s resource" +msgstr "Appliquez une requête DELETE sur la ressource %(name)s" + +#: templates/rest_framework/base.html:113 +msgid "Filters" +msgstr "Filtres" + +#: templates/rest_framework/base.html:172 +#: templates/rest_framework/base.html:186 +#, python-format +msgid "Make a POST request on the %(name)s resource" +msgstr "Appliquez une requête POST sur la ressource %(name)s" + +#: templates/rest_framework/base.html:216 +#: templates/rest_framework/base.html:230 +#, python-format +msgid "Make a PUT request on the %(name)s resource" +msgstr "Appliquez une requête PUT sur la ressource %(name)s" + +#: templates/rest_framework/base.html:233 +#, python-format +msgid "Make a PATCH request on the %(name)s resource" +msgstr "Appliquez une requête PATCH sur la ressource %(name)s" + +#: ui/apps.py:9 +#: ui/conf.py:22 +#: ui/conf.py:38 +#: ui/conf.py:53 +msgid "UI" +msgstr "IU" + +#: ui/conf.py:16 +msgid "Off" +msgstr "Désactivé" + +#: ui/conf.py:17 +msgid "Anonymous" +msgstr "Anonyme" + +#: ui/conf.py:18 +msgid "Detailed" +msgstr "Détaillé" + +#: ui/conf.py:20 +msgid "Analytics Tracking State" +msgstr "État du suivi analytique" + +#: ui/conf.py:21 +msgid "Enable or Disable Analytics Tracking." +msgstr "Activez ou désactivez le suivi analytique." + +#: ui/conf.py:31 +msgid "Custom Login Info" +msgstr "Infos de connexion personnalisées" + +#: ui/conf.py:32 +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. If multiple paragraphs of text are needed, new lines " +"(paragraphs) must be escaped as `\\n` within the block of text." +msgstr "" +"Si nécessaire, vous pouvez ajouter des informations particulières (telles " +"qu'une mention légale ou une clause de non-responsabilité) à une zone de " +"texte dans la fenêtre modale de connexion, grâce à ce paramètre. Tout " +"contenu ajouté doit l'être en texte brut, dans la mesure où le langage HTML " +"personnalisé et les autres langages de balisage ne sont pas pris en charge. " +"Si plusieurs paragraphes de texte sont nécessaires, les nouvelles lignes " +"(paragraphes) doivent être échappées sous la forme `\\n` dans le bloc de " +"texte." + +#: ui/conf.py:48 +msgid "Custom Logo" +msgstr "Logo personnalisé" + +#: ui/conf.py:49 +msgid "" +"To set up a custom logo, provide a file that you create. For the custom logo " +"to look its best, use a `.png` file with a transparent background. GIF, PNG " +"and JPEG formats are supported." +msgstr "" +"Pour configurer un logo personnalisé, chargez un fichier que vous avez créé. " +"Pour optimiser l'affichage du logo personnalisé, utilisez un fichier `.png` " +"avec un fond transparent. Les formats GIF, PNG et JPEG sont pris en charge." + +#: ui/fields.py:29 +msgid "" +"Invalid format for custom logo. Must be a data URL with a base64-encoded " +"GIF, PNG or JPEG image." +msgstr "" +"Format de logo personnalisé non valide. Entrez une URL de données avec une " +"image GIF, PNG ou JPEG codée en base64." + +#: ui/fields.py:30 +msgid "Invalid base64-encoded data in data URL." +msgstr "Données codées en base64 non valides dans l'URL de données" + +#: ui/templates/ui/index.html:49 +msgid "" +"Your session will expire in 60 seconds, would you like to continue?" +msgstr "" +"Votre session expirera dans 60 secondes, voulez-vous continuer ?" + +#: ui/templates/ui/index.html:64 +msgid "CANCEL" +msgstr "ANNULER" + +#: ui/templates/ui/index.html:116 +msgid "Set how many days of data should be retained." +msgstr "" +"Définissez le nombre de jours pendant lesquels les données doivent être " +"conservées." + +#: ui/templates/ui/index.html:122 +msgid "" +"Please enter an integer that is not " +"negative that is lower than 9999." +msgstr "" +"Entrez un entier non négatif et inférieur à 9999." + +#: ui/templates/ui/index.html:127 +msgid "" +"For facts collected older than the time period specified, save one fact scan " +"(snapshot) per time window (frequency). For example, facts older than 30 " +"days are purged, while one weekly fact scan is kept.\n" +"
\n" +"
CAUTION: Setting both numerical variables to \"0\" " +"will delete all facts.\n" +"
\n" +"
" +msgstr "" +"Pour les faits collectés en amont de la période spécifiée, enregistrez un " +"scan des faits (instantané) par fenêtre temporelle (fréquence). Par exemple, " +"les faits antérieurs à 30 jours sont purgés, tandis qu'un scan de faits " +"hebdomadaire est conservé.\n" +"
\n" +"
ATTENTION : le paramétrage des deux variables numériques sur \"0\" " +"supprime l'ensemble des faits.\n" +"
\n" +"
" + +#: ui/templates/ui/index.html:136 +msgid "Select a time period after which to remove old facts" +msgstr "" +"Sélectionnez un intervalle de temps après lequel les faits anciens pourront " +"être supprimés" + +#: ui/templates/ui/index.html:150 +msgid "" +"Please enter an integer " +"that is not negative " +"that is lower than 9999." +msgstr "" +"Entrez un entier non négatif et inférieur à 9999." + +#: ui/templates/ui/index.html:155 +msgid "Select a frequency for snapshot retention" +msgstr "Sélectionnez une fréquence pour la conservation des instantanés" + +#: ui/templates/ui/index.html:169 +msgid "" +"Please enter an integer that is not negative that is " +"lower than 9999." +msgstr "" +"Entrez un entier non négatif et " +"inférieur à 9999." + +#: ui/templates/ui/index.html:175 +msgid "working..." +msgstr "en cours..." + diff --git a/awx/locale/ja/LC_MESSAGES/ansible-tower-ui.mo b/awx/locale/ja/LC_MESSAGES/ansible-tower-ui.mo new file mode 100644 index 0000000000..4a255758de Binary files /dev/null and b/awx/locale/ja/LC_MESSAGES/ansible-tower-ui.mo differ diff --git a/awx/locale/ja/LC_MESSAGES/ansible-tower-ui.po b/awx/locale/ja/LC_MESSAGES/ansible-tower-ui.po new file mode 100644 index 0000000000..31e33bf0d2 --- /dev/null +++ b/awx/locale/ja/LC_MESSAGES/ansible-tower-ui.po @@ -0,0 +1,2803 @@ +# asasaki , 2017. #zanata +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Project-Id-Version: \n" +"MIME-Version: 1.0\n" +"PO-Revision-Date: 2017-01-10 10:27+0000\n" +"Last-Translator: asasaki \n" +"Language-Team: Japanese\n" +"Language: ja\n" +"X-Generator: Zanata 3.9.6\n" +"Plural-Forms: nplurals=1; plural=0\n" + +#: client/src/notifications/notificationTemplates.form.js:371 +msgid "%s or %s" +msgstr "%s または %s" + +#: client/src/controllers/Projects.js:397 +#: client/src/controllers/Projects.js:679 +msgid "" +"%sNote:%s Mercurial does not support password authentication for SSH. Do not " +"put the username and key in the URL. If using Bitbucket and SSH, do not " +"supply your Bitbucket username." +msgstr "" +"%s注:%s Mercurial は SSH のパスワード認証をサポートしません。ユーザー名およびキーを URL " +"に入れないでください。Bitbucket および SSH を使用している場合は、Bitbucket ユーザー名を入力しないでください。" + +#: client/src/controllers/Projects.js:384 +#: client/src/controllers/Projects.js:666 +msgid "" +"%sNote:%s When using SSH protocol for GitHub or Bitbucket, enter an SSH key " +"only, do not enter a username (other than git). Additionally, GitHub and " +"Bitbucket do not support password authentication when using SSH. GIT read " +"only protocol (git://) does not use username or password information." +msgstr "" +"%s注:%s GitHub または Bitbucket の SSH プロトコルを使用している場合、SSH キーのみを入力し、ユーザー名 (git 以外) " +"を入力しないでください。また、GitHub および Bitbucket は、SSH の使用時のパスワード認証をサポートしません。GIT " +"の読み取り専用プロトコル (git://) はユーザー名またはパスワード情報を使用しません。" + +#: client/src/forms/Credentials.js:287 +msgid "(defaults to %s)" +msgstr "(%s にデフォルト設定)" + +#: client/src/organizations/list/organizations-list.partial.html:15 +msgid "+ ADD" +msgstr "+ 追加" + +#: client/src/controllers/Users.js:185 +msgid "A value is required" +msgstr "値が必要" + +#: client/src/forms/Credentials.js:442 +#: client/src/forms/Inventories.js:153 +#: client/src/forms/JobTemplates.js:414 +#: client/src/forms/Organizations.js:75 +#: client/src/forms/Projects.js:237 +#: client/src/forms/Teams.js:86 +#: client/src/forms/Workflows.js:127 +#: client/src/inventory-scripts/inventory-scripts.list.js:45 +#: client/src/lists/Credentials.js:59 +#: client/src/lists/Inventories.js:68 +#: client/src/lists/Projects.js:67 +#: client/src/lists/Teams.js:50 +#: client/src/lists/Templates.js:62 +#: client/src/lists/Users.js:58 +#: client/src/notifications/notificationTemplates.list.js:52 +msgid "ADD" +msgstr "追加" + +#: client/src/notifications/notifications.list.js:68 +msgid "ADD NOTIFICATION TEMPLATE" +msgstr "通知テンプレートの追加" + +#: client/src/forms/Credentials.js:199 +msgid "API Key" +msgstr "API キー" + +#: client/src/notifications/notificationTemplates.form.js:248 +msgid "API Service/Integration Key" +msgstr "API サービス/統合キー" + +#: client/src/notifications/shared/type-change.service.js:52 +msgid "API Token" +msgstr "API トークン" + +#: client/src/setup-menu/setup-menu.partial.html:59 +msgid "About Tower" +msgstr "Tower について" + +#: client/src/forms/Credentials.js:92 +msgid "Access Key" +msgstr "アクセスキー" + +#: client/src/notifications/notificationTemplates.form.js:226 +msgid "Account SID" +msgstr "アカウント SID" + +#: client/src/notifications/notificationTemplates.form.js:184 +msgid "Account Token" +msgstr "アカウントトークン" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:20 +#: client/src/shared/list-generator/list-generator.factory.js:538 +msgid "Actions" +msgstr "アクション" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:17 +#: client/src/lists/Templates.js:40 +msgid "Activity" +msgstr "アクティビティー" + +#: client/src/configuration/system-form/configuration-system.controller.js:81 +msgid "Activity Stream" +msgstr "アクティビティーストリーム" + +#: client/src/forms/Inventories.js:104 +#: client/src/forms/Inventories.js:150 +#: client/src/forms/Organizations.js:72 +#: client/src/forms/Teams.js:83 +#: client/src/forms/Workflows.js:124 +msgid "Add" +msgstr "追加" + +#: client/src/lists/Credentials.js:17 +msgid "Add Credentials" +msgstr "認証情報の追加" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:12 +msgid "Add Existing Hosts" +msgstr "既存ホストの追加" + +#: client/src/lists/Inventories.js:15 +msgid "Add Inventories" +msgstr "インベントリーの追加" + +#: client/src/notifications/notifications.list.js:63 +msgid "Add Notification" +msgstr "通知の追加" + +#: client/src/lists/Projects.js:15 +msgid "Add Project" +msgstr "プロジェクトの追加" + +#: client/src/forms/JobTemplates.js:459 +#: client/src/forms/Workflows.js:172 +#: client/src/shared/form-generator.js:1707 +msgid "Add Survey" +msgstr "Survey の追加" + +#: client/src/lists/Teams.js:15 +msgid "Add Team" +msgstr "チームの追加" + +#: client/src/lists/Users.js:25 +msgid "Add Users" +msgstr "ユーザーの追加" + +#: client/src/forms/Credentials.js:440 +#: client/src/forms/Inventories.js:151 +#: client/src/forms/JobTemplates.js:412 +#: client/src/forms/Organizations.js:73 +#: client/src/forms/Projects.js:235 +msgid "Add a permission" +msgstr "パーミッションの追加" + +#: client/src/setup-menu/setup-menu.partial.html:23 +msgid "" +"Add passwords, SSH keys, etc. for Tower to use when launching jobs against " +"machines, or when syncing inventories or projects." +msgstr "" +"マシンに対してジョブを起動する際やインベントリーまたはプロジェクトの同期時に使用する Tower のパスワード、SSH キーなどを追加します。" + +#: client/src/forms/Teams.js:84 +msgid "Add user to team" +msgstr "ユーザーのチームへの追加" + +#: client/src/shared/form-generator.js:1450 +msgid "Admin" +msgstr "管理者" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:37 +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:43 +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:65 +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:74 +msgid "All" +msgstr "すべて" + +#: client/src/portal-mode/portal-mode-jobs.partial.html:7 +msgid "All Jobs" +msgstr "すべてのジョブ" + +#: client/src/forms/JobTemplates.js:299 +#: client/src/forms/JobTemplates.js:306 +msgid "Allow Provisioning Callbacks" +msgstr "プロビジョニングコールバックの許可" + +#: client/src/setup-menu/setup-menu.partial.html:11 +msgid "Allow others to sign into Tower and own the content they create." +msgstr "他のユーザーが Tower にサインインし、独自に作成するコンテンツを所有できるようにします。" + +#: client/src/forms/WorkflowMaker.js:50 +msgid "Always" +msgstr "常時" + +#: client/src/controllers/Projects.js:220 +msgid "" +"An SCM update does not appear to be running for project: %s. Click the " +"%sRefresh%s button to view the latest status." +msgstr "SCM 更新がプロジェクトに対して実行されていないようです: %s。%s更新%s ボタンをクリックして最新のステータスを表示してください。" + +#: client/src/controllers/Projects.js:162 +msgid "Are you sure you want to delete the project below?" +msgstr "以下のプロジェクトを削除してもよろしいですか?" + +#: client/src/controllers/Users.js:102 +msgid "Are you sure you want to delete the user below?" +msgstr "以下のユーザーを削除してもよろしいですか?" + +#: client/src/controllers/Projects.js:647 +msgid "Are you sure you want to remove the %s below from %s?" +msgstr "%s から以下の %s を削除してもよろしいですか?" + +#: client/src/forms/Credentials.js:233 +#: client/src/forms/Credentials.js:271 +#: client/src/forms/Credentials.js:310 +#: client/src/forms/Credentials.js:395 +msgid "Ask at runtime?" +msgstr "実行時に確認しますか?" + +#: client/src/shared/form-generator.js:1452 +msgid "Auditor" +msgstr "監査者" + +#: client/src/forms/Credentials.js:73 +msgid "" +"Authentication for network device access. This can include SSH keys, " +"usernames, passwords, and authorize information. Network credentials are " +"used when submitting jobs to run playbooks against network devices." +msgstr "" +"ネットワークデバイスアクセスの認証です。これには、SSH " +"キー、ユーザー名、パスワード、および承認情報が含まれることがあります。ネットワーク認証情報は、ネットワークデバイスに対して Playbook " +"を実行するためのジョブの送信時に使用されます。" + +#: client/src/forms/Credentials.js:69 +msgid "" +"Authentication for remote machine access. This can include SSH keys, " +"usernames, passwords, and sudo information. Machine credentials are used " +"when submitting jobs to run playbooks against remote hosts." +msgstr "" +"リモートマシンアクセスの認証です。これには、SSH キー、ユーザー名、パスワード、および sudo " +"情報が含まれることがあります。マシン認証情報は、リモートホストに対して Playbook を実行するためのジョブの送信時に使用されます。" + +#: client/src/forms/Credentials.js:341 +msgid "Authorize" +msgstr "承認" + +#: client/src/forms/Credentials.js:349 +msgid "Authorize Password" +msgstr "パスワードの承認" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:101 +msgid "Azure AD" +msgstr "Azure AD" + +#: client/src/forms/Projects.js:80 +msgid "" +"Base path used for locating playbooks. Directories found inside this path " +"will be listed in the playbook directory drop-down. Together the base path " +"and selected playbook directory provide the full path used to locate " +"playbooks." +msgstr "" +"Playbook を見つけるために使用されるベースパスです。このパス内にあるディレクトリーは Playbook " +"ディレクトリーのドロップダウンに一覧表示されます。ベースパスと選択された Playbook ディレクトリーは、Playbook " +"を見つけるために使用される完全なパスを提供します。" + +#: client/src/forms/JobTemplates.js:293 +msgid "Become Privilege Escalation" +msgstr "Become (権限昇格)" + +#: client/src/license/license.partial.html:104 +msgid "Browse" +msgstr "参照" + +#: client/src/app.js:317 +msgid "CREDENTIALS" +msgstr "認証情報" + +#: client/src/forms/Projects.js:194 +msgid "Cache Timeout" +msgstr "キャッシュタイムアウト" + +#: client/src/forms/Projects.js:183 +msgid "Cache Timeout%s (seconds)%s" +msgstr "キャッシュタイムアウト%s (seconds)%s" + +#: client/src/controllers/Projects.js:156 +#: client/src/controllers/Users.js:95 +msgid "Call to %s failed. DELETE returned status:" +msgstr "%s の呼び出しに失敗しました。DELETE で返されたステータス:" + +#: client/src/controllers/Projects.js:201 +#: client/src/controllers/Projects.js:217 +msgid "Call to %s failed. GET status:" +msgstr "%s の呼び出しに失敗しました。GET ステータス:" + +#: client/src/controllers/Projects.js:641 +msgid "Call to %s failed. POST returned status:" +msgstr "%s の呼び出しに失敗しました。POST で返されたステータス:" + +#: client/src/controllers/Projects.js:180 +msgid "Call to %s failed. POST status:" +msgstr "%s の呼び出しに失敗しました。POST ステータス:" + +#: client/src/controllers/Projects.js:226 +msgid "Call to get project failed. GET status:" +msgstr "プロジェクトを取得するための呼び出しに失敗しました。GET ステータス:" + +#: client/src/configuration/configuration.controller.js:434 +#: client/src/shared/form-generator.js:1695 +msgid "Cancel" +msgstr "取り消し" + +#: client/src/controllers/Projects.js:196 +msgid "Cancel Not Allowed" +msgstr "取り消しは許可されていません" + +#: client/src/lists/Projects.js:121 +msgid "Cancel the SCM update" +msgstr "SCM 更新の取り消し" + +#: client/src/controllers/Projects.js:53 +msgid "Canceled. Click for details" +msgstr "取り消されました。クリックして詳細を確認してください。" + +#: client/src/forms/Projects.js:82 +msgid "Change %s under \"Configure Tower\" to change this location." +msgstr "この場所を変更するために「Tower の設定」下の %s を変更します。" + +#: client/src/shared/form-generator.js:1084 +msgid "Choose a %s" +msgstr "%s の選択" + +#: client/src/license/license.partial.html:97 +msgid "" +"Choose your license file, agree to the End User License Agreement, and click " +"submit." +msgstr "ライセンスファイルを選択し、使用許諾契約書に同意した後に「送信」をクリックします。" + +#: client/src/forms/Projects.js:151 +msgid "Clean" +msgstr "クリーニング" + +#: client/src/lists/Inventories.js:18 +msgid "" +"Click on a row to select it, and click Finished when done. Click the %s " +"button to create a new inventory." +msgstr "行をクリックしてこれを選択し、終了したら「終了」をクリックします。%s ボタンをクリックして新規インベントリーを作成します。" + +#: client/src/lists/Teams.js:18 +msgid "" +"Click on a row to select it, and click Finished when done. Click the %s " +"button to create a new team." +msgstr "行をクリックしてこれを選択し、終了したら「終了」をクリックします。%s ボタンをクリックして新規チームを作成します。" + +#: client/src/lists/Templates.js:19 +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/forms/Credentials.js:319 +msgid "Client ID" +msgstr "クライアント ID" + +#: client/src/notifications/notificationTemplates.form.js:259 +msgid "Client Identifier" +msgstr "クライアント識別子" + +#: client/src/forms/Credentials.js:328 +msgid "Client Secret" +msgstr "クライアントシークレット" + +#: client/src/shared/form-generator.js:1699 +msgid "Close" +msgstr "閉じる" + +#: client/src/forms/JobTemplates.js:164 +#: client/src/forms/JobTemplates.js:176 +msgid "Cloud Credential" +msgstr "クラウド認証情報" + +#: client/src/helpers/Credentials.js:158 +msgid "CloudForms Host" +msgstr "CloudForms ホスト" + +#: client/src/notifications/notificationTemplates.form.js:295 +msgid "Color can be one of %s." +msgstr "色を %s のいずれかにすることができます。" + +#: client/src/lists/CompletedJobs.js:18 +msgid "Completed Jobs" +msgstr "完了したジョブ" + +#: client/src/management-jobs/card/card.partial.html:32 +msgid "Configure Notifications" +msgstr "通知の設定" + +#: client/src/forms/Users.js:82 +msgid "Confirm Password" +msgstr "パスワードの確認" + +#: client/src/configuration/configuration.controller.js:441 +msgid "Confirm Reset" +msgstr "リセットの確認" + +#: client/src/configuration/configuration.controller.js:450 +msgid "Confirm factory reset" +msgstr "出荷時の設定へのリセットの確認" + +#: client/src/forms/JobTemplates.js:255 +#: client/src/forms/JobTemplates.js:273 +#: client/src/forms/WorkflowMaker.js:141 +#: client/src/forms/WorkflowMaker.js:156 +msgid "" +"Consult the Ansible documentation for further details on the usage of tags." +msgstr "タグの使用法についての詳細は、Ansible ドキュメントを参照してください。" + +#: client/src/forms/JobTemplates.js:241 +msgid "" +"Control the level of output ansible will produce as the playbook executes." +msgstr "Playbook の実行時に Ansible が生成する出力のレベルを制御します。" + +#: client/src/lists/Templates.js:100 +msgid "Copy" +msgstr "コピー" + +#: client/src/lists/Templates.js:103 +msgid "Copy template" +msgstr "テンプレートのコピー" + +#: client/src/forms/Credentials.js:18 +msgid "Create Credential" +msgstr "認証情報の作成" + +#: client/src/lists/Users.js:52 +msgid "Create New" +msgstr "新規作成" + +#: client/src/lists/Credentials.js:57 +msgid "Create a new credential" +msgstr "新規認証情報の作成" + +#: client/src/inventory-scripts/inventory-scripts.list.js:43 +msgid "Create a new custom inventory" +msgstr "新規カスタムインベントリーの作成" + +#: client/src/lists/Inventories.js:66 +msgid "Create a new inventory" +msgstr "新規インベントリーの作成" + +#: client/src/notifications/notificationTemplates.list.js:50 +#: client/src/notifications/notifications.list.js:66 +msgid "Create a new notification template" +msgstr "新規通知テンプレートの作成" + +#: client/src/organizations/list/organizations-list.partial.html:16 +msgid "Create a new organization" +msgstr "新規組織の作成" + +#: client/src/lists/Projects.js:65 +msgid "Create a new project" +msgstr "新規プロジェクトの作成" + +#: client/src/lists/Teams.js:48 +msgid "Create a new team" +msgstr "新規チームの作成" + +#: client/src/lists/Templates.js:60 +msgid "Create a new template" +msgstr "新規テンプレートの作成" + +#: client/src/lists/Users.js:56 +msgid "Create a new user" +msgstr "新規ユーザーの作成" + +#: client/src/setup-menu/setup-menu.partial.html:35 +msgid "Create and edit scripts to dynamically load hosts from any source." +msgstr "任意のソースからホストを動的にロードするためのスクリプトを作成し、編集します。" + +#: client/src/setup-menu/setup-menu.partial.html:42 +msgid "" +"Create templates for sending notifications with Email, HipChat, Slack, and " +"SMS." +msgstr "メール、HipChat、Slack、および SMS での通知を送信するためのテンプレートを作成します。" + +#: client/src/forms/JobTemplates.js:154 +#: client/src/forms/WorkflowMaker.js:60 +#: client/src/forms/WorkflowMaker.js:69 +msgid "Credential" +msgstr "認証情報" + +#: client/src/lists/Credentials.js:18 +#: client/src/lists/Credentials.js:19 +#: client/src/setup-menu/setup-menu.partial.html:22 +msgid "Credentials" +msgstr "認証情報" + +#: client/src/inventory-scripts/inventory-scripts.form.js:50 +#: client/src/inventory-scripts/inventory-scripts.form.js:60 +msgid "Custom Script" +msgstr "カスタムスクリプト" + +#: client/src/app.js:409 +msgid "DASHBOARD" +msgstr "ダッシュボード" + +#: client/src/controllers/Projects.js:649 +#: client/src/controllers/Users.js:104 +msgid "DELETE" +msgstr "削除" + +#: client/src/controllers/Projects.js:161 +#: client/src/controllers/Projects.js:646 +#: client/src/controllers/Users.js:101 +#: client/src/inventory-scripts/inventory-scripts.list.js:74 +#: client/src/lists/Credentials.js:90 +#: client/src/lists/Inventories.js:92 +#: client/src/lists/Teams.js:77 +#: client/src/lists/Templates.js:125 +#: client/src/lists/Users.js:87 +#: client/src/notifications/notificationTemplates.list.js:89 +msgid "Delete" +msgstr "削除" + +#: client/src/lists/Credentials.js:92 +msgid "Delete credential" +msgstr "認証情報の削除" + +#: client/src/lists/Inventories.js:94 +msgid "Delete inventory" +msgstr "インベントリーの削除" + +#: client/src/inventory-scripts/inventory-scripts.list.js:76 +msgid "Delete inventory script" +msgstr "インベントリースクリプトの削除" + +#: client/src/notifications/notificationTemplates.list.js:91 +msgid "Delete notification" +msgstr "通知の削除" + +#: client/src/forms/Projects.js:161 +msgid "Delete on Update" +msgstr "更新時のデプロイ" + +#: client/src/lists/Teams.js:81 +msgid "Delete team" +msgstr "チームの削除" + +#: client/src/lists/Templates.js:128 +msgid "Delete template" +msgstr "テンプレートの削除" + +#: client/src/lists/CompletedJobs.js:82 +msgid "Delete the job" +msgstr "ジョブの削除" + +#: client/src/forms/Projects.js:163 +msgid "" +"Delete the local repository in its entirety prior to performing an update." +msgstr "更新の実行前にローカルリポジトリーを完全に削除します。" + +#: client/src/lists/Projects.js:115 +msgid "Delete the project" +msgstr "プロジェクトの削除" + +#: client/src/lists/ScheduledJobs.js:80 +msgid "Delete the schedule" +msgstr "スケジュールの削除" + +#: client/src/lists/Users.js:91 +msgid "Delete user" +msgstr "ユーザーの削除" + +#: client/src/forms/Projects.js:163 +msgid "" +"Depending on the size of the repository this may significantly increase the " +"amount of time required to complete an update." +msgstr "リポジトリーのサイズにより、更新の完了までに必要な時間が大幅に長くなる可能性があります。" + +#: client/src/forms/Credentials.js:41 +#: client/src/forms/Inventories.js:37 +#: client/src/forms/JobTemplates.js:42 +#: client/src/forms/Organizations.js:33 +#: client/src/forms/Projects.js:38 +#: client/src/forms/Teams.js:34 +#: client/src/forms/Users.js:142 +#: client/src/forms/Users.js:167 +#: client/src/forms/Workflows.js:41 +#: client/src/inventory-scripts/inventory-scripts.form.js:32 +#: client/src/inventory-scripts/inventory-scripts.list.js:25 +#: client/src/lists/Credentials.js:34 +#: client/src/lists/PortalJobTemplates.js:29 +#: client/src/lists/Teams.js:30 +#: client/src/lists/Templates.js:36 +#: client/src/notifications/notificationTemplates.form.js:36 +msgid "Description" +msgstr "説明" + +#: client/src/notifications/notificationTemplates.form.js:138 +#: client/src/notifications/notificationTemplates.form.js:143 +#: client/src/notifications/notificationTemplates.form.js:155 +#: client/src/notifications/notificationTemplates.form.js:160 +#: client/src/notifications/notificationTemplates.form.js:372 +msgid "Destination Channels" +msgstr "送信先チャネル" + +#: client/src/notifications/notificationTemplates.form.js:367 +msgid "Destination Channels or Users" +msgstr "送信先チャネルまたはユーザー" + +#: client/src/notifications/notificationTemplates.form.js:209 +#: client/src/notifications/notificationTemplates.form.js:214 +msgid "Destination SMS Number" +msgstr "送信先 SMS 番号" + +#: client/src/license/license.partial.html:5 +#: client/src/shared/form-generator.js:1481 +msgid "Details" +msgstr "詳細" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:70 +#: client/src/configuration/configuration.controller.js:170 +#: client/src/configuration/configuration.controller.js:232 +#: client/src/configuration/system-form/configuration-system.controller.js:49 +msgid "Discard changes" +msgstr "変更の破棄" + +#: client/src/forms/Teams.js:148 +msgid "Dissasociate permission from team" +msgstr "チームからパーミッションの関連付けを解除" + +#: client/src/forms/Users.js:217 +msgid "Dissasociate permission from user" +msgstr "ユーザーからパーミッションの関連付けを解除" + +#: client/src/forms/Credentials.js:382 +#: client/src/helpers/Credentials.js:133 +msgid "Domain Name" +msgstr "ドメイン名" + +#: client/src/inventory-scripts/inventory-scripts.form.js:58 +msgid "" +"Drag and drop your custom inventory script file here or create one in the " +"field to import your custom inventory." +msgstr "" +"カスタムインベントリーのスクリプトファイルをここにドラッグアンドドロップするか、またはこのフィールドにカスタムインベントリーをインポートするためのファイルを作成します。" + +#: client/src/forms/Projects.js:174 +msgid "" +"Each time a job runs using this project, perform an update to the local " +"repository prior to starting the job." +msgstr "このプロジェクトでジョブを実行する際は常に、ジョブの開始前にローカルリポジトリーに対して更新を実行します。" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:63 +#: client/src/inventory-scripts/inventory-scripts.list.js:57 +#: client/src/lists/Credentials.js:71 +#: client/src/lists/Inventories.js:78 +#: client/src/lists/Teams.js:60 +#: client/src/lists/Templates.js:108 +#: client/src/lists/Users.js:68 +#: client/src/notifications/notificationTemplates.list.js:63 +#: client/src/notifications/notificationTemplates.list.js:72 +msgid "Edit" +msgstr "編集" + +#: client/src/forms/JobTemplates.js:466 +#: client/src/forms/Workflows.js:179 +#: client/src/shared/form-generator.js:1711 +msgid "Edit Survey" +msgstr "Survey の編集" + +#: client/src/lists/Credentials.js:73 +msgid "Edit credential" +msgstr "認証情報の編集" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:66 +msgid "Edit host" +msgstr "ホストの編集" + +#: client/src/lists/Inventories.js:80 +msgid "Edit inventory" +msgstr "インベントリーの編集" + +#: client/src/inventory-scripts/inventory-scripts.list.js:59 +msgid "Edit inventory script" +msgstr "インベントリースクリプトの編集" + +#: client/src/notifications/notificationTemplates.list.js:74 +msgid "Edit notification" +msgstr "通知の編集" + +#: client/src/lists/Teams.js:64 +msgid "Edit team" +msgstr "チームの編集" + +#: client/src/lists/Templates.js:110 +msgid "Edit template" +msgstr "テンプレートの編集" + +#: client/src/lists/Projects.js:102 +msgid "Edit the project" +msgstr "プロジェクトの編集" + +#: client/src/lists/ScheduledJobs.js:66 +msgid "Edit the schedule" +msgstr "スケジュールの編集" + +#: client/src/lists/Users.js:72 +msgid "Edit user" +msgstr "ユーザーの編集" + +#: client/src/controllers/Projects.js:196 +msgid "" +"Either you do not have access or the SCM update process completed. Click the " +"%sRefresh%s button to view the latest status." +msgstr "アクセスがないか、または SCM 更新プロセスが完了しました。%s更新%s ボタンをクリックして最新のステータスを表示します。" + +#: client/src/forms/Credentials.js:192 +#: client/src/forms/Users.js:42 +msgid "Email" +msgstr "メール" + +#: client/src/forms/JobTemplates.js:288 +msgid "Enable Privilege Escalation" +msgstr "権限昇格の有効化" + +#: client/src/forms/JobTemplates.js:303 +msgid "" +"Enables creation of a provisioning callback URL. Using the URL a host can " +"contact Tower and request a configuration update using this job template." +msgstr "" +"プロビジョニングコールバック URL の作成を有効にします。この URL を使用してホストは Tower " +"に接続でき、このジョブテンプレートを使用して接続の更新を要求できます。" + +#: client/src/helpers/Credentials.js:306 +msgid "Encrypted credentials are not supported." +msgstr "暗号化された認証情報はサポートされていません。" + +#: client/src/license/license.partial.html:108 +msgid "End User License Agreement" +msgstr "使用許諾契約書" + +#: client/src/forms/Inventories.js:60 +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/helpers/Credentials.js:159 +msgid "" +"Enter the hostname or IP address for the virtual %s machine which is hosting " +"the CloudForm appliance." +msgstr "CloudForm アプライアンスをホストしている仮想%sマシンのホスト名または IP アドレスを入力します。" + +#: client/src/helpers/Credentials.js:150 +msgid "" +"Enter the hostname or IP address name which %scorresponds to your Red Hat " +"Satellite 6 server." +msgstr "Red Hat Satellite 6 サーバーに対応するホスト名%sまたは IP アドレスを入力します。" + +#: client/src/helpers/Credentials.js:128 +msgid "" +"Enter the hostname or IP address which corresponds to your VMware vCenter." +msgstr "VMware vCenter に対応するホスト名または IP アドレスを入力します。" + +#: client/src/configuration/configuration.controller.js:292 +#: client/src/configuration/configuration.controller.js:370 +#: client/src/configuration/configuration.controller.js:404 +#: client/src/configuration/configuration.controller.js:423 +#: client/src/controllers/Projects.js:133 +#: client/src/controllers/Projects.js:155 +#: client/src/controllers/Projects.js:180 +#: client/src/controllers/Projects.js:201 +#: client/src/controllers/Projects.js:216 +#: client/src/controllers/Projects.js:225 +#: client/src/controllers/Projects.js:363 +#: client/src/controllers/Projects.js:557 +#: client/src/controllers/Projects.js:623 +#: client/src/controllers/Projects.js:641 +#: client/src/controllers/Users.js:182 +#: client/src/controllers/Users.js:267 +#: client/src/controllers/Users.js:321 +#: client/src/controllers/Users.js:94 +#: client/src/helpers/Credentials.js:310 +#: client/src/helpers/Credentials.js:326 +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:119 +msgid "Error!" +msgstr "エラー!" + +#: client/src/controllers/Projects.js:381 +#: client/src/controllers/Projects.js:664 +msgid "Example URLs for GIT SCM include:" +msgstr "GIT SCM のサンプル URL には以下が含まれます:" + +#: client/src/controllers/Projects.js:394 +#: client/src/controllers/Projects.js:676 +msgid "Example URLs for Mercurial SCM include:" +msgstr "Mercurial SCM のサンプル URL には以下が含まれます:" + +#: client/src/controllers/Projects.js:389 +#: client/src/controllers/Projects.js:671 +msgid "Example URLs for Subversion SCM include:" +msgstr "Subversion SCM のサンプル URL には以下が含まれます:" + +#: client/src/license/license.partial.html:39 +msgid "Expires On" +msgstr "有効期限" + +#: client/src/forms/JobTemplates.js:352 +#: client/src/forms/JobTemplates.js:364 +#: client/src/forms/Workflows.js:72 +#: client/src/forms/Workflows.js:84 +msgid "Extra Variables" +msgstr "追加変数" + +#: client/src/dashboard/graphs/job-status/job-status-graph.directive.js:67 +msgid "FAILED" +msgstr "失敗" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:80 +msgid "Failed" +msgstr "失敗" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:44 +msgid "Failed Hosts" +msgstr "失敗したホスト" + +#: client/src/controllers/Users.js:182 +msgid "Failed to add new user. POST returned status:" +msgstr "新規ユーザーを追加できませんでした。POST で返されたステータス:" + +#: client/src/helpers/Credentials.js:311 +msgid "Failed to create new Credential. POST status:" +msgstr "新規の認証情報を作成できませんでした。POST ステータス:" + +#: client/src/controllers/Projects.js:364 +msgid "Failed to create new project. POST returned status:" +msgstr "新規プロジェクトを作成できませんでした。POST で返されたステータス:" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:120 +msgid "Failed to get third-party login types. Returned status:" +msgstr "サードパーティーのログインタイプを取得できませんでした。返されたステータス:" + +#: client/src/controllers/Projects.js:558 +msgid "Failed to retrieve project: %s. GET status:" +msgstr "プロジェクトを取得できませんでした: %s. GET ステータス:" + +#: client/src/controllers/Users.js:268 +#: client/src/controllers/Users.js:322 +msgid "Failed to retrieve user: %s. GET status:" +msgstr "ユーザーを取得できませんでした: %s. GET ステータス:" + +#: client/src/configuration/configuration.controller.js:371 +msgid "Failed to save settings. Returned status:" +msgstr "設定を保存できませんでした。返されたステータス:" + +#: client/src/configuration/configuration.controller.js:405 +msgid "Failed to save toggle settings. Returned status:" +msgstr "トグルの設定を保存できませんでした。返されたステータス:" + +#: client/src/helpers/Credentials.js:327 +msgid "Failed to update Credential. PUT status:" +msgstr "認証情報を更新できませんでした。PUT ステータス:" + +#: client/src/controllers/Projects.js:623 +msgid "Failed to update project: %s. PUT status:" +msgstr "プロジェクトを更新できませんでした: %s. PUT ステータス:" + +#: client/src/notifications/notifications.list.js:49 +msgid "Failure" +msgstr "失敗" + +#: client/src/lists/CompletedJobs.js:56 +#: client/src/lists/PortalJobs.js:37 +msgid "Finished" +msgstr "終了日時" + +#: client/src/forms/Users.js:28 +#: client/src/lists/Users.js:41 +msgid "First Name" +msgstr "名" + +#: client/src/helpers/Credentials.js:142 +msgid "For example, %s" +msgstr "例: %s" + +#: client/src/notifications/notificationTemplates.form.js:142 +#: client/src/notifications/notificationTemplates.form.js:159 +#: client/src/notifications/notificationTemplates.form.js:213 +#: client/src/notifications/notificationTemplates.form.js:333 +#: client/src/notifications/notificationTemplates.form.js:371 +#: client/src/notifications/notificationTemplates.form.js:98 +msgid "For example:" +msgstr "例:" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:54 +msgid "" +"For hosts that are part of an external inventory, this flag cannot be " +"changed. It will be set by the inventory sync process." +msgstr "外部インベントリーの一部であるホストの場合、このフラグを変更できません。これはインベントリー同期プロセスで設定されます。" + +#: client/src/forms/JobTemplates.js:223 +#: client/src/forms/WorkflowMaker.js:125 +msgid "" +"For more information and examples see %sthe Patterns topic at docs.ansible." +"com%s." +msgstr "詳細情報およびサンプルについては、docs.ansible.com の %sパターンのトピックを参照してください%s。" + +#: client/src/forms/JobTemplates.js:199 +#: client/src/forms/JobTemplates.js:212 +msgid "Forks" +msgstr "フォーク" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:102 +msgid "GitHub" +msgstr "GitHub" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:103 +msgid "GitHub Org" +msgstr "GitHub 組織" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:104 +msgid "GithHub Team" +msgstr "GithHub チーム" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:105 +msgid "Google OAuth2" +msgstr "Google OAuth2" + +#: client/src/forms/Teams.js:118 +msgid "Granted Permissions" +msgstr "付与されたパーミッション" + +#: client/src/forms/Users.js:183 +msgid "Granted permissions" +msgstr "付与されたパーミッション" + +#: client/src/setup-menu/setup-menu.partial.html:5 +msgid "" +"Group all of your content to manage permissions across departments in your " +"company." +msgstr "会社内の複数の部署のパーミッションを管理するためにすべてのコンテンツを分類します。" + +#: client/src/notifications/notificationTemplates.form.js:324 +msgid "HTTP Headers" +msgstr "HTTP ヘッダー" + +#: client/src/forms/Credentials.js:140 +#: client/src/notifications/notificationTemplates.form.js:72 +msgid "Host" +msgstr "ホスト" + +#: client/src/helpers/Credentials.js:131 +msgid "Host (Authentication URL)" +msgstr "ホスト (認証 URL)" + +#: client/src/forms/JobTemplates.js:326 +#: client/src/forms/JobTemplates.js:335 +msgid "Host Config Key" +msgstr "ホスト設定キー" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:55 +msgid "Host Enabled" +msgstr "有効なホスト" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:39 +msgid "Hosts" +msgstr "ホスト" + +#: client/src/license/license.partial.html:52 +msgid "Hosts Available" +msgstr "利用可能なホスト" + +#: client/src/license/license.partial.html:64 +msgid "Hosts Remaining" +msgstr "残りのホスト" + +#: client/src/license/license.partial.html:58 +msgid "Hosts Used" +msgstr "使用されたホスト" + +#: client/src/license/license.partial.html:116 +msgid "I agree to the End User License Agreement" +msgstr "使用許諾契約書に同意します。" + +#: client/src/main-menu/main-menu.partial.html:104 +#: client/src/main-menu/main-menu.partial.html:27 +msgid "INVENTORIES" +msgstr "インベントリー" + +#: client/src/notifications/notificationTemplates.form.js:356 +msgid "IRC Nick" +msgstr "IRC ニック" + +#: client/src/notifications/notificationTemplates.form.js:345 +msgid "IRC Server Address" +msgstr "IRC サーバーアドレス" + +#: client/src/notifications/shared/type-change.service.js:58 +msgid "IRC Server Password" +msgstr "IRC サーバーパスワード" + +#: client/src/notifications/shared/type-change.service.js:57 +msgid "IRC Server Port" +msgstr "IRC サーバーポート" + +#: client/src/forms/JobTemplates.js:291 +msgid "" +"If enabled, run this playbook as an administrator. This is the equivalent of " +"passing the %s option to the %s command." +msgstr "有効な場合、この Playbook を管理者として実行します。これは %s オプションを %s コマンドに渡すことに相当します。" + +#: client/src/forms/Credentials.js:54 +msgid "" +"If no organization is given, the credential can only be used by the user " +"that creates the credential. Organization admins and system administrators " +"can assign an organization so that roles for the credential can be assigned " +"to users and teams in that organization." +msgstr "" +"組織が指定されない場合、認証情報はそれを作成するユーザーのみに使用されます。組織管理者およびシステム管理者は組織を割り当て、認証情報のロールを組織内のユーザーおよびチームに割り当てられるようにします。" + +#: client/src/license/license.partial.html:70 +msgid "" +"If you are ready to upgrade, please contact us by clicking the button below" +msgstr "アップグレードの準備ができましたら、以下のボタンをクリックしてお問い合わせください。" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:54 +msgid "" +"Indicates if a host is available and should be included in running jobs." +msgstr "ホストが利用可能かどうか、また実行中のジョブに組み込む必要があるかどうかを示します。" + +#: client/src/forms/JobTemplates.js:58 +msgid "" +"Instead, %s will check playbook syntax, test environment setup and report " +"problems." +msgstr "代わりに、%s は Playbook 構文、テスト環境セットアップおよびレポートの問題を検査します。" + +#: client/src/license/license.partial.html:11 +msgid "Invalid License" +msgstr "無効なライセンス" + +#: client/src/license/license.controller.js:69 +#: client/src/license/license.controller.js:76 +msgid "Invalid file format. Please upload valid JSON." +msgstr "無効なファイル形式です。有効な JSON をアップロードしてください。" + +#: client/src/login/loginModal/loginModal.partial.html:34 +msgid "Invalid username and/or password. Please try again." +msgstr "無効なユーザー名および/またはパスワードです。やり直してください。" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:50 +#: client/src/lists/Inventories.js:16 +#: client/src/lists/Inventories.js:17 +msgid "Inventories" +msgstr "インベントリー" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:41 +#: client/src/forms/JobTemplates.js:73 +#: client/src/forms/JobTemplates.js:86 +#: client/src/forms/WorkflowMaker.js:79 +#: client/src/forms/WorkflowMaker.js:89 +msgid "Inventory" +msgstr "インベントリー" + +#: client/src/inventory-scripts/inventory-scripts.list.js:12 +#: client/src/setup-menu/setup-menu.partial.html:34 +msgid "Inventory Scripts" +msgstr "インベントリースクリプト" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:46 +msgid "Inventory Sync" +msgstr "インベントリー同期" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:55 +msgid "Inventory Sync Failures" +msgstr "インベントリーの同期の失敗" + +#: client/src/forms/Inventories.js:67 +msgid "Inventory Variables" +msgstr "インベントリー変数" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:4 +msgid "JOB STATUS" +msgstr "ジョブステータス" + +#: client/src/forms/JobTemplates.js:23 +msgid "JOB TEMPLATE" +msgstr "ジョブテンプレート" + +#: client/src/app.js:429 +#: client/src/dashboard/graphs/job-status/job-status-graph.directive.js:113 +#: client/src/main-menu/main-menu.partial.html:122 +#: client/src/main-menu/main-menu.partial.html:43 +msgid "JOBS" +msgstr "ジョブ" + +#: client/src/forms/JobTemplates.js:248 +#: client/src/forms/JobTemplates.js:256 +#: client/src/forms/WorkflowMaker.js:134 +#: client/src/forms/WorkflowMaker.js:142 +msgid "Job Tags" +msgstr "ジョブタグ" + +#: client/src/lists/Templates.js:65 +msgid "Job Template" +msgstr "ジョブテンプレート" + +#: client/src/lists/PortalJobTemplates.js:15 +#: client/src/lists/PortalJobTemplates.js:16 +msgid "Job Templates" +msgstr "ジョブテンプレート" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:32 +#: client/src/forms/JobTemplates.js:48 +#: client/src/forms/JobTemplates.js:62 +#: client/src/forms/WorkflowMaker.js:110 +#: client/src/forms/WorkflowMaker.js:99 +msgid "Job Type" +msgstr "ジョブタイプ" + +#: client/src/lists/PortalJobs.js:15 +#: client/src/lists/PortalJobs.js:19 +#: client/src/partials/jobs.html:7 +msgid "Jobs" +msgstr "ジョブ" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:106 +msgid "LDAP" +msgstr "LDAP" + +#: client/src/main-menu/main-menu.partial.html:83 +msgid "LOG OUT" +msgstr "ログアウト" + +#: client/src/notifications/notificationTemplates.form.js:270 +msgid "Label to be shown with notification" +msgstr "通知と共に表示されるラベル" + +#: client/src/forms/JobTemplates.js:340 +#: client/src/forms/JobTemplates.js:345 +#: client/src/forms/Workflows.js:60 +#: client/src/forms/Workflows.js:65 +#: client/src/lists/Templates.js:47 +msgid "Labels" +msgstr "ラベル" + +#: client/src/forms/Users.js:35 +#: client/src/lists/Users.js:45 +msgid "Last Name" +msgstr "姓" + +#: client/src/lists/Projects.js:53 +msgid "Last Updated" +msgstr "最終更新日時" + +#: client/src/lists/PortalJobTemplates.js:39 +#: client/src/lists/Templates.js:84 +#: client/src/shared/form-generator.js:1703 +msgid "Launch" +msgstr "起動" + +#: client/src/management-jobs/card/card.partial.html:21 +msgid "Launch Management Job" +msgstr "管理ジョブの起動" + +#: client/src/license/license.controller.js:42 +#: client/src/license/license.partial.html:8 +msgid "License" +msgstr "ライセンス" + +#: client/src/license/license.partial.html:102 +msgid "License File" +msgstr "ライセンスファイル" + +#: client/src/license/license.partial.html:33 +msgid "License Key" +msgstr "ライセンスキー" + +#: client/src/license/license.controller.js:42 +msgid "License Management" +msgstr "ライセンス管理" + +#: client/src/license/license.partial.html:21 +msgid "License Type" +msgstr "ライセンスタイプ" + +#: client/src/forms/JobTemplates.js:218 +#: client/src/forms/JobTemplates.js:225 +#: client/src/forms/WorkflowMaker.js:120 +#: client/src/forms/WorkflowMaker.js:127 +msgid "Limit" +msgstr "制限" + +#: client/src/shared/socket/socket.service.js:170 +msgid "Live events: attempting to connect to the Tower server." +msgstr "ライブイベント: Tower サーバーへの接続を試行しています。" + +#: client/src/shared/socket/socket.service.js:174 +msgid "" +"Live events: connected. Pages containing job status information will " +"automatically update in real-time." +msgstr "ライブイベント: 接続されています。ジョブステータス情報を含むページは自動的にリアルタイムで更新されます。" + +#: client/src/shared/socket/socket.service.js:178 +msgid "Live events: error connecting to the Tower server." +msgstr "ライブイベント: Tower サーバーへの接続時にエラーが発生しました。" + +#: client/src/shared/form-generator.js:1977 +msgid "Loading..." +msgstr "ロード中..." + +#: client/src/main-menu/main-menu.partial.html:188 +msgid "Log Out" +msgstr "ログアウト" + +#: client/src/configuration/system-form/configuration-system.controller.js:82 +msgid "Logging" +msgstr "ロギング" + +#: client/src/management-jobs/card/card.route.js:21 +msgid "MANAGEMENT JOBS" +msgstr "管理ジョブ" + +#: client/src/forms/Credentials.js:68 +msgid "Machine" +msgstr "マシン" + +#: client/src/forms/JobTemplates.js:137 +msgid "Machine Credential" +msgstr "マシンの認証情報" + +#: client/src/setup-menu/setup-menu.partial.html:29 +msgid "" +"Manage the cleanup of old job history, activity streams, data marked for " +"deletion, and system tracking info." +msgstr "古いジョブ履歴、アクティビティーストリーム、削除用にマークされたデータ、およびシステムトラッキング情報のクリーンアップを管理します。" + +#: client/src/helpers/Credentials.js:111 +msgid "Management Certificate" +msgstr "管理証明書" + +#: client/src/management-jobs/card/card.partial.html:4 +#: client/src/setup-menu/setup-menu.partial.html:28 +msgid "Management Jobs" +msgstr "管理ジョブ" + +#: client/src/controllers/Projects.js:62 +msgid "Manual projects do not require a schedule" +msgstr "手動プロジェクトにスケジュールは不要です" + +#: client/src/controllers/Projects.js:547 +#: client/src/controllers/Projects.js:61 +msgid "Manual projects do not require an SCM update" +msgstr "手動プロジェクトに SCM 更新は不要です" + +#: client/src/login/loginModal/loginModal.partial.html:28 +msgid "Maximum per-user sessions reached. Please sign in." +msgstr "ユーザーあたりの最大セッション数に達しました。サインインしてください。" + +#: client/src/configuration/system-form/configuration-system.controller.js:80 +msgid "Misc. System" +msgstr "その他のシステム" + +#: client/src/portal-mode/portal-mode-jobs.partial.html:4 +msgid "My Jobs" +msgstr "マイジョブ" + +#: client/src/main-menu/main-menu.partial.html:160 +msgid "My View" +msgstr "マイビュー" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:18 +msgid "NO HOSTS FOUND" +msgstr "ホストが見つかりませんでした" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:14 +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:13 +#: client/src/forms/Credentials.js:34 +#: client/src/forms/Inventories.js:29 +#: client/src/forms/JobTemplates.js:35 +#: client/src/forms/Organizations.js:26 +#: client/src/forms/Projects.js:31 +#: client/src/forms/Teams.js:126 +#: client/src/forms/Teams.js:27 +#: client/src/forms/Users.js:139 +#: client/src/forms/Users.js:164 +#: client/src/forms/Users.js:190 +#: client/src/forms/Workflows.js:34 +#: client/src/inventory-scripts/inventory-scripts.form.js:25 +#: client/src/inventory-scripts/inventory-scripts.list.js:20 +#: client/src/lists/CompletedJobs.js:43 +#: client/src/lists/Credentials.js:29 +#: client/src/lists/Inventories.js:46 +#: client/src/lists/PortalJobTemplates.js:24 +#: client/src/lists/PortalJobs.js:32 +#: client/src/lists/Projects.js:37 +#: client/src/lists/ScheduledJobs.js:32 +#: client/src/lists/Teams.js:25 +#: client/src/lists/Templates.js:26 +#: client/src/notifications/notificationTemplates.form.js:29 +#: client/src/notifications/notificationTemplates.list.js:33 +#: client/src/notifications/notifications.list.js:26 +msgid "Name" +msgstr "名前" + +#: client/src/forms/Credentials.js:72 +msgid "Network" +msgstr "ネットワーク" + +#: client/src/forms/JobTemplates.js:182 +#: client/src/forms/JobTemplates.js:193 +msgid "Network Credential" +msgstr "ネットワークの認証情報" + +#: client/src/forms/JobTemplates.js:192 +msgid "" +"Network credentials are used by Ansible networking modules to connect to and " +"manage networking devices." +msgstr "" +"ネットワーク認証情報は、ネットワークデバイスへの接続およびその管理を実行するために Ansible ネットワークモジュールによって使用されます。" + +#: client/src/inventory-scripts/inventory-scripts.form.js:16 +msgid "New Custom Inventory" +msgstr "新規カスタムインベントリー" + +#: client/src/forms/Inventories.js:18 +msgid "New Inventory" +msgstr "新規インベントリー" + +#: client/src/forms/JobTemplates.js:20 +msgid "New Job Template" +msgstr "新規ジョブテンプレート" + +#: client/src/notifications/notificationTemplates.form.js:16 +msgid "New Notification Template" +msgstr "新規通知テンプレート" + +#: client/src/forms/Organizations.js:18 +msgid "New Organization" +msgstr "新規組織" + +#: client/src/forms/Projects.js:18 +msgid "New Project" +msgstr "新規プロジェクト" + +#: client/src/forms/Teams.js:18 +msgid "New Team" +msgstr "新規チーム" + +#: client/src/forms/Users.js:18 +msgid "New User" +msgstr "新規ユーザー" + +#: client/src/forms/Workflows.js:19 +msgid "New Workflow Job Template" +msgstr "新規ワークフロージョブテンプレート" + +#: client/src/controllers/Users.js:174 +msgid "New user successfully created!" +msgstr "新規ユーザーが正常に作成されました!" + +#: client/src/lists/ScheduledJobs.js:50 +msgid "Next Run" +msgstr "次回の実行日時" + +#: client/src/lists/Credentials.js:24 +msgid "No Credentials Have Been Created" +msgstr "認証情報が作成されていません" + +#: client/src/controllers/Projects.js:123 +msgid "No SCM Configuration" +msgstr "SCM 設定がありません" + +#: client/src/controllers/Projects.js:114 +msgid "No Updates Available" +msgstr "利用可能な更新がありません" + +#: client/src/lists/CompletedJobs.js:22 +msgid "No completed jobs" +msgstr "完了したジョブがありません" + +#: client/src/license/license.controller.js:41 +msgid "No file selected." +msgstr "ファイルが選択されていません。" + +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:46 +msgid "No jobs were recently run." +msgstr "最近実行されたジョブがありません。" + +#: client/src/forms/Teams.js:123 +#: client/src/forms/Users.js:187 +msgid "No permissions have been granted" +msgstr "パーミッションが付与されていません" + +#: client/src/lists/ScheduledJobs.js:18 +msgid "No schedules exist" +msgstr "スケジュールがありません" + +#: client/src/controllers/Users.js:16 +msgid "Normal User" +msgstr "標準ユーザー" + +#: client/src/controllers/Projects.js:64 +msgid "Not configured for SCM" +msgstr "SCM 用に設定されていません" + +#: client/src/notifications/notificationTemplates.form.js:293 +msgid "Notification Color" +msgstr "通知の色" + +#: client/src/notifications/notificationTemplates.list.js:14 +msgid "Notification Templates" +msgstr "通知テンプレート" + +#: client/src/notifications/notifications.list.js:17 +#: client/src/setup-menu/setup-menu.partial.html:41 +msgid "Notifications" +msgstr "通知" + +#: client/src/notifications/notificationTemplates.form.js:306 +msgid "Notify Channel" +msgstr "通知チャネル" + +#: client/src/notifications/notificationTemplates.form.js:198 +msgid "Number associated with the \"Messaging Service\" in Twilio." +msgstr "Twilio の \"メッセージングサービス\" に関連付けられた数字。 " + +#: client/src/shared/form-generator.js:547 +msgid "OFF" +msgstr "オフ" + +#: client/src/shared/form-generator.js:545 +msgid "ON" +msgstr "オン" + +#: client/src/organizations/list/organizations-list.partial.html:6 +msgid "ORGANIZATIONS" +msgstr "組織" + +#: client/src/forms/WorkflowMaker.js:45 +msgid "On Failure" +msgstr "失敗した場合 " + +#: client/src/forms/WorkflowMaker.js:40 +msgid "On Success" +msgstr "成功した場合 " + +#: client/src/forms/Credentials.js:377 +msgid "" +"OpenStack domains define administrative boundaries. It is only needed for " +"Keystone v3 authentication URLs. Common scenarios include:" +msgstr "" +"OpenStack ドメインは管理上の境界を定義します。これは Keystone v3 認証 URL " +"にのみ必要です。共通するシナリオには以下が含まれます:" + +#: client/src/forms/JobTemplates.js:347 +#: client/src/forms/Workflows.js:67 +msgid "" +"Optional labels that describe this job template, such as 'dev' or 'test'. " +"Labels can be used to group and filter job templates and completed jobs in " +"the Tower display." +msgstr "" +"「dev」または「test」などのこのジョブテンプレートを説明するオプションラベルです。ラベルを使用し、Tower " +"のディスプレイでジョブテンプレートおよび完了したジョブの分類およびフィルターを実行できます。" + +#: client/src/forms/JobTemplates.js:284 +#: client/src/notifications/notificationTemplates.form.js:391 +msgid "Options" +msgstr "オプション" + +#: client/src/forms/Credentials.js:49 +#: client/src/forms/Credentials.js:55 +#: client/src/forms/Inventories.js:42 +#: client/src/forms/Projects.js:43 +#: client/src/forms/Projects.js:49 +#: client/src/forms/Teams.js:39 +#: client/src/forms/Users.js:59 +#: client/src/forms/Workflows.js:47 +#: client/src/forms/Workflows.js:53 +#: client/src/inventory-scripts/inventory-scripts.form.js:37 +#: client/src/inventory-scripts/inventory-scripts.list.js:30 +#: client/src/lists/Inventories.js:52 +#: client/src/lists/Teams.js:35 +#: client/src/notifications/notificationTemplates.form.js:41 +msgid "Organization" +msgstr "組織" + +#: client/src/forms/Users.js:129 +#: client/src/setup-menu/setup-menu.partial.html:4 +msgid "Organizations" +msgstr "組織" + +#: client/src/forms/Credentials.js:80 +msgid "Others (Cloud Providers)" +msgstr "その他 (クラウドプロバイダー)" + +#: client/src/lists/Credentials.js:45 +msgid "Owners" +msgstr "所有者" + +#: client/src/login/loginModal/loginModal.partial.html:68 +msgid "PASSWORD" +msgstr "パスワード" + +#: client/src/organizations/list/organizations-list.partial.html:44 +#: client/src/shared/form-generator.js:1880 +#: client/src/shared/list-generator/list-generator.factory.js:245 +msgid "PLEASE ADD ITEMS TO THIS LIST" +msgstr "項目をこの一覧に追加してください" + +#: client/src/main-menu/main-menu.partial.html:67 +msgid "PORTAL MODE" +msgstr "ポータルモード" + +#: client/src/main-menu/main-menu.partial.html:19 +#: client/src/main-menu/main-menu.partial.html:95 +msgid "PROJECTS" +msgstr "プロジェクト" + +#: client/src/notifications/notificationTemplates.form.js:237 +msgid "Pagerduty subdomain" +msgstr "Pagerduty サブドメイン" + +#: client/src/forms/JobTemplates.js:358 +#: client/src/forms/Workflows.js:78 +msgid "" +"Pass extra command line variables to the playbook. This is the %s or %s " +"command line parameter for %s. Provide key/value pairs using either YAML or " +"JSON." +msgstr "" +"追加のコマンドライン変数を Playbook に渡します。これは、%s の %s または %s コマンドラインパラメーターです。YAML または " +"JSON のいずれかを使用してキーと値のペアを指定します。" + +#: client/src/forms/Credentials.js:227 +#: client/src/forms/Users.js:70 +#: client/src/helpers/Credentials.js:119 +#: client/src/helpers/Credentials.js:127 +#: client/src/helpers/Credentials.js:147 +#: client/src/helpers/Credentials.js:156 +#: client/src/helpers/Credentials.js:165 +#: client/src/helpers/Credentials.js:45 +#: client/src/helpers/Credentials.js:94 +#: client/src/notifications/shared/type-change.service.js:28 +msgid "Password" +msgstr "パスワード" + +#: client/src/helpers/Credentials.js:73 +msgid "Password (API Key)" +msgstr "パスワード (API キー)" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:20 +msgid "Past 24 Hours" +msgstr "過去 24 時間" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:15 +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:26 +msgid "Past Month" +msgstr "過去 1 ヵ月" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:23 +msgid "Past Week" +msgstr "過去 1 週間" + +#: client/src/helpers/Credentials.js:102 +msgid "" +"Paste the contents of the PEM file associated with the service account email." +"" +msgstr "サービスアカウントメールに関連付けられた PEM ファイルの内容を貼り付けます。" + +#: client/src/helpers/Credentials.js:114 +msgid "" +"Paste the contents of the PEM file that corresponds to the certificate you " +"uploaded in the Microsoft Azure console." +msgstr "Microsoft Azure コンソールにアップロードした証明書に対応する PEM ファイルの内容を貼り付けます。" + +#: client/src/helpers/Credentials.js:66 +msgid "Paste the contents of the SSH private key file." +msgstr "SSH 秘密鍵ファイルの内容を貼り付けます。" + +#: client/src/helpers/Credentials.js:41 +msgid "Paste the contents of the SSH private key file.%s or click to close%s" +msgstr "SSH 秘密鍵ファイルの内容を貼り付けます。%s またはクリックして %s を閉じます。" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:8 +msgid "Period" +msgstr "期間" + +#: client/src/controllers/Projects.js:284 +#: client/src/controllers/Users.js:141 +msgid "Permission Error" +msgstr "パーミッションのエラー" + +#: client/src/forms/Credentials.js:432 +#: client/src/forms/Inventories.js:142 +#: client/src/forms/JobTemplates.js:403 +#: client/src/forms/Organizations.js:64 +#: client/src/forms/Projects.js:227 +#: client/src/forms/Workflows.js:116 +msgid "Permissions" +msgstr "パーミッション" + +#: client/src/forms/JobTemplates.js:120 +#: client/src/forms/JobTemplates.js:131 +msgid "Playbook" +msgstr "Playbook" + +#: client/src/forms/Projects.js:89 +msgid "Playbook Directory" +msgstr "Playbook ディレクトリー" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:52 +msgid "Playbook Run" +msgstr "Playbook 実行" + +#: client/src/license/license.partial.html:84 +msgid "" +"Please click the button below to visit Ansible's website to get a Tower " +"license key." +msgstr "以下のボタンをクリックし、Ansible の web サイトに移動して Tower ライセンスキーを取得します。" + +#: client/src/shared/form-generator.js:828 +#: client/src/shared/form-generator.js:953 +msgid "" +"Please enter a URL that begins with ssh, http or https. The URL may not " +"contain the '@' character." +msgstr "ssh、http または https で始まる URL を入力します。URL には「@」文字を含めることはできません。" + +#: client/src/shared/form-generator.js:1189 +msgid "Please enter a number greater than %d and less than %d." +msgstr "%d より大きく、%d より小さい数値を入力してください。" + +#: client/src/shared/form-generator.js:1191 +msgid "Please enter a number greater than %d." +msgstr "%d より大きい数値を入力してください。" + +#: client/src/shared/form-generator.js:1183 +msgid "Please enter a number." +msgstr "数値を入力してください。" + +#: client/src/login/loginModal/loginModal.partial.html:78 +msgid "Please enter a password." +msgstr "パスワードを入力してください。" + +#: client/src/login/loginModal/loginModal.partial.html:58 +msgid "Please enter a username." +msgstr "ユーザー名を入力してください。" + +#: client/src/shared/form-generator.js:818 +#: client/src/shared/form-generator.js:943 +msgid "Please enter a valid email address." +msgstr "有効なメールアドレスを入力してください。" + +#: client/src/shared/form-generator.js:1044 +#: client/src/shared/form-generator.js:813 +#: client/src/shared/form-generator.js:938 +msgid "Please enter a value." +msgstr "値を入力してください。" + +#: client/src/lists/CompletedJobs.js:13 +msgid "Please save and run a job to view" +msgstr "表示するジョブを保存し、実行してください。" + +#: client/src/notifications/notifications.list.js:15 +msgid "Please save before adding notifications" +msgstr "保存してから通知を追加します。" + +#: client/src/forms/Teams.js:69 +msgid "Please save before adding users" +msgstr "保存してからユーザーを追加します。" + +#: client/src/forms/Inventories.js:138 +#: client/src/forms/Inventories.js:91 +#: client/src/forms/JobTemplates.js:396 +#: client/src/forms/Organizations.js:57 +#: client/src/forms/Projects.js:219 +#: client/src/forms/Teams.js:110 +#: client/src/forms/Workflows.js:109 +msgid "Please save before assigning permissions" +msgstr "保存してからパーミッションを割り当てます。" + +#: client/src/forms/Users.js:122 +#: client/src/forms/Users.js:179 +msgid "Please save before assigning to organizations" +msgstr "保存してから組織に割り当てます。" + +#: client/src/forms/Users.js:148 +msgid "Please save before assigning to teams" +msgstr "保存してからチームに割り当てます。" + +#: client/src/forms/Workflows.js:185 +msgid "Please save before defining the workflow graph" +msgstr "保存してからワークフローグラフを定義します。" + +#: client/src/forms/WorkflowMaker.js:65 +msgid "Please select a Credential." +msgstr "認証情報を選択してください。" + +#: client/src/forms/JobTemplates.js:150 +msgid "" +"Please select a Machine Credential or check the Prompt on launch option." +msgstr "マシン認証情報を選択するか、または「起動プロンプト」オプションにチェックを付けます。" + +#: client/src/shared/form-generator.js:1224 +msgid "Please select a number between" +msgstr "Please select a number between" + +#: client/src/shared/form-generator.js:1220 +msgid "Please select a number." +msgstr "数値を選択してください。" + +#: client/src/shared/form-generator.js:1111 +#: client/src/shared/form-generator.js:1180 +#: client/src/shared/form-generator.js:1298 +#: client/src/shared/form-generator.js:1403 +msgid "Please select a value." +msgstr "値を選択してください。" + +#: client/src/forms/JobTemplates.js:83 +msgid "Please select an Inventory or check the Prompt on launch option." +msgstr "インベントリーを選択するか、または「起動プロンプト」オプションにチェックを付けてください。" + +#: client/src/forms/WorkflowMaker.js:86 +msgid "Please select an Inventory." +msgstr "インベントリーを選択してください。" + +#: client/src/shared/form-generator.js:1217 +msgid "Please select at least one value." +msgstr "1 つ以上の値を選択してください。" + +#: client/src/notifications/shared/type-change.service.js:27 +msgid "Port" +msgstr "ポート" + +#: client/src/forms/Credentials.js:257 +#: client/src/helpers/Credentials.js:36 +#: client/src/helpers/Credentials.js:60 +msgid "Private Key" +msgstr "秘密鍵" + +#: client/src/forms/Credentials.js:264 +msgid "Private Key Passphrase" +msgstr "秘密鍵のパスフレーズ" + +#: client/src/forms/Credentials.js:279 +#: client/src/forms/Credentials.js:283 +msgid "Privilege Escalation" +msgstr "権限昇格" + +#: client/src/helpers/Credentials.js:90 +msgid "Privilege Escalation Password" +msgstr "権限昇格のパスワード" + +#: client/src/helpers/Credentials.js:89 +msgid "Privilege Escalation Username" +msgstr "権限昇格のユーザー名" + +#: client/src/forms/JobTemplates.js:114 +#: client/src/forms/JobTemplates.js:97 +#: client/src/helpers/Credentials.js:103 +msgid "Project" +msgstr "プロジェクト" + +#: client/src/helpers/Credentials.js:132 +msgid "Project (Tenant Name)" +msgstr "プロジェクト (テナント名)" + +#: client/src/forms/Projects.js:75 +#: client/src/forms/Projects.js:83 +msgid "Project Base Path" +msgstr "プロジェクトのベースパス" + +#: client/src/forms/Credentials.js:363 +msgid "Project Name" +msgstr "プロジェクト名" + +#: client/src/forms/Projects.js:100 +msgid "Project Path" +msgstr "プロジェクトパス" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:66 +msgid "Project Sync Failures" +msgstr "プロジェクトの同期の失敗" + +#: client/src/controllers/Projects.js:134 +msgid "Project lookup failed. GET returned:" +msgstr "プロジェクトの検索に失敗しました。GET で以下が返されました:" + +#: client/src/dashboard/counts/dashboard-counts.directive.js:61 +#: client/src/lists/Projects.js:16 +#: client/src/lists/Projects.js:17 +msgid "Projects" +msgstr "プロジェクト" + +#: client/src/forms/JobTemplates.js:159 +#: client/src/forms/JobTemplates.js:230 +#: client/src/forms/JobTemplates.js:261 +#: client/src/forms/JobTemplates.js:279 +#: client/src/forms/JobTemplates.js:369 +#: client/src/forms/JobTemplates.js:68 +#: client/src/forms/JobTemplates.js:92 +msgid "Prompt on launch" +msgstr "起動プロンプト" + +#: client/src/forms/JobTemplates.js:253 +#: client/src/forms/JobTemplates.js:271 +#: client/src/forms/WorkflowMaker.js:139 +#: client/src/forms/WorkflowMaker.js:154 +msgid "Provide a comma separated list of tags." +msgstr "カンマ区切りのタグの一覧を指定してください。" + +#: client/src/forms/JobTemplates.js:221 +#: client/src/forms/WorkflowMaker.js:123 +msgid "" +"Provide a host pattern to further constrain the list of hosts that will be " +"managed or affected by the playbook. Multiple patterns can be separated by " +"%s %s or %s" +msgstr "" +"Playbook によって管理されるか、または影響されるホストの一覧をさらに制限するためのホストのパターンを指定してください。複数のパターンは %s " +"%s または %s で区切ることができます。" + +#: client/src/forms/JobTemplates.js:313 +#: client/src/forms/JobTemplates.js:321 +msgid "Provisioning Callback URL" +msgstr "プロビジョニングコールバック URL" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:107 +msgid "RADIUS" +msgstr "RADIUS" + +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:4 +msgid "RECENT JOB RUNS" +msgstr "最近のジョブ実行" + +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:42 +msgid "RECENTLY RUN JOBS" +msgstr "最近実行されたジョブ" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:4 +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:52 +msgid "RECENTLY USED JOB TEMPLATES" +msgstr "最近使用されたジョブテンプレート" + +#: client/src/lists/Projects.js:76 +#: client/src/partials/jobs.html:15 +#: client/src/portal-mode/portal-mode-jobs.partial.html:12 +msgid "REFRESH" +msgstr "更新" + +#: client/src/forms/JobTemplates.js:99 +msgid "RESET" +msgstr "リセット" + +#: client/src/helpers/Credentials.js:98 +msgid "RSA Private Key" +msgstr "RSA 秘密鍵" + +#: client/src/notifications/notificationTemplates.form.js:94 +#: client/src/notifications/notificationTemplates.form.js:99 +msgid "Recipient List" +msgstr "受信者リスト" + +#: client/src/bread-crumb/bread-crumb.partial.html:6 +#: client/src/lists/Projects.js:72 +msgid "Refresh the page" +msgstr "ページの更新" + +#: client/src/lists/CompletedJobs.js:75 +msgid "Relaunch using the same parameters" +msgstr "同一パラメーターによる起動" + +#: client/src/forms/Teams.js:144 +#: client/src/forms/Users.js:214 +msgid "Remove" +msgstr "削除" + +#: client/src/forms/Projects.js:153 +msgid "Remove any local modifications prior to performing an update." +msgstr "更新の実行前にローカルの変更を削除します。" + +#: client/src/license/license.partial.html:89 +msgid "Request License" +msgstr "ライセンスの要求" + +#: client/src/configuration/auth-form/sub-forms/auth-azure.form.js:41 +#: client/src/configuration/auth-form/sub-forms/auth-github-org.form.js:31 +#: client/src/configuration/auth-form/sub-forms/auth-github-team.form.js:31 +#: client/src/configuration/auth-form/sub-forms/auth-github.form.js:27 +#: client/src/configuration/auth-form/sub-forms/auth-google-oauth2.form.js:39 +#: client/src/configuration/auth-form/sub-forms/auth-ldap.form.js:87 +#: client/src/configuration/auth-form/sub-forms/auth-radius.form.js:32 +#: client/src/configuration/auth-form/sub-forms/auth-saml.form.js:59 +#: client/src/configuration/jobs-form/configuration-jobs.form.js:67 +#: client/src/configuration/system-form/configuration-system.form.js:41 +#: client/src/configuration/system-form/sub-forms/system-activity-stream.form.js:25 +#: client/src/configuration/system-form/sub-forms/system-logging.form.js:50 +#: client/src/configuration/system-form/sub-forms/system-misc.form.js:29 +#: client/src/configuration/ui-form/configuration-ui.form.js:35 +msgid "Reset All" +msgstr "すべてのリセット" + +#: client/src/lists/Projects.js:42 +msgid "Revision" +msgstr "リビジョン" + +#: client/src/controllers/Projects.js:657 +msgid "Revision #" +msgstr "リビジョン #" + +#: client/src/forms/Credentials.js:454 +#: client/src/forms/Inventories.js:120 +#: client/src/forms/Inventories.js:166 +#: client/src/forms/Organizations.js:88 +#: client/src/forms/Projects.js:249 +#: client/src/forms/Teams.js:137 +#: client/src/forms/Teams.js:99 +#: client/src/forms/Users.js:201 +msgid "Role" +msgstr "ロール" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:108 +msgid "SAML" +msgstr "SAML" + +#: client/src/controllers/Projects.js:657 +msgid "SCM Branch" +msgstr "SCM ブランチ" + +#: client/src/forms/Projects.js:154 +msgid "SCM Clean" +msgstr "SCM クリーニング" + +#: client/src/forms/Projects.js:130 +msgid "SCM Credential" +msgstr "SCM 認証情報" + +#: client/src/forms/Projects.js:165 +msgid "SCM Delete" +msgstr "SCM 削除" + +#: client/src/helpers/Credentials.js:93 +msgid "SCM Private Key" +msgstr "SCM 秘密鍵" + +#: client/src/forms/Projects.js:56 +msgid "SCM Type" +msgstr "SCM タイプ" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:49 +#: client/src/forms/Projects.js:175 +msgid "SCM Update" +msgstr "SCM 更新" + +#: client/src/controllers/Projects.js:176 +msgid "SCM Update Cancel" +msgstr "SCM 更新の取り消し" + +#: client/src/forms/Projects.js:145 +msgid "SCM Update Options" +msgstr "SCM 更新オプション" + +#: client/src/controllers/Projects.js:543 +#: client/src/controllers/Projects.js:57 +msgid "SCM update currently running" +msgstr "現在実行中の SCM 更新" + +#: client/src/main-menu/main-menu.partial.html:59 +msgid "SETTINGS" +msgstr "設定" + +#: client/src/login/loginModal/loginModal.partial.html:97 +msgid "SIGN IN" +msgstr "サインイン" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.partial.html:2 +msgid "SIGN IN WITH" +msgstr "サインイン:" + +#: client/src/app.js:513 +msgid "SOCKETS" +msgstr "ソケット" + +#: client/src/helpers/Credentials.js:166 +msgid "SSH Key" +msgstr "SSH キー" + +#: client/src/forms/Credentials.js:255 +msgid "SSH key description" +msgstr "SSH キーの説明" + +#: client/src/notifications/notificationTemplates.form.js:384 +msgid "SSL Connection" +msgstr "SSL 接続" + +#: client/src/forms/Credentials.js:120 +#: client/src/forms/Credentials.js:128 +msgid "STS Token" +msgstr "STS トークン" + +#: client/src/dashboard/graphs/job-status/job-status-graph.directive.js:64 +msgid "SUCCESSFUL" +msgstr "成功" + +#: client/src/helpers/Credentials.js:149 +msgid "Satellite 6 Host" +msgstr "Satellite 6 ホスト" + +#: client/src/shared/form-generator.js:1687 +msgid "Save" +msgstr "保存" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:81 +#: client/src/configuration/configuration.controller.js:181 +#: client/src/configuration/configuration.controller.js:240 +#: client/src/configuration/system-form/configuration-system.controller.js:60 +msgid "Save changes" +msgstr "変更の保存" + +#: client/src/license/license.partial.html:122 +msgid "Save successful!" +msgstr "正常に保存が実行されました!" + +#: client/src/lists/Templates.js:92 +msgid "Schedule" +msgstr "スケジュール" + +#: client/src/management-jobs/card/card.partial.html:26 +msgid "Schedule Management Job" +msgstr "管理ジョブのスケジュール" + +#: client/src/controllers/Projects.js:49 +msgid "Schedule future SCM updates" +msgstr "将来の SCM 更新のスケジュール" + +#: client/src/lists/Templates.js:95 +msgid "Schedule future job template runs" +msgstr "将来のジョブテンプレート実行のスケジュール" + +#: client/src/lists/ScheduledJobs.js:15 +msgid "Scheduled Jobs" +msgstr "スケジュール済みのジョブ" + +#: client/src/partials/jobs.html:10 +msgid "Schedules" +msgstr "スケジュール" + +#: client/src/inventory-scripts/inventory-scripts.form.js:59 +msgid "Script must begin with a hashbang sequence: i.e.... %s" +msgstr "スクリプトは hashbang シーケンスで開始する必要があります (例: .... %s)。" + +#: client/src/forms/Credentials.js:105 +msgid "Secret Key" +msgstr "シークレットキー" + +#: client/src/forms/Credentials.js:125 +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 サービスです。" + +#: client/src/shared/form-generator.js:1691 +msgid "Select" +msgstr "選択" + +#: client/src/configuration/jobs-form/configuration-jobs.controller.js:87 +#: client/src/configuration/ui-form/configuration-ui.controller.js:82 +msgid "Select commands" +msgstr "コマンドの選択" + +#: client/src/forms/Projects.js:98 +msgid "" +"Select from the list of directories found in the Project Base Path. Together " +"the base path and the playbook directory provide the full path used to " +"locate playbooks." +msgstr "" +"プロジェクトのベースパスにあるデイレクトリーの一覧から選択します。ベースパスと Playbook ディレクトリーは、Playbook " +"を見つけるために使用される完全なパスを提供します。" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:226 +msgid "Select group types" +msgstr "グループタイプの選択" + +#: client/src/forms/JobTemplates.js:152 +#: client/src/forms/WorkflowMaker.js:67 +msgid "" +"Select the credential you want the job to use when accessing the remote " +"hosts. Choose the credential containing the username and SSH key or " +"password that Ansible will need to log into the remote hosts." +msgstr "" +"リモートホストへのアクセス時にジョブで使用する認証情報を選択します。Ansible がリモートホストにログインするために必要なユーザー名および SSH " +"キーまたはパスワードが含まれる認証情報を選択してください。 " + +#: client/src/forms/JobTemplates.js:85 +#: client/src/forms/WorkflowMaker.js:88 +msgid "Select the inventory containing the hosts you want this job to manage." +msgstr "このジョブで管理するホストが含まれるインベントリーを選択してください。" + +#: client/src/forms/JobTemplates.js:130 +msgid "Select the playbook to be executed by this job." +msgstr "このジョブで実行される Playbook を選択してください。" + +#: client/src/forms/JobTemplates.js:113 +msgid "" +"Select the project containing the playbook you want this job to execute." +msgstr "このジョブで実行する Playbook が含まれるプロジェクトを選択してください。" + +#: client/src/configuration/system-form/configuration-system.controller.js:167 +msgid "Select types" +msgstr "タイプの選択" + +#: client/src/forms/JobTemplates.js:174 +msgid "" +"Selecting an optional cloud credential in the job template will pass along " +"the access credentials to the running playbook, allowing provisioning into " +"the cloud without manually passing parameters to the included modules." +msgstr "" +"ジョブテンプレートでオプションのクラウド認証情報を選択すると、アクセス認証情報が実行中の Playbook " +"に渡され、パラメーターを組み込みモジュールに手動で渡さなくてもクラウドへのプロビジョニングが許可されます。" + +#: client/src/notifications/notificationTemplates.form.js:83 +msgid "Sender Email" +msgstr "送信者のメール" + +#: client/src/helpers/Credentials.js:97 +msgid "Service Account Email Address" +msgstr "サービスアカウントのメールアドレス" + +#: client/src/forms/JobTemplates.js:60 +#: client/src/forms/WorkflowMaker.js:108 +msgid "" +"Setting the type to %s will execute the playbook and store any scanned " +"facts for use with Tower's System Tracking feature." +msgstr "" +"タイプを %s に設定すると Playbook が実行され、Tower のシステムトラッキング機能で使用するスキャンされたファクトが保存されます。" + +#: client/src/forms/JobTemplates.js:57 +msgid "Setting the type to %s will not execute the playbook." +msgstr "タイプを %s に設定すると Playbook は実行されません。" + +#: client/src/forms/WorkflowMaker.js:106 +msgid "" +"Setting the type to %s will not execute the playbook. Instead, %s will check " +"playbook syntax, test environment setup and report problems." +msgstr "" +"タイプを %s に設定すると Playbook は実行されません。その代わりに、%s は Playbook " +"構文、テスト環境セットアップおよびレポートの問題を検査します。" + +#: client/src/main-menu/main-menu.partial.html:147 +msgid "Settings" +msgstr "設定" + +#: client/src/shared/form-generator.js:843 +msgid "Show" +msgstr "表示" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:34 +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:45 +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:56 +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:77 +msgid "Sign in with %s" +msgstr "%s でサインイン" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:64 +msgid "Sign in with %s Organizations" +msgstr "%s 組織でサインイン" + +#: client/src/login/loginModal/thirdPartySignOn/thirdPartySignOn.service.js:62 +msgid "Sign in with %s Teams" +msgstr "%s チームでサインイン" + +#: client/src/forms/JobTemplates.js:266 +#: client/src/forms/JobTemplates.js:274 +#: client/src/forms/WorkflowMaker.js:149 +#: client/src/forms/WorkflowMaker.js:157 +msgid "Skip Tags" +msgstr "スキップタグ" + +#: client/src/forms/JobTemplates.js:272 +#: client/src/forms/WorkflowMaker.js:155 +msgid "" +"Skip tags are useful when you have a large playbook, and you want to skip " +"specific parts of a play or task." +msgstr "スキップタグは、Playbook のサイズが大きく、プレイまたはタスクの特定の部分をスキップする必要がある場合に役立ちます。" + +#: client/src/forms/Credentials.js:76 +msgid "Source Control" +msgstr "ソースコントロール" + +#: client/src/forms/Projects.js:27 +msgid "Source Details" +msgstr "ソース詳細" + +#: client/src/notifications/notificationTemplates.form.js:196 +msgid "Source Phone Number" +msgstr "発信元の電話番号" + +#: client/src/notifications/notificationTemplates.form.js:332 +msgid "Specify HTTP Headers in JSON format" +msgstr "JSON 形式での HTTP ヘッダーの指定" + +#: client/src/forms/Credentials.js:285 +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/setup-menu/setup-menu.partial.html:17 +msgid "" +"Split up your organization to associate content and control permissions for " +"groups." +msgstr "コンテンツを関連付け、グループのパーミッションを制御するために組織を分割します。" + +#: client/src/lists/PortalJobTemplates.js:42 +#: client/src/lists/Templates.js:87 +msgid "Start a job using this template" +msgstr "このテンプレートによるジョブの開始" + +#: client/src/controllers/Projects.js:48 +#: client/src/controllers/Projects.js:540 +msgid "Start an SCM update" +msgstr "SCM 更新の開始" + +#: client/src/dashboard/hosts/dashboard-hosts.list.js:49 +msgid "Status" +msgstr "ステータス" + +#: client/src/license/license.partial.html:121 +msgid "Submit" +msgstr "送信" + +#: client/src/license/license.partial.html:27 +msgid "Subscription" +msgstr "サブスクリプション" + +#: client/src/forms/Credentials.js:152 +#: client/src/forms/Credentials.js:163 +msgid "Subscription ID" +msgstr "サブスクリプション ID" + +#: client/src/forms/Credentials.js:162 +msgid "Subscription ID is an Azure construct, which is mapped to a username." +msgstr "サブスクリプション ID は、ユーザー名にマップされる Azure コンストラクトです。" + +#: client/src/notifications/notifications.list.js:38 +msgid "Success" +msgstr "成功" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:77 +msgid "Successful" +msgstr "成功" + +#: client/src/controllers/Users.js:18 +msgid "System Administrator" +msgstr "システム管理者" + +#: client/src/controllers/Users.js:17 +msgid "System Auditor" +msgstr "システム監査者" + +#: client/src/app.js:341 +msgid "TEAMS" +msgstr "チーム" + +#: client/src/main-menu/main-menu.partial.html:113 +#: client/src/main-menu/main-menu.partial.html:35 +msgid "TEMPLATES" +msgstr "テンプレート" + +#: client/src/dashboard/graphs/job-status/job-status-graph.directive.js:106 +msgid "TIME" +msgstr "時間" + +#: client/src/forms/JobTemplates.js:254 +#: client/src/forms/WorkflowMaker.js:140 +msgid "" +"Tags are useful when you have a large playbook, and you want to run a " +"specific part of a play or task." +msgstr "タグは、Playbook のサイズが大きく、プレイまたはタスクの特定の部分を実行する必要がある場合に役立ちます。" + +#: client/src/notifications/notificationTemplates.form.js:313 +msgid "Target URL" +msgstr "ターゲット URL" + +#: client/src/forms/Credentials.js:461 +#: client/src/forms/Inventories.js:126 +#: client/src/forms/Inventories.js:173 +#: client/src/forms/Organizations.js:95 +#: client/src/forms/Projects.js:255 +msgid "Team Roles" +msgstr "チームロール" + +#: client/src/forms/Users.js:155 +#: client/src/lists/Teams.js:16 +#: client/src/lists/Teams.js:17 +#: client/src/setup-menu/setup-menu.partial.html:16 +msgid "Teams" +msgstr "チーム" + +#: client/src/lists/Templates.js:16 +msgid "Template" +msgstr "テンプレート" + +#: client/src/lists/Templates.js:17 +#: client/src/lists/Templates.js:18 +msgid "Templates" +msgstr "テンプレート" + +#: client/src/forms/Credentials.js:335 +msgid "Tenant ID" +msgstr "テナント ID" + +#: client/src/notifications/notificationTemplates.list.js:65 +msgid "Test notification" +msgstr "テスト通知" + +#: client/src/shared/form-generator.js:1409 +msgid "That value was not found. Please enter or select a valid value." +msgstr "値が見つかりませんでした。有効な値を入力または選択してください。" + +#: client/src/helpers/Credentials.js:105 +msgid "" +"The Project ID is the GCE assigned identification. It is constructed as two " +"words followed by a three digit number. Such as:" +msgstr "プロジェクト ID は GCE によって割り当てられる識別情報です。これは、以下のように 2 語とそれに続く 3 桁の数字で構成されます。" + +#: client/src/controllers/Projects.js:693 +msgid "The SCM update process is running." +msgstr "SCM 更新プロセスが実行中です。" + +#: client/src/forms/Credentials.js:191 +msgid "" +"The email address assigned to the Google Compute Engine %sservice account." +msgstr "Google Compute Engine %sサービスアカウントに割り当てられたメールアドレス。" + +#: client/src/helpers/Credentials.js:141 +msgid "The host to authenticate with." +msgstr "認証するホスト。" + +#: client/src/helpers/Credentials.js:75 +msgid "The host value" +msgstr "ホスト値" + +#: client/src/forms/JobTemplates.js:208 +msgid "" +"The number of parallel or simultaneous processes to use while executing the " +"playbook. 0 signifies the default value from the %sansible configuration " +"file%s." +msgstr "" +"Playbook の実行中に使用する並列または同時プロセスの数です。0 は %sansible 設定ファイル%s のデフォルト値を表します。" + +#: client/src/helpers/Credentials.js:74 +msgid "The project value" +msgstr "プロジェクト値" + +#: client/src/controllers/Projects.js:123 +msgid "" +"The selected project is not configured for SCM. To configure for SCM, edit " +"the project and provide SCM settings, and then run an update." +msgstr "" +"選択されたプロジェクトは SCM に対して設定されていません。SCM の設定を行うには、プロジェクトを編集して SCM " +"設定を指定してから更新を実行します。" + +#: client/src/lists/PortalJobTemplates.js:20 +msgid "There are no job templates to display at this time" +msgstr "現時点で表示できるジョブテンプレートはありません" + +#: client/src/lists/PortalJobs.js:20 +msgid "There are no jobs to display at this time" +msgstr "現時点で表示できるジョブはありません" + +#: client/src/controllers/Projects.js:114 +msgid "" +"There is no SCM update information available for this project. An update has " +"not yet been completed. If you have not already done so, start an update " +"for this project." +msgstr "" +"このプロジェクトに利用できる SCM " +"更新情報はありません。更新はまだ完了していません。まだ更新を実行していない場合は、このプロジェクトの更新を開始してください。" + +#: client/src/configuration/configuration.controller.js:293 +msgid "There was an error resetting value. Returned status:" +msgstr "値のリセット中にエラーが発生しました。返されたステータス:" + +#: client/src/configuration/configuration.controller.js:424 +msgid "There was an error resetting values. Returned status:" +msgstr "値のリセット中にエラーが発生しました。返されたステータス:" + +#: client/src/helpers/Credentials.js:138 +msgid "" +"This is the tenant name. This value is usually the same as the username." +msgstr "これはテナント名です。通常、この値はユーザー名と同じです。" + +#: client/src/notifications/notifications.list.js:21 +msgid "" +"This list is populated by notification templates added from the " +"%sNotifications%s section" +msgstr "この一覧は、%s通知%s セクションで追加される通知テンプレートで事前に設定されます。" + +#: client/src/notifications/notificationTemplates.form.js:199 +msgid "This must be of the form %s." +msgstr "これは %s 形式でなければなりません。" + +#: client/src/forms/Users.js:160 +msgid "This user is not a member of any teams" +msgstr "このユーザーはいずれのチームのメンバーでもありません。" + +#: client/src/shared/form-generator.js:823 +#: client/src/shared/form-generator.js:948 +msgid "" +"This value does not match the password you entered previously. Please " +"confirm that password." +msgstr "この値は、以前に入力されたパスワードと一致しません。パスワードを確認してください。" + +#: client/src/configuration/configuration.controller.js:449 +msgid "" +"This will reset all configuration values to their factory defaults. Are you " +"sure you want to proceed?" +msgstr "これにより、すべての設定値が出荷時の設定にリセットされます。本当に続行してもよいですか?" + +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:14 +msgid "Time" +msgstr "時間" + +#: client/src/license/license.partial.html:45 +msgid "Time Remaining" +msgstr "残りの時間" + +#: client/src/forms/Projects.js:191 +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/forms/Credentials.js:126 +msgid "" +"To learn more about the IAM STS Token, refer to the %sAmazon documentation%s." +"" +msgstr "IAM STS トークンについての詳細は、%sAmazon ドキュメント%s を参照してください。" + +#: client/src/shared/form-generator.js:848 +msgid "Toggle the display of plaintext." +msgstr "プレーンテキストの表示を切り替えます。" + +#: client/src/notifications/shared/type-change.service.js:34 +#: client/src/notifications/shared/type-change.service.js:40 +msgid "Token" +msgstr "トークン" + +#: client/src/forms/Credentials.js:61 +#: client/src/forms/Credentials.js:85 +#: client/src/forms/Teams.js:132 +#: client/src/forms/Users.js:196 +#: client/src/forms/WorkflowMaker.js:34 +#: client/src/lists/CompletedJobs.js:50 +#: client/src/lists/Credentials.js:39 +#: client/src/lists/Projects.js:48 +#: client/src/lists/ScheduledJobs.js:42 +#: client/src/lists/Templates.js:31 +#: client/src/notifications/notificationTemplates.form.js:54 +#: client/src/notifications/notificationTemplates.list.js:38 +#: client/src/notifications/notifications.list.js:31 +msgid "Type" +msgstr "タイプ" + +#: client/src/forms/Credentials.js:25 +#: client/src/notifications/notificationTemplates.form.js:23 +msgid "Type Details" +msgstr "タイプの詳細" + +#: client/src/notifications/notificationTemplates.form.js:212 +#: client/src/notifications/notificationTemplates.form.js:97 +msgid "Type an option on each line." +msgstr "各行にオプションを入力します。" + +#: client/src/notifications/notificationTemplates.form.js:141 +#: client/src/notifications/notificationTemplates.form.js:158 +#: client/src/notifications/notificationTemplates.form.js:370 +msgid "Type an option on each line. The pound symbol (#) is not required." +msgstr "各行にオプションを入力します。シャープ記号 (#) は不要です。" + +#: client/src/controllers/Projects.js:402 +#: client/src/controllers/Projects.js:684 +msgid "URL popover text" +msgstr "URL ポップオーバーテキスト" + +#: client/src/login/loginModal/loginModal.partial.html:49 +msgid "USERNAME" +msgstr "ユーザー名" + +#: client/src/app.js:365 +msgid "USERS" +msgstr "ユーザー" + +#: client/src/controllers/Projects.js:220 +msgid "Update Not Found" +msgstr "更新が見つかりません" + +#: client/src/controllers/Projects.js:693 +msgid "Update in Progress" +msgstr "更新が進行中です" + +#: client/src/forms/Projects.js:172 +msgid "Update on Launch" +msgstr "起動時の更新" + +#: client/src/license/license.partial.html:71 +msgid "Upgrade" +msgstr "アップグレード" + +#: client/src/notifications/notificationTemplates.form.js:404 +msgid "Use SSL" +msgstr "SSL の使用" + +#: client/src/notifications/notificationTemplates.form.js:397 +msgid "Use TLS" +msgstr "TLS の使用" + +#: client/src/forms/Credentials.js:77 +msgid "" +"Used to check out and synchronize playbook repositories with a remote source " +"control management system such as Git, Subversion (svn), or Mercurial (hg). " +"These credentials are used by Projects." +msgstr "" +"Git、Subversion (svn)、または Mercurial (hg) などのリモートソースコントロール管理システムで Playbook " +"リポジトリーをチェックアウトし、同期するために使用されます。これらの認証情報はプロジェクトで使用されます。" + +#: client/src/forms/Credentials.js:449 +#: client/src/forms/Inventories.js:115 +#: client/src/forms/Inventories.js:161 +#: client/src/forms/Organizations.js:83 +#: client/src/forms/Projects.js:244 +#: client/src/forms/Teams.js:94 +msgid "User" +msgstr "ユーザー" + +#: client/src/forms/Users.js:94 +msgid "User Type" +msgstr "ユーザータイプ" + +#: client/src/forms/Users.js:49 +#: client/src/helpers/Credentials.js:117 +#: client/src/helpers/Credentials.js:32 +#: client/src/helpers/Credentials.js:56 +#: client/src/helpers/Credentials.js:88 +#: client/src/lists/Users.js:37 +#: client/src/notifications/notificationTemplates.form.js:64 +msgid "Username" +msgstr "ユーザー名" + +#: client/src/forms/Credentials.js:81 +msgid "" +"Usernames, passwords, and access keys for authenticating to the specified " +"cloud or infrastructure provider. These are used for dynamic inventory " +"sources and for cloud provisioning and deployment in playbook runs." +msgstr "" +"指定されたクラウドまたはインフラストラクチャープロバイダーに対する認証を行うためのユーザー名、パスワード、およびアクセスキーです。これらは動的なインベントリーソースおよび " +"Playbook 実行のクラウドプロビジョニングおよびデプロイメントに使用されます。" + +#: client/src/forms/Teams.js:75 +#: client/src/lists/Users.js:26 +#: client/src/lists/Users.js:27 +#: client/src/setup-menu/setup-menu.partial.html:10 +msgid "Users" +msgstr "ユーザー" + +#: client/src/dashboard/lists/job-templates/job-templates-list.partial.html:7 +#: client/src/dashboard/lists/jobs/jobs-list.partial.html:7 +msgid "VIEW ALL" +msgstr "すべてを表示" + +#: client/src/main-menu/main-menu.partial.html:75 +msgid "VIEW DOCUMENTATION" +msgstr "ドキュメントの表示" + +#: client/src/main-menu/main-menu.partial.html:51 +msgid "VIEW USER PAGE FOR {{ $root.current_user.username | uppercase }}" +msgstr "{{ $root.current_user.username | uppercase }} のユーザーページの表示" + +#: client/src/license/license.partial.html:10 +msgid "Valid License" +msgstr "有効なライセンス" + +#: client/src/forms/Inventories.js:55 +msgid "Variables" +msgstr "変数" + +#: client/src/forms/Credentials.js:389 +msgid "Vault Password" +msgstr "Vault パスワード" + +#: client/src/forms/JobTemplates.js:235 +#: client/src/forms/JobTemplates.js:242 +msgid "Verbosity" +msgstr "詳細" + +#: client/src/about/about.controller.js:24 +#: client/src/license/license.partial.html:15 +msgid "Version" +msgstr "バージョン" + +#: client/src/dashboard/graphs/dashboard-graphs.partial.html:58 +#: client/src/inventory-scripts/inventory-scripts.list.js:65 +#: client/src/lists/Credentials.js:80 +#: client/src/lists/Inventories.js:85 +#: client/src/lists/Teams.js:69 +#: client/src/lists/Templates.js:117 +#: client/src/lists/Users.js:78 +#: client/src/notifications/notificationTemplates.list.js:80 +msgid "View" +msgstr "表示" + +#: client/src/main-menu/main-menu.partial.html:173 +msgid "View Documentation" +msgstr "ドキュメントの表示" + +#: client/src/forms/Inventories.js:65 +msgid "View JSON examples at %s" +msgstr "JSON サンプルを %s に表示" + +#: client/src/forms/JobTemplates.js:450 +#: client/src/forms/Workflows.js:163 +#: client/src/shared/form-generator.js:1715 +msgid "View Survey" +msgstr "Survey の表示" + +#: client/src/forms/Inventories.js:66 +msgid "View YAML examples at %s" +msgstr "YAML サンプルを %s に表示" + +#: client/src/setup-menu/setup-menu.partial.html:47 +msgid "View Your License" +msgstr "ライセンスの表示" + +#: client/src/setup-menu/setup-menu.partial.html:48 +msgid "View and edit your license information." +msgstr "ライセンス情報を表示し、編集します。" + +#: client/src/lists/Credentials.js:82 +msgid "View credential" +msgstr "認証情報の表示" + +#: client/src/setup-menu/setup-menu.partial.html:60 +msgid "View information about this version of Ansible Tower." +msgstr "本バージョンの Ansible Tower 情報を表示します。" + +#: client/src/lists/Inventories.js:87 +msgid "View inventory" +msgstr "インベントリーの表示" + +#: client/src/inventory-scripts/inventory-scripts.list.js:67 +msgid "View inventory script" +msgstr "インベントリースクリプトの表示" + +#: client/src/notifications/notificationTemplates.list.js:82 +msgid "View notification" +msgstr "通知の表示" + +#: client/src/lists/Teams.js:72 +msgid "View team" +msgstr "チームの表示" + +#: client/src/lists/Templates.js:119 +msgid "View template" +msgstr "テンプレートの表示" + +#: client/src/lists/Projects.js:108 +msgid "View the project" +msgstr "プロジェクトの表示" + +#: client/src/lists/ScheduledJobs.js:73 +msgid "View the schedule" +msgstr "スケジュールの表示" + +#: client/src/lists/Users.js:81 +msgid "View user" +msgstr "ユーザーの表示" + +#: client/src/forms/Workflows.js:22 +msgid "WORKFLOW" +msgstr "ワークフロー" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:68 +#: client/src/configuration/configuration.controller.js:168 +#: client/src/configuration/configuration.controller.js:230 +#: client/src/configuration/system-form/configuration-system.controller.js:47 +msgid "Warning: Unsaved Changes" +msgstr "警告: 変更が保存されていません" + +#: client/src/login/loginModal/loginModal.partial.html:17 +msgid "Welcome to Ansible Tower!  Please sign in." +msgstr "Ansible Tower へようこそ!  サインインしてください。" + +#: client/src/license/license.partial.html:78 +msgid "" +"Welcome to Ansible Tower! Please complete the steps below to acquire a " +"license." +msgstr "Ansible Tower へようこそ! ライセンスを取得するために以下のステップを完了してください。" + +#: client/src/forms/JobTemplates.js:55 +#: client/src/forms/WorkflowMaker.js:104 +msgid "" +"When this template is submitted as a job, setting the type to %s will " +"execute the playbook, running tasks on the selected hosts." +msgstr "" +"このテンプレートがジョブとして送信される場合、タイプを %s に設定すると Playbook が実行され、選択されたホストでタスクが実行されます。" + +#: client/src/forms/Workflows.js:187 +#: client/src/shared/form-generator.js:1719 +msgid "Workflow Editor" +msgstr "ワークフローエディター" + +#: client/src/lists/Templates.js:70 +msgid "Workflow Job Template" +msgstr "ワークフロージョブテンプレート" + +#: client/src/controllers/Projects.js:468 +msgid "You do not have access to view this property" +msgstr "これを適切に表示するためのアクセス権がありません。" + +#: client/src/controllers/Projects.js:284 +msgid "You do not have permission to add a project." +msgstr "プロジェクトを追加するパーミッションがありません。" + +#: client/src/controllers/Users.js:141 +msgid "You do not have permission to add a user." +msgstr "ユーザーを追加するパーミッションがありません。" + +#: client/src/configuration/auth-form/configuration-auth.controller.js:67 +#: client/src/configuration/configuration.controller.js:167 +#: client/src/configuration/configuration.controller.js:229 +#: client/src/configuration/system-form/configuration-system.controller.js:46 +msgid "" +"You have unsaved changes. Would you like to proceed without " +"saving?" +msgstr "保存されていない変更があります。変更せずに次に進みますか?" + +#: client/src/shared/form-generator.js:960 +msgid "Your password must be %d characters long." +msgstr "パスワードの長さは %d 文字にしてください。" + +#: client/src/shared/form-generator.js:965 +msgid "Your password must contain a lowercase letter." +msgstr "パスワードには小文字を含める必要があります。" + +#: client/src/shared/form-generator.js:975 +msgid "Your password must contain a number." +msgstr "パスワードには数字を含める必要があります。" + +#: client/src/shared/form-generator.js:970 +msgid "Your password must contain an uppercase letter." +msgstr "パスワードには大文字を含める必要があります。" + +#: client/src/shared/form-generator.js:980 +msgid "Your password must contain one of the following characters: %s" +msgstr "パスワードには以下の文字のいずれかを使用する必要があります: %s" + +#: client/src/controllers/Projects.js:176 +msgid "Your request to cancel the update was submitted to the task manager." +msgstr "更新を取り消す要求がタスクマネージャーに送信されました。" + +#: client/src/login/loginModal/loginModal.partial.html:22 +msgid "Your session timed out due to inactivity. Please sign in." +msgstr "アイドル時間によりセッションがタイムアウトしました。サインインしてください。" + +#: client/src/shared/form-generator.js:1224 +msgid "and" +msgstr "and" + +#: client/src/forms/Credentials.js:139 +#: client/src/forms/Credentials.js:362 +msgid "set in helpers/credentials" +msgstr "ヘルパー/認証情報で設定" + +#: client/src/forms/Credentials.js:379 +msgid "v2 URLs%s - leave blank" +msgstr "v2 URL%s - 空白にする" + +#: client/src/forms/Credentials.js:380 +msgid "v3 default%s - set to 'default'" +msgstr "v3 デフォルト%s - 「デフォルト」に設定" + +#: client/src/forms/Credentials.js:381 +msgid "v3 multi-domain%s - your domain name" +msgstr "v3 マルチドメイン%s - ドメイン名" + diff --git a/awx/locale/ja/LC_MESSAGES/django.mo b/awx/locale/ja/LC_MESSAGES/django.mo new file mode 100644 index 0000000000..fa812f4296 Binary files /dev/null and b/awx/locale/ja/LC_MESSAGES/django.mo differ diff --git a/awx/locale/ja/LC_MESSAGES/django.po b/awx/locale/ja/LC_MESSAGES/django.po new file mode 100644 index 0000000000..34aee63799 --- /dev/null +++ b/awx/locale/ja/LC_MESSAGES/django.po @@ -0,0 +1,3984 @@ +# asasaki , 2017. #zanata +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-12-15 12:05+0530\n" +"PO-Revision-Date: 2017-01-10 04:55+0000\n" +"Last-Translator: asasaki \n" +"Language-Team: Japanese\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ja\n" +"X-Generator: Zanata 3.9.6\n" +"Plural-Forms: nplurals=1; plural=0\n" + +#: api/authentication.py:67 +msgid "Invalid token header. No credentials provided." +msgstr "無効なトークンヘッダーです。認証情報が提供されていません。" + +#: api/authentication.py:70 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "無効なトークンヘッダーです。トークン文字列にはスペースを含めることができません。" + +#: api/authentication.py:105 +msgid "User inactive or deleted" +msgstr "ユーザーが非アクティブか、または削除されています" + +#: api/authentication.py:161 +msgid "Invalid task token" +msgstr "無効なタスクトークン" + +#: api/conf.py:12 +msgid "Idle Time Force Log Out" +msgstr "アイドル時間、強制ログアウト" + +#: api/conf.py:13 +msgid "" +"Number of seconds that a user is inactive before they will need to login " +"again." +msgstr "ユーザーが再ログインするまでに非アクティブな状態になる秒数です。" + +#: api/conf.py:14 +#: api/conf.py:24 +#: api/conf.py:33 +#: sso/conf.py:124 +#: sso/conf.py:135 +#: sso/conf.py:147 +#: sso/conf.py:162 +msgid "Authentication" +msgstr "認証" + +#: api/conf.py:22 +msgid "Maximum number of simultaneous logins" +msgstr "同時ログインの最大数" + +#: api/conf.py:23 +msgid "" +"Maximum number of simultaneous logins a user may have. To disable enter -1." +msgstr "ユーザーが実行できる同時ログインの最大数です。無効にするには -1 を入力します。" + +#: api/conf.py:31 +msgid "Enable HTTP Basic Auth" +msgstr "HTTP Basic 認証の有効化" + +#: api/conf.py:32 +msgid "Enable HTTP Basic Auth for the API Browser." +msgstr "API ブラウザーの HTTP Basic 認証を有効にします。" + +#: api/generics.py:446 +msgid "\"id\" is required to disassociate" +msgstr "関連付けを解除するには 「id」が必要です" + +#: api/metadata.py:50 +msgid "Database ID for this {}." +msgstr "この{}のデータベース ID。" + +#: api/metadata.py:51 +msgid "Name of this {}." +msgstr "この{}の名前。" + +#: api/metadata.py:52 +msgid "Optional description of this {}." +msgstr "この{}のオプションの説明。" + +#: api/metadata.py:53 +msgid "Data type for this {}." +msgstr "この{}のデータタイプ。" + +#: api/metadata.py:54 +msgid "URL for this {}." +msgstr "この{}の URL。" + +#: api/metadata.py:55 +msgid "Data structure with URLs of related resources." +msgstr "関連リソースの URL のあるデータ構造。" + +#: api/metadata.py:56 +msgid "Data structure with name/description for related resources." +msgstr "関連リソースの名前/説明のあるデータ構造。" + +#: api/metadata.py:57 +msgid "Timestamp when this {} was created." +msgstr "この {} の作成時のタイムスタンプ。" + +#: api/metadata.py:58 +msgid "Timestamp when this {} was last modified." +msgstr "この {} の最終変更時のタイムスタンプ。" + +#: api/parsers.py:31 +#, python-format +msgid "JSON parse error - %s" +msgstr "JSON パースエラー: %s" + +#: api/serializers.py:248 +msgid "Playbook Run" +msgstr "Playbook 実行" + +#: api/serializers.py:249 +msgid "Command" +msgstr "コマンド" + +#: api/serializers.py:250 +msgid "SCM Update" +msgstr "SCM 更新" + +#: api/serializers.py:251 +msgid "Inventory Sync" +msgstr "インベントリーの同期" + +#: api/serializers.py:252 +msgid "Management Job" +msgstr "管理ジョブ" + +#: api/serializers.py:253 +msgid "Workflow Job" +msgstr "ワークフロージョブ" + +#: api/serializers.py:655 +#: api/serializers.py:713 +#: api/views.py:3914 +#, python-format +msgid "" +"Standard Output too large to display (%(text_size)d bytes), only download " +"supported for sizes over %(supported_size)d bytes" +msgstr "" +"標準出力が大きすぎて表示できません (%(text_size)d バイト)。サイズが %(supported_size)d " +"バイトを超える場合はダウンロードのみがサポートされます。" + +#: api/serializers.py:728 +msgid "Write-only field used to change the password." +msgstr "パスワードを変更するために使用される書き込み専用フィールド。" + +#: api/serializers.py:730 +msgid "Set if the account is managed by an external service" +msgstr "アカウントが外部サービスで管理される場合に設定されます" + +#: api/serializers.py:754 +msgid "Password required for new User." +msgstr "新規ユーザーのパスワードを入力してください。" + +#: api/serializers.py:838 +#, python-format +msgid "Unable to change %s on user managed by LDAP." +msgstr "LDAP で管理されたユーザーの %s を変更できません。" + +#: api/serializers.py:990 +msgid "Organization is missing" +msgstr "組織がありません" + +#: api/serializers.py:996 +msgid "Array of playbooks available within this project." +msgstr "このプロジェクト内で利用可能な一連の Playbook。" + +#: api/serializers.py:1178 +#, python-format +msgid "Invalid port specification: %s" +msgstr "無効なポート指定: %s" + +#: api/serializers.py:1206 +#: main/validators.py:192 +msgid "Must be valid JSON or YAML." +msgstr "有効な JSON または YAML である必要があります。" + +#: api/serializers.py:1263 +msgid "Invalid group name." +msgstr "無効なグループ名。" + +#: api/serializers.py:1338 +msgid "" +"Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python" +msgstr "スクリプトは hashbang シーケンスで開始する必要があります (例: .... #!/usr/bin/env python)" + +#: api/serializers.py:1391 +msgid "If 'source' is 'custom', 'source_script' must be provided." +msgstr "「source」が「custom」である場合、「source_script」を指定する必要があります。" + +#: api/serializers.py:1395 +msgid "" +"The 'source_script' does not belong to the same organization as the " +"inventory." +msgstr "「source_script」はインベントリーと同じ組織に属しません。" + +#: api/serializers.py:1397 +msgid "'source_script' doesn't exist." +msgstr "「source_script」は存在しません。" + +#: api/serializers.py:1756 +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 "" +"ユーザーを所有者ロールに追加するために使用される書き込み専用フィールドです。提供されている場合は、チームまたは組織のいずれも指定しないでください。作成時にのみ有効です。" + +#: api/serializers.py:1761 +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 "" +"チームを所有者ロールに追加するために使用される書き込み専用フィールドです。提供されている場合は、ユーザーまたは組織のいずれも指定しないでください。作成時にのみ有効です。" + +#: api/serializers.py:1766 +msgid "" +"Inherit permissions from organization roles. If provided on creation, do not " +"give either user or team." +msgstr "組織ロールからパーミッションを継承します。作成時に提供される場合は、ユーザーまたはチームのいずれも指定しないでください。" + +#: api/serializers.py:1782 +msgid "Missing 'user', 'team', or 'organization'." +msgstr "「user」、「team」、または「organization」がありません。" + +#: api/serializers.py:1795 +msgid "" +"Credential organization must be set and match before assigning to a team" +msgstr "認証情報の組織が設定され、一致している状態でチームに割り当てる必要があります。" + +#: api/serializers.py:1887 +msgid "This field is required." +msgstr "このフィールドは必須です。" + +#: api/serializers.py:1889 +#: api/serializers.py:1891 +msgid "Playbook not found for project." +msgstr "プロジェクトの Playbook が見つかりません。" + +#: api/serializers.py:1893 +msgid "Must select playbook for project." +msgstr "プロジェクトの Playbook を選択してください。" + +#: api/serializers.py:1957 +#: main/models/jobs.py:280 +msgid "Scan jobs must be assigned a fixed inventory." +msgstr "スキャンジョブに固定インベントリーが割り当てられている必要があります。" + +#: api/serializers.py:1959 +#: main/models/jobs.py:283 +msgid "Job types 'run' and 'check' must have assigned a project." +msgstr "ジョブタイプ「run」および「check」によりプロジェクトが割り当てられている必要があります。" + +#: api/serializers.py:1962 +msgid "Survey Enabled cannot be used with scan jobs." +msgstr "Survey Enabled はスキャンジョブで使用できません。" + +#: api/serializers.py:2024 +msgid "Invalid job template." +msgstr "無効なジョブテンプレート。" + +#: api/serializers.py:2109 +msgid "Credential not found or deleted." +msgstr "認証情報が見つからないか、または削除されました。" + +#: api/serializers.py:2111 +msgid "Job Template Project is missing or undefined." +msgstr "ジョブテンプレートプロジェクトが見つからないか、または定義されていません。" + +#: api/serializers.py:2113 +msgid "Job Template Inventory is missing or undefined." +msgstr "ジョブテンプレートインベントリーが見つからないか、または定義されていません。" + +#: api/serializers.py:2398 +#, python-format +msgid "%(job_type)s is not a valid job type. The choices are %(choices)s." +msgstr "%(job_type)s は有効なジョブタイプではありません。%(choices)s を選択できます。" + +#: api/serializers.py:2403 +msgid "Workflow job template is missing during creation." +msgstr "ワークフロージョブテンプレートが作成時に見つかりません。" + +#: api/serializers.py:2408 +#, python-format +msgid "Cannot nest a %s inside a WorkflowJobTemplate" +msgstr "ワークフロージョブテンプレート内に %s をネストできません" + +#: api/serializers.py:2646 +#, python-format +msgid "Job Template '%s' is missing or undefined." +msgstr "ジョブテンプレート「%s」が見つからない、または定義されていません。" + +#: api/serializers.py:2672 +msgid "Must be a valid JSON or YAML dictionary." +msgstr "有効な JSON または YAML 辞書でなければなりません。" + +#: api/serializers.py:2817 +msgid "" +"Missing required fields for Notification Configuration: notification_type" +msgstr "通知設定の必須フィールドがありません: notification_type" + +#: api/serializers.py:2840 +msgid "No values specified for field '{}'" +msgstr "フィールド '{}' に値が指定されていません" + +#: api/serializers.py:2845 +msgid "Missing required fields for Notification Configuration: {}." +msgstr "通知設定の必須フィールドがありません: {}。" + +#: api/serializers.py:2848 +msgid "Configuration field '{}' incorrect type, expected {}." +msgstr "設定フィールド '{}' のタイプが正しくありません。{} が予期されました。" + +#: api/serializers.py:2901 +msgid "Inventory Source must be a cloud resource." +msgstr "インベントリーソースはクラウドリソースでなければなりません。" + +#: api/serializers.py:2903 +msgid "Manual Project can not have a schedule set." +msgstr "手動プロジェクトにはスケジュールを設定できません。" + +#: api/serializers.py:2925 +msgid "" +"DTSTART required in rrule. Value should match: DTSTART:YYYYMMDDTHHMMSSZ" +msgstr "DTSTART が rrule で必要です。値は、DSTART:YYYYMMDDTHHMMSSZ に一致する必要があります。" + +#: api/serializers.py:2927 +msgid "Multiple DTSTART is not supported." +msgstr "複数の DTSTART はサポートされません。" + +#: api/serializers.py:2929 +msgid "RRULE require in rrule." +msgstr "RRULE が rrule で必要です。" + +#: api/serializers.py:2931 +msgid "Multiple RRULE is not supported." +msgstr "複数の RRULE はサポートされません。" + +#: api/serializers.py:2933 +msgid "INTERVAL required in rrule." +msgstr "INTERVAL が rrule で必要です。" + +#: api/serializers.py:2935 +msgid "TZID is not supported." +msgstr "TZID はサポートされません。" + +#: api/serializers.py:2937 +msgid "SECONDLY is not supported." +msgstr "SECONDLY はサポートされません。" + +#: api/serializers.py:2939 +msgid "Multiple BYMONTHDAYs not supported." +msgstr "複数の BYMONTHDAY はサポートされません。" + +#: api/serializers.py:2941 +msgid "Multiple BYMONTHs not supported." +msgstr "複数の BYMONTH はサポートされません。" + +#: api/serializers.py:2943 +msgid "BYDAY with numeric prefix not supported." +msgstr "数字の接頭辞のある BYDAY はサポートされません。" + +#: api/serializers.py:2945 +msgid "BYYEARDAY not supported." +msgstr "BYYEARDAY はサポートされません。" + +#: api/serializers.py:2947 +msgid "BYWEEKNO not supported." +msgstr "BYWEEKNO はサポートされません。" + +#: api/serializers.py:2951 +msgid "COUNT > 999 is unsupported." +msgstr "COUNT > 999 はサポートされません。" + +#: api/serializers.py:2955 +msgid "rrule parsing failed validation." +msgstr "rrule の構文解析で検証に失敗しました。" + +#: api/serializers.py:2973 +msgid "" +"A summary of the new and changed values when an object is created, updated, " +"or deleted" +msgstr "オブジェクトの作成、更新または削除時の新規値および変更された値の概要" + +#: api/serializers.py:2975 +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 " +"に関連付けられたか、またはその関連付けが解除されたオブジェクトタイプになります。" + +#: api/serializers.py:2978 +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 " +"が関連付けられるオブジェクトタイプになります。" + +#: api/serializers.py:2981 +msgid "The action taken with respect to the given object(s)." +msgstr "指定されたオブジェクトについて実行されたアクション。" + +#: api/serializers.py:3081 +msgid "Unable to login with provided credentials." +msgstr "提供される認証情報でログインできません。" + +#: api/serializers.py:3083 +msgid "Must include \"username\" and \"password\"." +msgstr "「username」および「password」を含める必要があります。" + +#: api/views.py:96 +msgid "Your license does not allow use of the activity stream." +msgstr "お使いのライセンスではアクティビティーストリームを使用できません。" + +#: api/views.py:106 +msgid "Your license does not permit use of system tracking." +msgstr "お使いのライセンスではシステムトラッキングを使用できません。" + +#: api/views.py:116 +msgid "Your license does not allow use of workflows." +msgstr "お使いのライセンスではワークフローを使用できません。" + +#: api/views.py:124 +#: templates/rest_framework/api.html:28 +msgid "REST API" +msgstr "REST API" + +#: api/views.py:131 +#: templates/rest_framework/api.html:4 +msgid "Ansible Tower REST API" +msgstr "Ansible Tower REST API" + +#: api/views.py:147 +msgid "Version 1" +msgstr "バージョン 1" + +#: api/views.py:198 +msgid "Ping" +msgstr "Ping" + +#: api/views.py:227 +#: conf/apps.py:12 +msgid "Configuration" +msgstr "設定" + +#: api/views.py:280 +msgid "Invalid license data" +msgstr "無効なライセンスデータ" + +#: api/views.py:282 +msgid "Missing 'eula_accepted' property" +msgstr "'eula_accepted' プロパティーがありません" + +#: api/views.py:286 +msgid "'eula_accepted' value is invalid" +msgstr "'eula_accepted' 値は無効です。" + +#: api/views.py:289 +msgid "'eula_accepted' must be True" +msgstr "'eula_accepted' は True でなければなりません" + +#: api/views.py:296 +msgid "Invalid JSON" +msgstr "無効な JSON" + +#: api/views.py:304 +msgid "Invalid License" +msgstr "無効なライセンス" + +#: api/views.py:314 +msgid "Invalid license" +msgstr "無効なライセンス" + +#: api/views.py:322 +#, python-format +msgid "Failed to remove license (%s)" +msgstr "ライセンスの削除に失敗しました (%s)" + +#: api/views.py:327 +msgid "Dashboard" +msgstr "ダッシュボード" + +#: api/views.py:433 +msgid "Dashboard Jobs Graphs" +msgstr "ダッシュボードのジョブグラフ" + +#: api/views.py:469 +#, python-format +msgid "Unknown period \"%s\"" +msgstr "不明な期間 \"%s\"" + +#: api/views.py:483 +msgid "Schedules" +msgstr "スケジュール" + +#: api/views.py:502 +msgid "Schedule Jobs List" +msgstr "スケジュールジョブの一覧" + +#: api/views.py:711 +msgid "Your Tower license only permits a single organization to exist." +msgstr "お使いの Tower ライセンスでは、単一組織のみの存在が許可されます。" + +#: api/views.py:932 +#: api/views.py:1284 +msgid "Role 'id' field is missing." +msgstr "ロール「id」フィールドがありません。" + +#: api/views.py:938 +#: api/views.py:4182 +msgid "You cannot assign an Organization role as a child role for a Team." +msgstr "組織ロールをチームの子ロールとして割り当てることができません。" + +#: api/views.py:942 +#: api/views.py:4196 +msgid "You cannot grant system-level permissions to a team." +msgstr "システムレベルのパーミッションをチームに付与できません。" + +#: api/views.py:949 +#: api/views.py:4188 +msgid "" +"You cannot grant credential access to a team when the Organization field " +"isn't set, or belongs to a different organization" +msgstr "組織フィールドが設定されていないか、または別の組織に属する場合に認証情報のアクセス権をチームに付与できません" + +#: api/views.py:1039 +msgid "Cannot delete project." +msgstr "プロジェクトを削除できません。" + +#: api/views.py:1068 +msgid "Project Schedules" +msgstr "プロジェクトのスケジュール" + +#: api/views.py:1168 +#: api/views.py:2252 +#: api/views.py:3225 +msgid "Cannot delete job resource when associated workflow job is running." +msgstr "関連付けられたワークフロージョブが実行中の場合、ジョブリソースを削除できません。" + +#: api/views.py:1244 +msgid "Me" +msgstr "自分" + +#: api/views.py:1288 +#: api/views.py:4137 +msgid "You may not perform any action with your own admin_role." +msgstr "独自の admin_role でアクションを実行することはできません。" + +#: api/views.py:1294 +#: api/views.py:4141 +msgid "You may not change the membership of a users admin_role" +msgstr "ユーザーの admin_role のメンバーシップを変更することはできません" + +#: api/views.py:1299 +#: api/views.py:4146 +msgid "" +"You cannot grant credential access to a user not in the credentials' " +"organization" +msgstr "認証情報の組織に属さないユーザーに認証情報のアクセス権を付与することはできません" + +#: api/views.py:1303 +#: api/views.py:4150 +msgid "You cannot grant private credential access to another user" +msgstr "非公開の認証情報のアクセス権を別のユーザーに付与することはできません" + +#: api/views.py:1401 +#, python-format +msgid "Cannot change %s." +msgstr "%s を変更できません。" + +#: api/views.py:1407 +msgid "Cannot delete user." +msgstr "ユーザーを削除できません。" + +#: api/views.py:1553 +msgid "Cannot delete inventory script." +msgstr "インベントリースクリプトを削除できません。" + +#: api/views.py:1788 +msgid "Fact not found." +msgstr "ファクトが見つかりませんでした。" + +#: api/views.py:2108 +msgid "Inventory Source List" +msgstr "インベントリーソース一覧" + +#: api/views.py:2136 +msgid "Cannot delete inventory source." +msgstr "インベントリーソースを削除できません。" + +#: api/views.py:2144 +msgid "Inventory Source Schedules" +msgstr "インベントリーソースのスケジュール" + +#: api/views.py:2173 +msgid "Notification Templates can only be assigned when source is one of {}." +msgstr "ソースが {} のいずれかである場合、通知テンプレートのみを割り当てることができます。" + +#: api/views.py:2380 +msgid "Job Template Schedules" +msgstr "ジョブテンプレートスケジュール" + +#: api/views.py:2399 +#: api/views.py:2409 +msgid "Your license does not allow adding surveys." +msgstr "お使いのライセンスでは Survey を追加できません。" + +#: api/views.py:2416 +msgid "'name' missing from survey spec." +msgstr "Survey の指定に「name」がありません。" + +#: api/views.py:2418 +msgid "'description' missing from survey spec." +msgstr "Survey の指定に「description」がありません。" + +#: api/views.py:2420 +msgid "'spec' missing from survey spec." +msgstr "Survey の指定に「spec」がありません。" + +#: api/views.py:2422 +msgid "'spec' must be a list of items." +msgstr "「spec」は項目の一覧にする必要があります。" + +#: api/views.py:2424 +msgid "'spec' doesn't contain any items." +msgstr "「spec」には項目が含まれません。" + +#: api/views.py:2429 +#, python-format +msgid "Survey question %s is not a json object." +msgstr "Survey の質問 %s は json オブジェクトではありません。" + +#: api/views.py:2431 +#, python-format +msgid "'type' missing from survey question %s." +msgstr "Survey の質問 %s に「type」がありません。" + +#: api/views.py:2433 +#, python-format +msgid "'question_name' missing from survey question %s." +msgstr "Survey の質問 %s に「question_name」がありません。" + +#: api/views.py:2435 +#, python-format +msgid "'variable' missing from survey question %s." +msgstr "Survey の質問 %s に「variable」がありません。" + +#: api/views.py:2437 +#, python-format +msgid "'variable' '%(item)s' duplicated in survey question %(survey)s." +msgstr "Survey の質問%(survey)s で「variable」の「%(item)s」が重複しています。" + +#: api/views.py:2442 +#, python-format +msgid "'required' missing from survey question %s." +msgstr "Survey の質問 %s に「required」がありません。" + +#: api/views.py:2641 +msgid "No matching host could be found!" +msgstr "一致するホストが見つかりませんでした!" + +#: api/views.py:2644 +msgid "Multiple hosts matched the request!" +msgstr "複数のホストが要求に一致しました!" + +#: api/views.py:2649 +msgid "Cannot start automatically, user input required!" +msgstr "自動的に開始できません。ユーザー入力が必要です!" + +#: api/views.py:2656 +msgid "Host callback job already pending." +msgstr "ホストのコールバックジョブがすでに保留中です。" + +#: api/views.py:2669 +msgid "Error starting job!" +msgstr "ジョブの開始時にエラーが発生しました!" + +#: api/views.py:2995 +msgid "Workflow Job Template Schedules" +msgstr "ワークフロージョブテンプレートのスケジュール" + +#: api/views.py:3131 +#: api/views.py:3853 +msgid "Superuser privileges needed." +msgstr "スーパーユーザー権限が必要です。" + +#: api/views.py:3161 +msgid "System Job Template Schedules" +msgstr "システムジョブテンプレートのスケジュール" + +#: api/views.py:3344 +msgid "Job Host Summaries List" +msgstr "ジョブホスト概要一覧" + +#: api/views.py:3386 +msgid "Job Event Children List" +msgstr "ジョブイベント子一覧" + +#: api/views.py:3395 +msgid "Job Event Hosts List" +msgstr "ジョブイベントホスト一覧" + +#: api/views.py:3404 +msgid "Job Events List" +msgstr "ジョブイベント一覧" + +#: api/views.py:3436 +msgid "Job Plays List" +msgstr "ジョブプレイ一覧" + +#: api/views.py:3513 +msgid "Job Play Tasks List" +msgstr "ジョブプレイタスク一覧" + +#: api/views.py:3529 +msgid "Job not found." +msgstr "ジョブが見つかりませんでした。" + +#: api/views.py:3533 +msgid "'event_id' not provided." +msgstr "「event_id」が指定されていません。" + +#: api/views.py:3537 +msgid "Parent event not found." +msgstr "親イベントが見つかりませんでした。" + +#: api/views.py:3809 +msgid "Ad Hoc Command Events List" +msgstr "アドホックコマンドイベント一覧" + +#: api/views.py:3963 +#, python-format +msgid "Error generating stdout download file: %s" +msgstr "stdout ダウンロードファイルの生成中にエラーが発生しました: %s" + +#: api/views.py:4009 +msgid "Delete not allowed while there are pending notifications" +msgstr "保留中の通知がある場合に削除は許可されません" + +#: api/views.py:4016 +msgid "NotificationTemplate Test" +msgstr "通知テンプレートテスト" + +#: api/views.py:4131 +msgid "User 'id' field is missing." +msgstr "ユーザー「id」フィールドがありません。" + +#: api/views.py:4174 +msgid "Team 'id' field is missing." +msgstr "チーム「id」フィールドがありません。" + +#: conf/conf.py:20 +msgid "Bud Frogs" +msgstr "Bud Frogs" + +#: conf/conf.py:21 +msgid "Bunny" +msgstr "Bunny" + +#: conf/conf.py:22 +msgid "Cheese" +msgstr "Cheese" + +#: conf/conf.py:23 +msgid "Daemon" +msgstr "Daemon" + +#: conf/conf.py:24 +msgid "Default Cow" +msgstr "Default Cow" + +#: conf/conf.py:25 +msgid "Dragon" +msgstr "Dragon" + +#: conf/conf.py:26 +msgid "Elephant in Snake" +msgstr "Elephant in Snake" + +#: conf/conf.py:27 +msgid "Elephant" +msgstr "Elephant" + +#: conf/conf.py:28 +msgid "Eyes" +msgstr "Eyes" + +#: conf/conf.py:29 +msgid "Hello Kitty" +msgstr "Hello Kitty" + +#: conf/conf.py:30 +msgid "Kitty" +msgstr "Kitty" + +#: conf/conf.py:31 +msgid "Luke Koala" +msgstr "Luke Koala" + +#: conf/conf.py:32 +msgid "Meow" +msgstr "Meow" + +#: conf/conf.py:33 +msgid "Milk" +msgstr "Milk" + +#: conf/conf.py:34 +msgid "Moofasa" +msgstr "Moofasa" + +#: conf/conf.py:35 +msgid "Moose" +msgstr "Moose" + +#: conf/conf.py:36 +msgid "Ren" +msgstr "Ren" + +#: conf/conf.py:37 +msgid "Sheep" +msgstr "Sheep" + +#: conf/conf.py:38 +msgid "Small Cow" +msgstr "Small Cow" + +#: conf/conf.py:39 +msgid "Stegosaurus" +msgstr "Stegosaurus" + +#: conf/conf.py:40 +msgid "Stimpy" +msgstr "Stimpy" + +#: conf/conf.py:41 +msgid "Super Milker" +msgstr "Super Milker" + +#: conf/conf.py:42 +msgid "Three Eyes" +msgstr "Three Eyes" + +#: conf/conf.py:43 +msgid "Turkey" +msgstr "Turkey" + +#: conf/conf.py:44 +msgid "Turtle" +msgstr "Turtle" + +#: conf/conf.py:45 +msgid "Tux" +msgstr "Tux" + +#: conf/conf.py:46 +msgid "Udder" +msgstr "Udder" + +#: conf/conf.py:47 +msgid "Vader Koala" +msgstr "Vader Koala" + +#: conf/conf.py:48 +msgid "Vader" +msgstr "Vader" + +#: conf/conf.py:49 +msgid "WWW" +msgstr "WWW" + +#: conf/conf.py:52 +msgid "Cow Selection" +msgstr "Cow Selection" + +#: conf/conf.py:53 +msgid "Select which cow to use with cowsay when running jobs." +msgstr "ジョブの実行時に cowsay で使用する cow を選択します。" + +#: conf/conf.py:54 +#: conf/conf.py:75 +msgid "Cows" +msgstr "Cows" + +#: conf/conf.py:73 +msgid "Example Read-Only Setting" +msgstr "読み取り専用設定の例" + +#: conf/conf.py:74 +msgid "Example setting that cannot be changed." +msgstr "変更不可能な設定例" + +#: conf/conf.py:93 +msgid "Example Setting" +msgstr "設定例" + +#: conf/conf.py:94 +msgid "Example setting which can be different for each user." +msgstr "ユーザーごとに異なる設定例" + +#: conf/conf.py:95 +#: conf/registry.py:67 +#: conf/views.py:46 +msgid "User" +msgstr "ユーザー" + +#: conf/fields.py:38 +msgid "Enter a valid URL" +msgstr "無効な URL の入力" + +#: conf/license.py:19 +msgid "Your Tower license does not allow that." +msgstr "お使いの Tower ライセンスではこれを許可しません。" + +#: conf/management/commands/migrate_to_database_settings.py:41 +msgid "Only show which settings would be commented/migrated." +msgstr "コメント/移行する設定についてのみ表示します。" + +#: conf/management/commands/migrate_to_database_settings.py:48 +msgid "" +"Skip over settings that would raise an error when commenting/migrating." +msgstr "コメント/移行時にエラーを発生させる設定をスキップします。" + +#: conf/management/commands/migrate_to_database_settings.py:55 +msgid "Skip commenting out settings in files." +msgstr "ファイル内の設定のコメント化をスキップします。" + +#: conf/management/commands/migrate_to_database_settings.py:61 +msgid "Backup existing settings files with this suffix." +msgstr "この接尾辞を持つ既存の設定ファイルをバックアップします。" + +#: conf/registry.py:55 +msgid "All" +msgstr "すべて" + +#: conf/registry.py:56 +msgid "Changed" +msgstr "変更済み" + +#: conf/registry.py:68 +msgid "User-Defaults" +msgstr "ユーザー設定" + +#: conf/views.py:38 +msgid "Setting Categories" +msgstr "設定カテゴリー" + +#: conf/views.py:61 +msgid "Setting Detail" +msgstr "設定の詳細" + +#: main/access.py:255 +#, python-format +msgid "Bad data found in related field %s." +msgstr "関連フィールド %s に不正データが見つかりました。" + +#: main/access.py:296 +msgid "License is missing." +msgstr "ライセンスが見つかりません。" + +#: main/access.py:298 +msgid "License has expired." +msgstr "ライセンスの有効期限が切れました。" + +#: main/access.py:303 +#, python-format +msgid "License count of %s instances has been reached." +msgstr "%s インスタンスのライセンス数に達しました。" + +#: main/access.py:305 +#, python-format +msgid "License count of %s instances has been exceeded." +msgstr "%s インスタンスのライセンス数を超えました。" + +#: main/access.py:307 +msgid "Host count exceeds available instances." +msgstr "ホスト数が利用可能なインスタンスの上限を上回っています。" + +#: main/access.py:311 +#, python-format +msgid "Feature %s is not enabled in the active license." +msgstr "機能 %s はアクティブなライセンスで有効にされていません。" + +#: main/access.py:313 +msgid "Features not found in active license." +msgstr "各種機能はアクティブなライセンスにありません。" + +#: main/access.py:507 +#: main/access.py:574 +#: main/access.py:694 +#: main/access.py:957 +#: main/access.py:1198 +#: main/access.py:1587 +msgid "Resource is being used by running jobs" +msgstr "リソースが実行中のジョブで使用されています" + +#: main/access.py:618 +msgid "Unable to change inventory on a host." +msgstr "ホストのインベントリーを変更できません。" + +#: main/access.py:630 +#: main/access.py:675 +msgid "Cannot associate two items from different inventories." +msgstr "異なるインベントリーの 2 つの項目を関連付けることはできません。" + +#: main/access.py:663 +msgid "Unable to change inventory on a group." +msgstr "グループのインベントリーを変更できません。" + +#: main/access.py:877 +msgid "Unable to change organization on a team." +msgstr "チームの組織を変更できません。" + +#: main/access.py:890 +msgid "The {} role cannot be assigned to a team" +msgstr "{} ロールをチームに割り当てることができません" + +#: main/access.py:892 +msgid "The admin_role for a User cannot be assigned to a team" +msgstr "ユーザーの admin_role をチームに割り当てることができません" + +#: main/apps.py:9 +msgid "Main" +msgstr "メイン" + +#: main/conf.py:17 +msgid "Enable Activity Stream" +msgstr "アクティビティーストリームの有効化" + +#: main/conf.py:18 +msgid "Enable capturing activity for the Tower activity stream." +msgstr "Tower アクティビティーストリームのアクティビティーのキャプチャーを有効にします。" + +#: main/conf.py:19 +#: main/conf.py:29 +#: main/conf.py:39 +#: main/conf.py:48 +#: main/conf.py:60 +#: main/conf.py:78 +#: main/conf.py:103 +msgid "System" +msgstr "システム" + +#: main/conf.py:27 +msgid "Enable Activity Stream for Inventory Sync" +msgstr "インベントリー同期のアクティビティティーストリームの有効化" + +#: main/conf.py:28 +msgid "" +"Enable capturing activity for the Tower activity stream when running " +"inventory sync." +msgstr "インベントリー同期の実行時に Tower アクティビティーストリームのアクティビティーのキャプチャーを有効にします。" + +#: main/conf.py:37 +msgid "All Users Visible to Organization Admins" +msgstr "組織管理者に表示されるすべてのユーザー" + +#: main/conf.py:38 +msgid "" +"Controls whether any Organization Admin can view all users, even those not " +"associated with their Organization." +msgstr "組織管理者が、それぞれの組織に関連付けられていないすべてのユーザーを閲覧できるかどうかを制御します。" + +#: main/conf.py:46 +msgid "Enable Tower Administrator Alerts" +msgstr "Tower 管理者アラートの有効化" + +#: main/conf.py:47 +msgid "" +"Allow Tower to email Admin users for system events that may require " +"attention." +msgstr "Tower から管理者ユーザーに対し、注意を要する可能性のあるシステムイベントについてのメールを送信することを許可します。" + +#: main/conf.py:57 +msgid "Base URL of the Tower host" +msgstr "Tower ホストのベース URL" + +#: main/conf.py:58 +msgid "" +"This setting is used by services like notifications to render a valid url to " +"the Tower host." +msgstr "この設定は、有効な URL を Tower ホストにレンダリングする通知などのサービスで使用されます。" + +#: main/conf.py:67 +msgid "Remote Host Headers" +msgstr "リモートホストヘッダー" + +#: main/conf.py:68 +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 " +"behind a reverse proxy.\n" +"\n" +"Note: The headers will be searched in order and the first found remote host " +"name or IP will be used.\n" +"\n" +"In the below example 8.8.8.7 would be the chosen IP address.\n" +"X-Forwarded-For: 8.8.8.7, 192.168.2.1, 127.0.0.1\n" +"Host: 127.0.0.1\n" +"REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST']" +msgstr "" +"リモートホスト名または IP を判別するために検索する HTTP " +"ヘッダーおよびメタキーです。リバースプロキシーの後ろの場合は、\"HTTP_X_FORWARDED_FOR\" のように項目をこの一覧に追加します。\n" +"\n" +"注: ヘッダーが順番に検索され、最初に検出されるリモートホスト名または IP が使用されます。\n" +"\n" +"以下の例では、8.8.8.7 が選択された IP アドレスになります。\n" +"X-Forwarded-For: 8.8.8.7, 192.168.2.1, 127.0.0.1\n" +"Host: 127.0.0.1\n" +"REMOTE_HOST_HEADERS = ['HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST']" + +#: main/conf.py:99 +msgid "Tower License" +msgstr "Tower ライセンス" + +#: main/conf.py:100 +msgid "" +"The license controls which features and functionality are enabled in Tower. " +"Use /api/v1/config/ to update or change the license." +msgstr "" +"ライセンスによって、Tower で有効にされる特長および機能が制御されます。ライセンスを更新または変更するには、/api/v1/config/ " +"を使用します。" + +#: main/conf.py:110 +msgid "Ansible Modules Allowed for Ad Hoc Jobs" +msgstr "アドホックジョブで許可される Ansible モジュール" + +#: main/conf.py:111 +msgid "List of modules allowed to be used by ad-hoc jobs." +msgstr "アドホックジョブで使用できるモジュール一覧。" + +#: main/conf.py:112 +#: main/conf.py:121 +#: main/conf.py:130 +#: main/conf.py:139 +#: main/conf.py:148 +#: main/conf.py:158 +#: main/conf.py:168 +#: main/conf.py:178 +#: main/conf.py:187 +#: main/conf.py:199 +#: main/conf.py:211 +#: main/conf.py:223 +msgid "Jobs" +msgstr "ジョブ" + +#: main/conf.py:119 +msgid "Enable job isolation" +msgstr "ジョブの分離の有効化" + +#: main/conf.py:120 +msgid "" +"Isolates an Ansible job from protected parts of the Tower system to prevent " +"exposing sensitive information." +msgstr "機密情報の公開を防ぐために Tower システムの保護された部分から Ansible ジョブを分離します。" + +#: main/conf.py:128 +msgid "Job isolation execution path" +msgstr "ジョブ分離の実行パス" + +#: main/conf.py:129 +msgid "" +"Create temporary working directories for isolated jobs in this location." +msgstr "この場所に分離されたジョブの一時作業ディレクトリーを作成します。" + +#: main/conf.py:137 +msgid "Paths to hide from isolated jobs" +msgstr "分離されたジョブから非表示にするパス" + +#: main/conf.py:138 +msgid "Additional paths to hide from isolated processes." +msgstr "分離されたプロセスから非表示にする追加パス。" + +#: main/conf.py:146 +msgid "Paths to expose to isolated jobs" +msgstr "分離されたジョブに公開するパス" + +#: main/conf.py:147 +msgid "" +"Whitelist of paths that would otherwise be hidden to expose to isolated jobs." +"" +msgstr "分離されたジョブに公開されないように非表示にされることがあるパスのホワイトリスト。" + +#: main/conf.py:156 +msgid "Standard Output Maximum Display Size" +msgstr "標準出力の最大表示サイズ" + +#: main/conf.py:157 +msgid "" +"Maximum Size of Standard Output in bytes to display before requiring the " +"output be downloaded." +msgstr "出力のダウンロードを要求する前に表示される標準出力の最大サイズ (バイト単位)。" + +#: main/conf.py:166 +msgid "Job Event Standard Output Maximum Display Size" +msgstr "ジョブイベントの標準出力の最大表示サイズ" + +#: main/conf.py:167 +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` は切り捨てが実行されると `…` " +"で終了します。" + +#: main/conf.py:176 +msgid "Maximum Scheduled Jobs" +msgstr "スケジュール済みジョブの最大数" + +#: main/conf.py:177 +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 "スケジュールからの起動時に実行を待機している同じジョブテンプレートの最大数です (これ以上作成されることはありません)。" + +#: main/conf.py:185 +msgid "Ansible Callback Plugins" +msgstr "Ansible コールバックプラグイン" + +#: main/conf.py:186 +msgid "" +"List of paths to search for extra callback plugins to be used when running " +"jobs." +msgstr "ジョブの実行時に使用される追加のコールバックプラグインについて検索するパスの一覧。" + +#: main/conf.py:196 +msgid "Default Job Timeout" +msgstr "デフォルトのジョブタイムアウト" + +#: main/conf.py:197 +msgid "" +"Maximum time 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 " +"が使用されている場合はタイムアウトを設定できないことを示します。個別のジョブテンプレートに設定されるタイムアウトはこれを上書きします。" + +#: main/conf.py:208 +msgid "Default Inventory Update Timeout" +msgstr "デフォルトのインベントリー更新タイムアウト" + +#: main/conf.py:209 +msgid "" +"Maximum time 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 " +"が設定されている場合はタイムアウトを設定できないことを示します。個別のインベントリーソースに設定されるタイムアウトはこれを上書きします。" + +#: main/conf.py:220 +msgid "Default Project Update Timeout" +msgstr "デフォルトのプロジェクト更新タイムアウト" + +#: main/conf.py:221 +msgid "" +"Maximum time 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 " +"が設定されている場合はタイムアウトを設定できないことを示します。個別のプロジェクトに設定されるタイムアウトはこれを上書きします。" + +#: main/conf.py:231 +msgid "Logging Aggregator Receiving Host" +msgstr "ログアグリゲーター受信ホスト" + +#: main/conf.py:232 +msgid "External host maintain a log collector to send logs to" +msgstr "外部ホストがログの送信先のログコレクターを維持します" + +#: main/conf.py:233 +#: main/conf.py:242 +#: main/conf.py:252 +#: main/conf.py:261 +#: main/conf.py:271 +#: main/conf.py:286 +#: main/conf.py:297 +#: main/conf.py:306 +msgid "Logging" +msgstr "ロギング" + +#: main/conf.py:240 +msgid "Logging Aggregator Receiving Port" +msgstr "ログアグリゲーター受信ポート" + +#: main/conf.py:241 +msgid "Port that the log collector is listening on" +msgstr "ログコレクターがリッスンしているポート" + +#: main/conf.py:250 +msgid "Logging Aggregator Type: Logstash, Loggly, Datadog, etc" +msgstr "ログアグリゲーターのタイプ: Logstash、Loggly、Datadog など" + +#: main/conf.py:251 +msgid "The type of log aggregator service to format messages for" +msgstr "メッセージのフォーマットに使用するログアグリゲーターサービスのタイプ" + +#: main/conf.py:259 +msgid "Logging Aggregator Username to Authenticate With" +msgstr "認証に使用するログアグリゲーターのユーザー名" + +#: main/conf.py:260 +msgid "Username for Logstash or others (basic auth)" +msgstr "Logstash その他のユーザー名 (基本認証)" + +#: main/conf.py:269 +msgid "Logging Aggregator Password to Authenticate With" +msgstr "認証に使用するログアグリゲーターのパスワード" + +#: main/conf.py:270 +msgid "Password for Logstash or others (basic auth)" +msgstr "Logstash その他のパスワード (基本認証)" + +#: main/conf.py:278 +msgid "Loggers to send data to the log aggregator from" +msgstr "ログアグリゲーターにデータを送信するロガー" + +#: main/conf.py:279 +msgid "" +"List of loggers that will send HTTP logs to the collector, these can include " +"any or all of: \n" +"activity_stream - logs duplicate to records entered in activity stream\n" +"job_events - callback data from Ansible job events\n" +"system_tracking - data generated from scan jobs\n" +"Sending generic Tower logs must be configured through local_settings." +"pyinstead of this mechanism." +msgstr "" +"HTTP ログをコレクターに送信するロガーの一覧です。これらには以下のいずれか、またはすべてが含まれます。\n" +"activity_stream - アクティビティーストリームに入力されるレコードへのログの複製\n" +"job_events - Ansible ジョブイベントからのコールバックデータ\n" +"system_tracking - スキャンジョブから生成されるデータ\n" +"汎用 Tower ログの送信は、このメカニズムの local_settings.pyinstead で設定する必要があります。" + +#: main/conf.py:293 +msgid "" +"Flag denoting to send individual messages for each fact in system tracking" +msgstr "システムトラッキングの各ファクトについての個別メッセージを送信することを示すフラグ" + +#: main/conf.py:294 +msgid "" +"If not set, the data from system tracking will be sent inside of a single " +"dictionary, but if set, separate requests will be sent for each package, " +"service, etc. that is found in the scan." +msgstr "" +"設定されていない場合、システムトラッキングのデータが単一辞書内に送信されますが、設定されている場合は、スキャンで見つかる各パッケージ、サービスなどについての個別の要求が送信されます。" + +#: main/conf.py:304 +msgid "Flag denoting whether to use the external logger system" +msgstr "外部ロガーシステムを使用するかどうかを示すフラグ" + +#: main/conf.py:305 +msgid "" +"If not set, only normal settings data will be used to configure loggers." +msgstr "設定されていない場合、標準設定データのみがロガーを設定するために使用されます。" + +#: main/models/activity_stream.py:22 +msgid "Entity Created" +msgstr "エンティティーの作成" + +#: main/models/activity_stream.py:23 +msgid "Entity Updated" +msgstr "エンティティーの更新" + +#: main/models/activity_stream.py:24 +msgid "Entity Deleted" +msgstr "エンティティーの削除" + +#: main/models/activity_stream.py:25 +msgid "Entity Associated with another Entity" +msgstr "エンティティーの別のエンティティーへの関連付け" + +#: main/models/activity_stream.py:26 +msgid "Entity was Disassociated with another Entity" +msgstr "エンティティーの別のエンティティーとの関連付けの解除" + +#: main/models/ad_hoc_commands.py:96 +msgid "No valid inventory." +msgstr "有効なインベントリーはありません。" + +#: main/models/ad_hoc_commands.py:103 +#: main/models/jobs.py:163 +msgid "You must provide a machine / SSH credential." +msgstr "マシン/SSH 認証情報を入力してください。" + +#: main/models/ad_hoc_commands.py:114 +#: main/models/ad_hoc_commands.py:122 +msgid "Invalid type for ad hoc command" +msgstr "アドホックコマンドの無効なタイプ" + +#: main/models/ad_hoc_commands.py:117 +msgid "Unsupported module for ad hoc commands." +msgstr "アドホックコマンドのサポートされていないモジュール。" + +#: main/models/ad_hoc_commands.py:125 +#, python-format +msgid "No argument passed to %s module." +msgstr "%s モジュールに渡される引数はありません。" + +#: main/models/ad_hoc_commands.py:220 +#: main/models/jobs.py:767 +msgid "Host Failed" +msgstr "ホストの失敗" + +#: main/models/ad_hoc_commands.py:221 +#: main/models/jobs.py:768 +msgid "Host OK" +msgstr "ホスト OK" + +#: main/models/ad_hoc_commands.py:222 +#: main/models/jobs.py:771 +msgid "Host Unreachable" +msgstr "ホストに到達できません" + +#: main/models/ad_hoc_commands.py:227 +#: main/models/jobs.py:770 +msgid "Host Skipped" +msgstr "ホストがスキップされました" + +#: main/models/ad_hoc_commands.py:237 +#: main/models/jobs.py:798 +msgid "Debug" +msgstr "デバッグ" + +#: main/models/ad_hoc_commands.py:238 +#: main/models/jobs.py:799 +msgid "Verbose" +msgstr "詳細" + +#: main/models/ad_hoc_commands.py:239 +#: main/models/jobs.py:800 +msgid "Deprecated" +msgstr "非推奨" + +#: main/models/ad_hoc_commands.py:240 +#: main/models/jobs.py:801 +msgid "Warning" +msgstr "警告" + +#: main/models/ad_hoc_commands.py:241 +#: main/models/jobs.py:802 +msgid "System Warning" +msgstr "システム警告" + +#: main/models/ad_hoc_commands.py:242 +#: main/models/jobs.py:803 +#: main/models/unified_jobs.py:62 +msgid "Error" +msgstr "エラー" + +#: main/models/base.py:45 +#: main/models/base.py:51 +#: main/models/base.py:56 +msgid "Run" +msgstr "実行" + +#: main/models/base.py:46 +#: main/models/base.py:52 +#: main/models/base.py:57 +msgid "Check" +msgstr "チェック" + +#: main/models/base.py:47 +msgid "Scan" +msgstr "スキャン" + +#: main/models/base.py:61 +msgid "Read Inventory" +msgstr "インベントリーの読み取り" + +#: main/models/base.py:62 +msgid "Edit Inventory" +msgstr "インベントリーの編集" + +#: main/models/base.py:63 +msgid "Administrate Inventory" +msgstr "インベントリーの管理" + +#: main/models/base.py:64 +msgid "Deploy To Inventory" +msgstr "インベントリーへのデプロイ" + +#: main/models/base.py:65 +msgid "Deploy To Inventory (Dry Run)" +msgstr "インベントリーへのデプロイ (ドライラン)" + +#: main/models/base.py:66 +msgid "Scan an Inventory" +msgstr "インベントリーのスキャン" + +#: main/models/base.py:67 +msgid "Create a Job Template" +msgstr "ジョブテンプレートの作成" + +#: main/models/credential.py:33 +msgid "Machine" +msgstr "マシン" + +#: main/models/credential.py:34 +msgid "Network" +msgstr "ネットワーク" + +#: main/models/credential.py:35 +msgid "Source Control" +msgstr "ソースコントロール" + +#: main/models/credential.py:36 +msgid "Amazon Web Services" +msgstr "Amazon Web サービス" + +#: main/models/credential.py:37 +msgid "Rackspace" +msgstr "Rackspace" + +#: main/models/credential.py:38 +#: main/models/inventory.py:713 +msgid "VMware vCenter" +msgstr "VMware vCenter" + +#: main/models/credential.py:39 +#: main/models/inventory.py:714 +msgid "Red Hat Satellite 6" +msgstr "Red Hat Satellite 6" + +#: main/models/credential.py:40 +#: main/models/inventory.py:715 +msgid "Red Hat CloudForms" +msgstr "Red Hat CloudForms" + +#: main/models/credential.py:41 +#: main/models/inventory.py:710 +msgid "Google Compute Engine" +msgstr "Google Compute Engine" + +#: main/models/credential.py:42 +#: main/models/inventory.py:711 +msgid "Microsoft Azure Classic (deprecated)" +msgstr "Microsoft Azure Classic (非推奨)" + +#: main/models/credential.py:43 +#: main/models/inventory.py:712 +msgid "Microsoft Azure Resource Manager" +msgstr "Microsoft Azure Resource Manager" + +#: main/models/credential.py:44 +#: main/models/inventory.py:716 +msgid "OpenStack" +msgstr "OpenStack" + +#: main/models/credential.py:48 +msgid "None" +msgstr "なし" + +#: main/models/credential.py:49 +msgid "Sudo" +msgstr "Sudo" + +#: main/models/credential.py:50 +msgid "Su" +msgstr "Su" + +#: main/models/credential.py:51 +msgid "Pbrun" +msgstr "Pbrun" + +#: main/models/credential.py:52 +msgid "Pfexec" +msgstr "Pfexec" + +#: main/models/credential.py:101 +msgid "Host" +msgstr "ホスト" + +#: main/models/credential.py:102 +msgid "The hostname or IP address to use." +msgstr "使用するホスト名または IP アドレス。" + +#: main/models/credential.py:108 +msgid "Username" +msgstr "ユーザー名" + +#: main/models/credential.py:109 +msgid "Username for this credential." +msgstr "この認証情報のユーザー名。" + +#: main/models/credential.py:115 +msgid "Password" +msgstr "パスワード" + +#: main/models/credential.py:116 +msgid "" +"Password for this credential (or \"ASK\" to prompt the user for machine " +"credentials)." +msgstr "この認証情報のパスワード (またはマシンの認証情報を求めるプロンプトを出すには 「ASK」)。" + +#: main/models/credential.py:123 +msgid "Security Token" +msgstr "セキュリティートークン" + +#: main/models/credential.py:124 +msgid "Security Token for this credential" +msgstr "この認証情報のセキュリティートークン" + +#: main/models/credential.py:130 +msgid "Project" +msgstr "プロジェクト" + +#: main/models/credential.py:131 +msgid "The identifier for the project." +msgstr "プロジェクトの識別子。" + +#: main/models/credential.py:137 +msgid "Domain" +msgstr "ドメイン" + +#: main/models/credential.py:138 +msgid "The identifier for the domain." +msgstr "ドメインの識別子。" + +#: main/models/credential.py:143 +msgid "SSH private key" +msgstr "SSH 秘密鍵" + +#: main/models/credential.py:144 +msgid "RSA or DSA private key to be used instead of password." +msgstr "パスワードの代わりに使用される RSA または DSA 秘密鍵。" + +#: main/models/credential.py:150 +msgid "SSH key unlock" +msgstr "SSH キーのロック解除" + +#: main/models/credential.py:151 +msgid "" +"Passphrase to unlock SSH private key if encrypted (or \"ASK\" to prompt the " +"user for machine credentials)." +msgstr "" +"暗号化されている場合は SSH 秘密鍵のロックを解除するためのパスフレーズ (またはマシンの認証情報を求めるプロンプトを出すには「ASK」)。" + +#: main/models/credential.py:159 +msgid "Privilege escalation method." +msgstr "権限昇格メソッド。" + +#: main/models/credential.py:165 +msgid "Privilege escalation username." +msgstr "権限昇格ユーザー名。" + +#: main/models/credential.py:171 +msgid "Password for privilege escalation method." +msgstr "権限昇格メソッドのパスワード。" + +#: main/models/credential.py:177 +msgid "Vault password (or \"ASK\" to prompt the user)." +msgstr "Vault パスワード (またはユーザーにプロンプトを出すには「ASK」)。" + +#: main/models/credential.py:181 +msgid "Whether to use the authorize mechanism." +msgstr "承認メカニズムを使用するかどうか。" + +#: main/models/credential.py:187 +msgid "Password used by the authorize mechanism." +msgstr "承認メカニズムで使用されるパスワード。" + +#: main/models/credential.py:193 +msgid "Client Id or Application Id for the credential" +msgstr "認証情報のクライアント ID またはアプリケーション ID" + +#: main/models/credential.py:199 +msgid "Secret Token for this credential" +msgstr "この認証情報のシークレットトークン" + +#: main/models/credential.py:205 +msgid "Subscription identifier for this credential" +msgstr "この認証情報のサブスクリプション識別子" + +#: main/models/credential.py:211 +msgid "Tenant identifier for this credential" +msgstr "この認証情報のテナント識別子" + +#: main/models/credential.py:281 +msgid "Host required for VMware credential." +msgstr "VMware 認証情報に必要なホスト。" + +#: main/models/credential.py:283 +msgid "Host required for OpenStack credential." +msgstr "OpenStack 認証情報に必要なホスト。" + +#: main/models/credential.py:292 +msgid "Access key required for AWS credential." +msgstr "AWS 認証情報に必要なアクセスキー。" + +#: main/models/credential.py:294 +msgid "Username required for Rackspace credential." +msgstr "Rackspace 認証情報に必要なユーザー名。" + +#: main/models/credential.py:297 +msgid "Username required for VMware credential." +msgstr "VMware 認証情報に必要なユーザー名。" + +#: main/models/credential.py:299 +msgid "Username required for OpenStack credential." +msgstr "OpenStack 認証情報に必要なユーザー名。" + +#: main/models/credential.py:305 +msgid "Secret key required for AWS credential." +msgstr "AWS 認証情報に必要なシークレットキー。" + +#: main/models/credential.py:307 +msgid "API key required for Rackspace credential." +msgstr "Rackspace 認証情報に必要な API キー。" + +#: main/models/credential.py:309 +msgid "Password required for VMware credential." +msgstr "VMware 認証情報に必要なパスワード。" + +#: main/models/credential.py:311 +msgid "Password or API key required for OpenStack credential." +msgstr "OpenStack 認証情報に必要なパスワードまたは API キー。" + +#: main/models/credential.py:317 +msgid "Project name required for OpenStack credential." +msgstr "OpenStack 認証情報に必要なプロジェクト名。" + +#: main/models/credential.py:344 +msgid "SSH key unlock must be set when SSH key is encrypted." +msgstr "SSH キーの暗号化時に SSH キーのロック解除を設定する必要があります。" + +#: main/models/credential.py:350 +msgid "Credential cannot be assigned to both a user and team." +msgstr "認証情報はユーザーとチームの両方に割り当てることができません。" + +#: main/models/fact.py:21 +msgid "Host for the facts that the fact scan captured." +msgstr "ファクトスキャンがキャプチャーしたファクトのホスト。" + +#: main/models/fact.py:26 +msgid "Date and time of the corresponding fact scan gathering time." +msgstr "対応するファクトスキャン収集時間の日時。" + +#: main/models/fact.py:29 +msgid "" +"Arbitrary JSON structure of module facts captured at timestamp for a single " +"host." +msgstr "単一ホストのタイムスタンプでキャプチャーされるモジュールファクトの任意の JSON 構造。" + +#: main/models/inventory.py:45 +msgid "inventories" +msgstr "インベントリー" + +#: main/models/inventory.py:52 +msgid "Organization containing this inventory." +msgstr "このインベントリーを含む組織。" + +#: main/models/inventory.py:58 +msgid "Inventory variables in JSON or YAML format." +msgstr "JSON または YAML 形式のインベントリー変数。" + +#: main/models/inventory.py:63 +msgid "Flag indicating whether any hosts in this inventory have failed." +msgstr "このインベントリーのホストが失敗したかどうかを示すフラグ。" + +#: main/models/inventory.py:68 +msgid "Total number of hosts in this inventory." +msgstr "このインべントリー内のホストの合計数。" + +#: main/models/inventory.py:73 +msgid "Number of hosts in this inventory with active failures." +msgstr "アクティブなエラーのあるこのインベントリー内のホストの数。" + +#: main/models/inventory.py:78 +msgid "Total number of groups in this inventory." +msgstr "このインべントリー内のグループの合計数。" + +#: main/models/inventory.py:83 +msgid "Number of groups in this inventory with active failures." +msgstr "アクティブなエラーのあるこのインベントリー内のグループの数。" + +#: main/models/inventory.py:88 +msgid "" +"Flag indicating whether this inventory has any external inventory sources." +msgstr "このインベントリーに外部のインベントリーソースがあるかどうかを示すフラグ。" + +#: main/models/inventory.py:93 +msgid "" +"Total number of external inventory sources configured within this inventory." +msgstr "このインベントリー内で設定される外部インベントリーソースの合計数。" + +#: main/models/inventory.py:98 +msgid "Number of external inventory sources in this inventory with failures." +msgstr "エラーのあるこのインベントリー内の外部インベントリーソースの数。" + +#: main/models/inventory.py:339 +msgid "Is this host online and available for running jobs?" +msgstr "このホストはオンラインで、ジョブを実行するために利用できますか?" + +#: main/models/inventory.py:345 +msgid "" +"The value used by the remote inventory source to uniquely identify the host" +msgstr "ホストを一意に識別するためにリモートインベントリーソースで使用される値" + +#: main/models/inventory.py:350 +msgid "Host variables in JSON or YAML format." +msgstr "JSON または YAML 形式のホスト変数。" + +#: main/models/inventory.py:372 +msgid "Flag indicating whether the last job failed for this host." +msgstr "このホストの最後のジョブが失敗したかどうかを示すフラグ。" + +#: main/models/inventory.py:377 +msgid "" +"Flag indicating whether this host was created/updated from any external " +"inventory sources." +msgstr "このホストが外部インベントリーソースから作成/更新されたかどうかを示すフラグ。" + +#: main/models/inventory.py:383 +msgid "Inventory source(s) that created or modified this host." +msgstr "このホストを作成または変更したインベントリーソース。" + +#: main/models/inventory.py:474 +msgid "Group variables in JSON or YAML format." +msgstr "JSON または YAML 形式のグループ変数。" + +#: main/models/inventory.py:480 +msgid "Hosts associated directly with this group." +msgstr "このグループに直接関連付けられたホスト。" + +#: main/models/inventory.py:485 +msgid "Total number of hosts directly or indirectly in this group." +msgstr "このグループに直接的または間接的に属するホストの合計数。" + +#: main/models/inventory.py:490 +msgid "Flag indicating whether this group has any hosts with active failures." +msgstr "このグループにアクティブなエラーのあるホストがあるかどうかを示すフラグ。" + +#: main/models/inventory.py:495 +msgid "Number of hosts in this group with active failures." +msgstr "アクティブなエラーのあるこのグループ内のホストの数。" + +#: main/models/inventory.py:500 +msgid "Total number of child groups contained within this group." +msgstr "このグループに含まれる子グループの合計数。" + +#: main/models/inventory.py:505 +msgid "Number of child groups within this group that have active failures." +msgstr "アクティブなエラーのあるこのグループ内の子グループの数。" + +#: main/models/inventory.py:510 +msgid "" +"Flag indicating whether this group was created/updated from any external " +"inventory sources." +msgstr "このグループが外部インベントリーソースから作成/更新されたかどうかを示すフラグ。" + +#: main/models/inventory.py:516 +msgid "Inventory source(s) that created or modified this group." +msgstr "このグループを作成または変更したインベントリーソース。" + +#: main/models/inventory.py:706 +#: main/models/projects.py:42 +#: main/models/unified_jobs.py:386 +msgid "Manual" +msgstr "手動" + +#: main/models/inventory.py:707 +msgid "Local File, Directory or Script" +msgstr "ローカルファイル、ディレクトリーまたはスクリプト" + +#: main/models/inventory.py:708 +msgid "Rackspace Cloud Servers" +msgstr "Rackspace クラウドサーバー" + +#: main/models/inventory.py:709 +msgid "Amazon EC2" +msgstr "Amazon EC2" + +#: main/models/inventory.py:717 +msgid "Custom Script" +msgstr "カスタムスクリプト" + +#: main/models/inventory.py:828 +msgid "Inventory source variables in YAML or JSON format." +msgstr "YAML または JSON 形式のインベントリーソース変数。" + +#: main/models/inventory.py:847 +msgid "" +"Comma-separated list of filter expressions (EC2 only). Hosts are imported " +"when ANY of the filters match." +msgstr "カンマ区切りのフィルター式の一覧 (EC2 のみ) です。ホストは、フィルターのいずれかが一致する場合にインポートされます。" + +#: main/models/inventory.py:853 +msgid "Limit groups automatically created from inventory source (EC2 only)." +msgstr "インベントリーソースから自動的に作成されるグループを制限します (EC2 のみ)。" + +#: main/models/inventory.py:857 +msgid "Overwrite local groups and hosts from remote inventory source." +msgstr "リモートインベントリーソースからのローカルグループおよびホストを上書きします。" + +#: main/models/inventory.py:861 +msgid "Overwrite local variables from remote inventory source." +msgstr "リモートインベントリーソースからのローカル変数を上書きします。" + +#: main/models/inventory.py:893 +msgid "Availability Zone" +msgstr "アベイラビリティーゾーン" + +#: main/models/inventory.py:894 +msgid "Image ID" +msgstr "イメージ ID" + +#: main/models/inventory.py:895 +msgid "Instance ID" +msgstr "インスタンス ID" + +#: main/models/inventory.py:896 +msgid "Instance Type" +msgstr "インスタンスタイプ" + +#: main/models/inventory.py:897 +msgid "Key Name" +msgstr "キー名" + +#: main/models/inventory.py:898 +msgid "Region" +msgstr "リージョン" + +#: main/models/inventory.py:899 +msgid "Security Group" +msgstr "セキュリティーグループ" + +#: main/models/inventory.py:900 +msgid "Tags" +msgstr "タグ" + +#: main/models/inventory.py:901 +msgid "VPC ID" +msgstr "VPC ID" + +#: main/models/inventory.py:902 +msgid "Tag None" +msgstr "タグ None" + +#: main/models/inventory.py:973 +#, python-format +msgid "" +"Cloud-based inventory sources (such as %s) require credentials for the " +"matching cloud service." +msgstr "クラウドベースのインベントリーソース (%s など) には一致するクラウドサービスの認証情報が必要です。" + +#: main/models/inventory.py:980 +msgid "Credential is required for a cloud source." +msgstr "認証情報がクラウドソースに必要です。" + +#: main/models/inventory.py:1005 +#, python-format +msgid "Invalid %(source)s region: %(region)s" +msgstr "無効な %(source)s リージョン: %(region)s" + +#: main/models/inventory.py:1031 +#, python-format +msgid "Invalid filter expression: %(filter)s" +msgstr "無効なフィルター式: %(filter)s" + +#: main/models/inventory.py:1050 +#, python-format +msgid "Invalid group by choice: %(choice)s" +msgstr "無効なグループ (選択による): %(choice)s" + +#: main/models/inventory.py:1198 +#, python-format +msgid "" +"Unable to configure this item for cloud sync. It is already managed by %s." +msgstr "クラウド同期用にこの項目を設定できません。すでに %s によって管理されています。" + +#: main/models/inventory.py:1293 +msgid "Inventory script contents" +msgstr "インベントリースクリプトの内容" + +#: main/models/inventory.py:1298 +msgid "Organization owning this inventory script" +msgstr "このインベントリースクリプトを所有する組織" + +#: main/models/jobs.py:171 +msgid "You must provide a network credential." +msgstr "ネットワーク認証情報を指定する必要があります。" + +#: main/models/jobs.py:179 +msgid "" +"Must provide a credential for a cloud provider, such as Amazon Web Services " +"or Rackspace." +msgstr "Amazon Web Services または Rackspace などのクラウドプロバイダーの認証情報を指定する必要があります。" + +#: main/models/jobs.py:271 +msgid "Job Template must provide 'inventory' or allow prompting for it." +msgstr "ジョブテンプレートは「inventory」を指定するか、このプロンプトを許可する必要があります。" + +#: main/models/jobs.py:275 +msgid "Job Template must provide 'credential' or allow prompting for it." +msgstr "ジョブテンプレートは「credential」を指定するか、このプロンプトを許可する必要があります。" + +#: main/models/jobs.py:364 +msgid "Cannot override job_type to or from a scan job." +msgstr "スキャンジョブから/への job_type を上書きを実行できません。" + +#: main/models/jobs.py:367 +msgid "Inventory cannot be changed at runtime for scan jobs." +msgstr "インベントリーはスキャンジョブの実行時に変更できません。" + +#: main/models/jobs.py:433 +#: main/models/projects.py:243 +msgid "SCM Revision" +msgstr "SCM リビジョン" + +#: main/models/jobs.py:434 +msgid "The SCM Revision from the Project used for this job, if available" +msgstr "このジョブに使用されるプロジェクトからの SCM リビジョン (ある場合)" + +#: main/models/jobs.py:442 +msgid "" +"The SCM Refresh task used to make sure the playbooks were available for the " +"job run" +msgstr "SCM 更新タスクは、Playbook がジョブの実行で利用可能であったことを確認するために使用されます" + +#: main/models/jobs.py:666 +msgid "job host summaries" +msgstr "ジョブホストの概要" + +#: main/models/jobs.py:769 +msgid "Host Failure" +msgstr "ホストの失敗" + +#: main/models/jobs.py:772 +#: main/models/jobs.py:786 +msgid "No Hosts Remaining" +msgstr "残りのホストがありません" + +#: main/models/jobs.py:773 +msgid "Host Polling" +msgstr "ホストのポーリング" + +#: main/models/jobs.py:774 +msgid "Host Async OK" +msgstr "ホストの非同期 OK" + +#: main/models/jobs.py:775 +msgid "Host Async Failure" +msgstr "ホストの非同期失敗" + +#: main/models/jobs.py:776 +msgid "Item OK" +msgstr "項目 OK" + +#: main/models/jobs.py:777 +msgid "Item Failed" +msgstr "項目の失敗" + +#: main/models/jobs.py:778 +msgid "Item Skipped" +msgstr "項目のスキップ" + +#: main/models/jobs.py:779 +msgid "Host Retry" +msgstr "ホストの再試行" + +#: main/models/jobs.py:781 +msgid "File Difference" +msgstr "ファイルの相違点" + +#: main/models/jobs.py:782 +msgid "Playbook Started" +msgstr "Playbook の開始" + +#: main/models/jobs.py:783 +msgid "Running Handlers" +msgstr "実行中のハンドラー" + +#: main/models/jobs.py:784 +msgid "Including File" +msgstr "組み込みファイル" + +#: main/models/jobs.py:785 +msgid "No Hosts Matched" +msgstr "一致するホストがありません" + +#: main/models/jobs.py:787 +msgid "Task Started" +msgstr "タスクの開始" + +#: main/models/jobs.py:789 +msgid "Variables Prompted" +msgstr "変数のプロモート" + +#: main/models/jobs.py:790 +msgid "Gathering Facts" +msgstr "ファクトの収集" + +#: main/models/jobs.py:791 +msgid "internal: on Import for Host" +msgstr "内部: ホストのインポート時" + +#: main/models/jobs.py:792 +msgid "internal: on Not Import for Host" +msgstr "内部: ホストの非インポート時" + +#: main/models/jobs.py:793 +msgid "Play Started" +msgstr "プレイの開始" + +#: main/models/jobs.py:794 +msgid "Playbook Complete" +msgstr "Playbook の完了" + +#: main/models/jobs.py:1240 +msgid "Remove jobs older than a certain number of days" +msgstr "特定の日数より前のジョブを削除" + +#: main/models/jobs.py:1241 +msgid "Remove activity stream entries older than a certain number of days" +msgstr "特定の日数より前のアクティビティーストリームのエントリーを削除" + +#: main/models/jobs.py:1242 +msgid "Purge and/or reduce the granularity of system tracking data" +msgstr "システムトラッキングデータの詳細度の削除/削減" + +#: main/models/label.py:29 +msgid "Organization this label belongs to." +msgstr "このラベルが属する組織。" + +#: main/models/notifications.py:31 +msgid "Email" +msgstr "メール" + +#: main/models/notifications.py:32 +msgid "Slack" +msgstr "Slack" + +#: main/models/notifications.py:33 +msgid "Twilio" +msgstr "Twilio" + +#: main/models/notifications.py:34 +msgid "Pagerduty" +msgstr "Pagerduty" + +#: main/models/notifications.py:35 +msgid "HipChat" +msgstr "HipChat" + +#: main/models/notifications.py:36 +msgid "Webhook" +msgstr "Webhook" + +#: main/models/notifications.py:37 +msgid "IRC" +msgstr "IRC" + +#: main/models/notifications.py:127 +#: main/models/unified_jobs.py:57 +msgid "Pending" +msgstr "保留中" + +#: main/models/notifications.py:128 +#: main/models/unified_jobs.py:60 +msgid "Successful" +msgstr "成功" + +#: main/models/notifications.py:129 +#: main/models/unified_jobs.py:61 +msgid "Failed" +msgstr "失敗" + +#: main/models/organization.py:157 +msgid "Execute Commands on the Inventory" +msgstr "インベントリーでのコマンドの実行" + +#: main/models/organization.py:211 +msgid "Token not invalidated" +msgstr "トークンが無効にされませんでした" + +#: main/models/organization.py:212 +msgid "Token is expired" +msgstr "トークンは期限切れです" + +#: main/models/organization.py:213 +msgid "Maximum per-user sessions reached" +msgstr "ユーザーあたりの最大セッション数に達しました。" + +#: main/models/organization.py:216 +msgid "Invalid token" +msgstr "無効なトークン" + +#: main/models/organization.py:233 +msgid "Reason the auth token was invalidated." +msgstr "認証トークンが無効にされた理由。" + +#: main/models/organization.py:272 +msgid "Invalid reason specified" +msgstr "無効な理由が特定されました" + +#: main/models/projects.py:43 +msgid "Git" +msgstr "Git" + +#: main/models/projects.py:44 +msgid "Mercurial" +msgstr "Mercurial" + +#: main/models/projects.py:45 +msgid "Subversion" +msgstr "Subversion" + +#: main/models/projects.py:71 +msgid "" +"Local path (relative to PROJECTS_ROOT) containing playbooks and related " +"files for this project." +msgstr "このプロジェクトの Playbook および関連するファイルを含むローカルパス (PROJECTS_ROOT との相対)。" + +#: main/models/projects.py:80 +msgid "SCM Type" +msgstr "SCM タイプ" + +#: main/models/projects.py:81 +msgid "Specifies the source control system used to store the project." +msgstr "プロジェクトを保存するために使用されるソースコントロールシステムを指定します。" + +#: main/models/projects.py:87 +msgid "SCM URL" +msgstr "SCM URL" + +#: main/models/projects.py:88 +msgid "The location where the project is stored." +msgstr "プロジェクトが保存される場所。" + +#: main/models/projects.py:94 +msgid "SCM Branch" +msgstr "SCM ブランチ" + +#: main/models/projects.py:95 +msgid "Specific branch, tag or commit to checkout." +msgstr "チェックアウトする特定のブランチ、タグまたはコミット。" + +#: main/models/projects.py:99 +msgid "Discard any local changes before syncing the project." +msgstr "ローカル変更を破棄してからプロジェクトを同期します。" + +#: main/models/projects.py:103 +msgid "Delete the project before syncing." +msgstr "プロジェクトを削除してから同期します。" + +#: main/models/projects.py:116 +msgid "The amount of time to run before the task is canceled." +msgstr "タスクが取り消される前の実行時間。" + +#: main/models/projects.py:130 +msgid "Invalid SCM URL." +msgstr "無効な SCM URL。" + +#: main/models/projects.py:133 +msgid "SCM URL is required." +msgstr "SCM URL が必要です。" + +#: main/models/projects.py:142 +msgid "Credential kind must be 'scm'." +msgstr "認証情報の種類は 'scm' にする必要があります。" + +#: main/models/projects.py:157 +msgid "Invalid credential." +msgstr "無効な認証情報。" + +#: main/models/projects.py:229 +msgid "Update the project when a job is launched that uses the project." +msgstr "プロジェクトを使用するジョブの起動時にプロジェクトを更新します。" + +#: main/models/projects.py:234 +msgid "" +"The number of seconds after the last project update ran that a newproject " +"update will be launched as a job dependency." +msgstr "新規プロジェクトの更新がジョブの依存関係として起動される最終プロジェクト更新後の秒数。" + +#: main/models/projects.py:244 +msgid "The last revision fetched by a project update" +msgstr "プロジェクト更新で取得される最新リビジョン" + +#: main/models/projects.py:251 +msgid "Playbook Files" +msgstr "Playbook ファイル" + +#: main/models/projects.py:252 +msgid "List of playbooks found in the project" +msgstr "プロジェクトにある Playbook の一覧" + +#: main/models/rbac.py:122 +msgid "roles" +msgstr "ロール" + +#: main/models/rbac.py:438 +msgid "role_ancestors" +msgstr "role_ancestors" + +#: main/models/schedules.py:69 +msgid "Enables processing of this schedule by Tower." +msgstr "Tower によるこのスケジュールの処理を有効にします。" + +#: main/models/schedules.py:75 +msgid "The first occurrence of the schedule occurs on or after this time." +msgstr "スケジュールの最初のオカレンスはこの時間またはこの時間の後に生じます。" + +#: main/models/schedules.py:81 +msgid "" +"The last occurrence of the schedule occurs before this time, aftewards the " +"schedule expires." +msgstr "スケジュールの最後のオカレンスはこの時間の前に生じます。その後スケジュールが期限切れになります。" + +#: main/models/schedules.py:85 +msgid "A value representing the schedules iCal recurrence rule." +msgstr "スケジュールの iCal 繰り返しルールを表す値。" + +#: main/models/schedules.py:91 +msgid "The next time that the scheduled action will run." +msgstr "スケジュールされたアクションが次に実行される時間。" + +#: main/models/unified_jobs.py:56 +msgid "New" +msgstr "新規" + +#: main/models/unified_jobs.py:58 +msgid "Waiting" +msgstr "待機中" + +#: main/models/unified_jobs.py:59 +msgid "Running" +msgstr "実行中" + +#: main/models/unified_jobs.py:63 +msgid "Canceled" +msgstr "取り消されました" + +#: main/models/unified_jobs.py:67 +msgid "Never Updated" +msgstr "更新されていません" + +#: main/models/unified_jobs.py:71 +#: ui/templates/ui/index.html:85 +#: ui/templates/ui/index.html.py:104 +msgid "OK" +msgstr "OK" + +#: main/models/unified_jobs.py:72 +msgid "Missing" +msgstr "不明" + +#: main/models/unified_jobs.py:76 +msgid "No External Source" +msgstr "外部ソースがありません" + +#: main/models/unified_jobs.py:83 +msgid "Updating" +msgstr "更新中" + +#: main/models/unified_jobs.py:387 +msgid "Relaunch" +msgstr "再起動" + +#: main/models/unified_jobs.py:388 +msgid "Callback" +msgstr "コールバック" + +#: main/models/unified_jobs.py:389 +msgid "Scheduled" +msgstr "スケジュール済み" + +#: main/models/unified_jobs.py:390 +msgid "Dependency" +msgstr "依存関係" + +#: main/models/unified_jobs.py:391 +msgid "Workflow" +msgstr "ワークフロー" + +#: main/models/unified_jobs.py:437 +msgid "The Tower node the job executed on." +msgstr "ジョブが実行される Tower ノード。" + +#: main/models/unified_jobs.py:463 +msgid "The date and time the job was queued for starting." +msgstr "ジョブが開始のために待機した日時。" + +#: main/models/unified_jobs.py:469 +msgid "The date and time the job finished execution." +msgstr "ジョブが実行を完了した日時。" + +#: main/models/unified_jobs.py:475 +msgid "Elapsed time in seconds that the job ran." +msgstr "ジョブ実行の経過時間 (秒単位)" + +#: main/models/unified_jobs.py:497 +msgid "" +"A status field to indicate the state of the job if it wasn't able to run and " +"capture stdout" +msgstr "stdout の実行およびキャプチャーを実行できない場合のジョブの状態を示すための状態フィールド" + +#: main/notifications/base.py:17 +#: main/notifications/email_backend.py:28 +msgid "{} #{} had status {} on Ansible Tower, view details at {}\n" +"\n" +msgstr "{} #{} には Ansible Tower のステータス {} があります。詳細については {} で確認してください\n" +"\n" + +#: main/notifications/hipchat_backend.py:46 +msgid "Error sending messages: {}" +msgstr "メッセージの送信時のエラー: {}" + +#: main/notifications/hipchat_backend.py:48 +msgid "Error sending message to hipchat: {}" +msgstr "メッセージの hipchat への送信時のエラー: {}" + +#: main/notifications/irc_backend.py:54 +msgid "Exception connecting to irc server: {}" +msgstr "irc サーバーへの接続時の例外: {}" + +#: main/notifications/pagerduty_backend.py:39 +msgid "Exception connecting to PagerDuty: {}" +msgstr "PagerDuty への接続時の例外: {}" + +#: main/notifications/pagerduty_backend.py:48 +#: main/notifications/slack_backend.py:52 +#: main/notifications/twilio_backend.py:46 +msgid "Exception sending messages: {}" +msgstr "メッセージの送信時の例外: {}" + +#: main/notifications/twilio_backend.py:36 +msgid "Exception connecting to Twilio: {}" +msgstr "Twilio への接続時の例外: {}" + +#: main/notifications/webhook_backend.py:38 +#: main/notifications/webhook_backend.py:40 +msgid "Error sending notification webhook: {}" +msgstr "通知 webhook の送信時のエラー: {}" + +#: main/tasks.py:139 +msgid "Ansible Tower host usage over 90%" +msgstr "Ansible Tower ホストの使用率が 90% を超えました" + +#: main/tasks.py:144 +msgid "Ansible Tower license will expire soon" +msgstr "Ansible Tower ライセンスがまもなく期限切れになります" + +#: main/tasks.py:197 +msgid "status_str must be either succeeded or failed" +msgstr "status_str は成功または失敗のいずれかである必要があります" + +#: main/utils/common.py:88 +#, python-format +msgid "Unable to convert \"%s\" to boolean" +msgstr "\"%s\" をブール値に変換できません" + +#: main/utils/common.py:242 +#, python-format +msgid "Unsupported SCM type \"%s\"" +msgstr "サポートされない SCM タイプ \"%s\"" + +#: main/utils/common.py:249 +#: main/utils/common.py:261 +#: main/utils/common.py:280 +#, python-format +msgid "Invalid %s URL" +msgstr "無効な %s URL" + +#: main/utils/common.py:251 +#: main/utils/common.py:289 +#, python-format +msgid "Unsupported %s URL" +msgstr "サポートされていない %s URL" + +#: main/utils/common.py:291 +#, python-format +msgid "Unsupported host \"%s\" for file:// URL" +msgstr "ファイル:// URL のサポートされていないホスト \"%s\" " + +#: main/utils/common.py:293 +#, python-format +msgid "Host is required for %s URL" +msgstr "%s URL にはホストが必要です" + +#: main/utils/common.py:311 +#, python-format +msgid "Username must be \"git\" for SSH access to %s." +msgstr "%s への SSH アクセスではユーザー名を \"git\" にする必要があります。" + +#: main/utils/common.py:317 +#, python-format +msgid "Username must be \"hg\" for SSH access to %s." +msgstr "%s への SSH アクセスではユーザー名を \"hg\" にする必要があります。" + +#: main/validators.py:60 +#, python-format +msgid "Invalid certificate or key: %r..." +msgstr "無効な証明書またはキー: %r..." + +#: main/validators.py:74 +#, python-format +msgid "Invalid private key: unsupported type \"%s\"" +msgstr "無効な秘密鍵: サポートされていないタイプ \"%s\"" + +#: main/validators.py:78 +#, python-format +msgid "Unsupported PEM object type: \"%s\"" +msgstr "サポートされていない PEM オブジェクトタイプ: \"%s\"" + +#: main/validators.py:103 +msgid "Invalid base64-encoded data" +msgstr "無効な base64 エンコードされたデータ" + +#: main/validators.py:122 +msgid "Exactly one private key is required." +msgstr "秘密鍵が 1 つのみ必要です。" + +#: main/validators.py:124 +msgid "At least one private key is required." +msgstr "1 つ以上の秘密鍵が必要です。" + +#: main/validators.py:126 +#, python-format +msgid "" +"At least %(min_keys)d private keys are required, only %(key_count)d provided." +"" +msgstr "%(min_keys)d 以上の秘密鍵が必要です。提供数: %(key_count)d のみ。" + +#: main/validators.py:129 +#, python-format +msgid "Only one private key is allowed, %(key_count)d provided." +msgstr "秘密鍵が 1 つのみ許可されます。提供数: %(key_count)d" + +#: main/validators.py:131 +#, python-format +msgid "" +"No more than %(max_keys)d private keys are allowed, %(key_count)d provided." +msgstr "%(max_keys)d を超える秘密鍵は許可されません。提供数: %(key_count)d " + +#: main/validators.py:136 +msgid "Exactly one certificate is required." +msgstr "証明書が 1 つのみ必要です。" + +#: main/validators.py:138 +msgid "At least one certificate is required." +msgstr "1 つ以上の証明書が必要です。" + +#: main/validators.py:140 +#, python-format +msgid "" +"At least %(min_certs)d certificates are required, only %(cert_count)d " +"provided." +msgstr "%(min_certs)d 以上の証明書が必要です。提供数: %(cert_count)d のみ。" + +#: main/validators.py:143 +#, python-format +msgid "Only one certificate is allowed, %(cert_count)d provided." +msgstr "証明書が 1 つのみ許可されます。提供数: %(cert_count)d" + +#: main/validators.py:145 +#, python-format +msgid "" +"No more than %(max_certs)d certificates are allowed, %(cert_count)d provided." +"" +msgstr "%(max_certs)d を超える証明書は許可されません。提供数: %(cert_count)d" + +#: main/views.py:20 +msgid "API Error" +msgstr "API エラー" + +#: main/views.py:49 +msgid "Bad Request" +msgstr "不正な要求です" + +#: main/views.py:50 +msgid "The request could not be understood by the server." +msgstr "要求がサーバーによって認識されませんでした。" + +#: main/views.py:57 +msgid "Forbidden" +msgstr "許可されていません" + +#: main/views.py:58 +msgid "You don't have permission to access the requested resource." +msgstr "要求されたリソースにアクセスするためのパーミッションがありません。" + +#: main/views.py:65 +msgid "Not Found" +msgstr "見つかりません" + +#: main/views.py:66 +msgid "The requested resource could not be found." +msgstr "要求されたリソースは見つかりませんでした。" + +#: main/views.py:73 +msgid "Server Error" +msgstr "サーバーエラー" + +#: main/views.py:74 +msgid "A server error has occurred." +msgstr "サーバーエラーが発生しました。" + +#: settings/defaults.py:593 +msgid "Chicago" +msgstr "シカゴ" + +#: settings/defaults.py:594 +msgid "Dallas/Ft. Worth" +msgstr "ダラス/フォートワース" + +#: settings/defaults.py:595 +msgid "Northern Virginia" +msgstr "北バージニア" + +#: settings/defaults.py:596 +msgid "London" +msgstr "ロンドン" + +#: settings/defaults.py:597 +msgid "Sydney" +msgstr "シドニー" + +#: settings/defaults.py:598 +msgid "Hong Kong" +msgstr "香港" + +#: settings/defaults.py:625 +msgid "US East (Northern Virginia)" +msgstr "米国東部 (バージニア北部)" + +#: settings/defaults.py:626 +msgid "US East (Ohio)" +msgstr "米国東部 (オハイオ)" + +#: settings/defaults.py:627 +msgid "US West (Oregon)" +msgstr "米国西部 (オレゴン)" + +#: settings/defaults.py:628 +msgid "US West (Northern California)" +msgstr "米国西部 (北カリフォルニア)" + +#: settings/defaults.py:629 +msgid "EU (Frankfurt)" +msgstr "EU (フランクフルト)" + +#: settings/defaults.py:630 +msgid "EU (Ireland)" +msgstr "EU (アイルランド)" + +#: settings/defaults.py:631 +msgid "Asia Pacific (Singapore)" +msgstr "アジア太平洋 (シンガポール)" + +#: settings/defaults.py:632 +msgid "Asia Pacific (Sydney)" +msgstr "アジア太平洋 (シドニー)" + +#: settings/defaults.py:633 +msgid "Asia Pacific (Tokyo)" +msgstr "アジア太平洋 (東京)" + +#: settings/defaults.py:634 +msgid "Asia Pacific (Seoul)" +msgstr "アジア太平洋 (ソウル)" + +#: settings/defaults.py:635 +msgid "Asia Pacific (Mumbai)" +msgstr "アジア太平洋 (ムンバイ)" + +#: settings/defaults.py:636 +msgid "South America (Sao Paulo)" +msgstr "南アメリカ (サンパウロ)" + +#: settings/defaults.py:637 +msgid "US West (GovCloud)" +msgstr "米国西部 (GovCloud)" + +#: settings/defaults.py:638 +msgid "China (Beijing)" +msgstr "中国 (北京)" + +#: settings/defaults.py:687 +msgid "US East (B)" +msgstr "米国東部 (B)" + +#: settings/defaults.py:688 +msgid "US East (C)" +msgstr "米国東部 (C)" + +#: settings/defaults.py:689 +msgid "US East (D)" +msgstr "米国東部 (D)" + +#: settings/defaults.py:690 +msgid "US Central (A)" +msgstr "米国中部 (A)" + +#: settings/defaults.py:691 +msgid "US Central (B)" +msgstr "米国中部 (B)" + +#: settings/defaults.py:692 +msgid "US Central (C)" +msgstr "米国中部 (C)" + +#: settings/defaults.py:693 +msgid "US Central (F)" +msgstr "米国中部 (F)" + +#: settings/defaults.py:694 +msgid "Europe West (B)" +msgstr "欧州西部 (B)" + +#: settings/defaults.py:695 +msgid "Europe West (C)" +msgstr "欧州西部 (C)" + +#: settings/defaults.py:696 +msgid "Europe West (D)" +msgstr "欧州西部 (D)" + +#: settings/defaults.py:697 +msgid "Asia East (A)" +msgstr "アジア東部 (A)" + +#: settings/defaults.py:698 +msgid "Asia East (B)" +msgstr "アジア東部 (B)" + +#: settings/defaults.py:699 +msgid "Asia East (C)" +msgstr "アジア東部 (C)" + +#: settings/defaults.py:723 +msgid "US Central" +msgstr "米国中部" + +#: settings/defaults.py:724 +msgid "US East" +msgstr "米国東部" + +#: settings/defaults.py:725 +msgid "US East 2" +msgstr "米国東部 2" + +#: settings/defaults.py:726 +msgid "US North Central" +msgstr "米国中北部" + +#: settings/defaults.py:727 +msgid "US South Central" +msgstr "米国中南部" + +#: settings/defaults.py:728 +msgid "US West" +msgstr "米国西部" + +#: settings/defaults.py:729 +msgid "Europe North" +msgstr "欧州北部" + +#: settings/defaults.py:730 +msgid "Europe West" +msgstr "欧州西部" + +#: settings/defaults.py:731 +msgid "Asia Pacific East" +msgstr "アジア太平洋東部" + +#: settings/defaults.py:732 +msgid "Asia Pacific Southeast" +msgstr "アジア太平洋南東部" + +#: settings/defaults.py:733 +msgid "Japan East" +msgstr "日本東部" + +#: settings/defaults.py:734 +msgid "Japan West" +msgstr "日本西部" + +#: settings/defaults.py:735 +msgid "Brazil South" +msgstr "ブラジル南部" + +#: sso/apps.py:9 +msgid "Single Sign-On" +msgstr "シングルサインオン" + +#: sso/conf.py:27 +msgid "" +"Mapping to organization admins/users from social auth accounts. This setting\n" +"controls which users are placed into which Tower organizations based on\n" +"their username and email address. Dictionary keys are organization names.\n" +"organizations will be created if not present if the license allows for\n" +"multiple organizations, otherwise the single default organization is used\n" +"regardless of the key. Values are dictionaries defining the options for\n" +"each organization's membership. For each organization it is possible to\n" +"specify which users are automatically users of the organization and also\n" +"which users can administer the organization. \n" +"\n" +"- admins: None, True/False, string or list of strings.\n" +" If None, organization admins will not be updated.\n" +" If True, all users using social auth will automatically be added as admins\n" +" of the organization.\n" +" If False, no social auth users will be automatically added as admins of\n" +" the organization.\n" +" If a string or list of strings, specifies the usernames and emails for\n" +" users who will be added to the organization. Strings in the format\n" +" \"//\" will be interpreted as JavaScript regular " +"expressions and\n" +" may also be used instead of string literals; only \"i\" and \"m\" are " +"supported\n" +" for flags.\n" +"- remove_admins: True/False. Defaults to True.\n" +" If True, a user who does not match will be removed from the organization's\n" +" administrative list.\n" +"- users: None, True/False, string or list of strings. Same rules apply as " +"for\n" +" admins.\n" +"- remove_users: True/False. Defaults to True. Same rules as apply for \n" +" remove_admins." +msgstr "" +"ソーシャル認証アカウントから組織管理者/ユーザーへのマッピングです。この設定\n" +"は、ユーザーのユーザー名とメールアドレスに基づいてどのユーザーをどの Tower 組織に配置するかを制御します。\n" +"辞書キーは組織名です。\n" +"組織は、存在しない場合、ライセンスで複数の組織が許可される場合に作成されます。そうでない場合、キーとは無関係に単一のデフォルト組織が使用されます。\n" +"値は、各組織のメンバーシップのオプションを定義する辞書です。\n" +"各組織については、自動的に組織のユーザーにするユーザーと\n" +"組織を管理できるユーザーを指定できます。\n" +"\n" +"- admins: None、True/False、文字列または文字列の一覧。\n" +" None の場合、組織管理者は更新されません。\n" +" True の場合、ソーシャル認証を使用するすべてのユーザーが組織の管理者として\n" +" 自動的に追加されます。\n" +" False の場合、ソーシャル認証ユーザーは組織の管理者として自動的に\n" +" 追加されません。\n" +" 文字列または文字列の一覧の場合、組織に追加されるユーザーの\n" +" ユーザー名およびメールを指定します。\"//\" 形式の文字列\n" +" は JavaScript 正規表現として解釈され、文字列リテラルの代わりに使用できます。\n" +" \"i\" と \"m\" のみがフラグでサポートされます。\n" +" - remove_admins: True/False。デフォルトで True に設定されます。\n" +" True の場合、一致しないユーザーは組織の管理者リストから削除されます。\n" +" - users: None、True/False、文字列または文字列の一覧。管理者の場合と同じルールが\n" +" 適用されます。\n" +"- remove_users: True/False。デフォルトで True に設定されます。remove_admins の\n" +" 場合と同じルールが適用されます。" + +#: sso/conf.py:76 +msgid "" +"Mapping of team members (users) from social auth accounts. Keys are team\n" +"names (will be created if not present). Values are dictionaries of options\n" +"for each team's membership, where each can contain the following parameters:\n" +"\n" +"- organization: string. The name of the organization to which the team\n" +" belongs. The team will be created if the combination of organization and\n" +" team name does not exist. The organization will first be created if it\n" +" does not exist. If the license does not allow for multiple organizations,\n" +" the team will always be assigned to the single default organization.\n" +"- users: None, True/False, string or list of strings.\n" +" If None, team members will not be updated.\n" +" If True/False, all social auth users will be added/removed as team\n" +" members.\n" +" If a string or list of strings, specifies expressions used to match users.\n" +" User will be added as a team member if the username or email matches.\n" +" Strings in the format \"//\" will be interpreted as " +"JavaScript\n" +" regular expressions and may also be used instead of string literals; only " +"\"i\"\n" +" and \"m\" are supported for flags.\n" +"- remove: True/False. Defaults to True. If True, a user who does not match\n" +" the rules above will be removed from the team." +msgstr "" +"ソーシャル認証アカウントからチームメンバー (ユーザー) へのマッピングです。\n" +"キーはチーム名です (存在しない場合に作成されます)。値は各チームの\n" +"メンバーシップのオプションの辞書です。各値には以下のパラメーターが含まれます。\n" +"\n" +"- organization: 文字列。チームが属する組織の名前です。\n" +" チームは組織とチーム名の組み合わせが存在しない場合に作成されます。\n" +" 組織がまず作成されます (存在しない場合)。ライセンスにより複数の組織が許可\n" +" されない場合、チームは常に単一のデフォルト組織に割り当てられます。\n" +"- ユーザー: None、True/False、文字列または文字列の一覧。\n" +" None の場合、チームメンバーは更新されません。\n" +" True/False の場合、すべてのソーシャル認証ユーザーがチームメンバーとして\n" +" 追加/削除されます。\n" +" 文字列または文字列の一覧の場合、ユーザーに一致する表現を指定します。\n" +" ユーザーは、ユーザー名またはメールが一致する場合にチームメンバーとして\n" +" 追加されます。\n" +" \"//\" 形式の文字列が JavaScript 正規表現として解釈され、\n" +" 文字列リテラルの代わりに使用することもできます。\"i\"\n" +" および \"m\" のみがフラグでサポートされます。\n" +"- remove: True/False。デフォルトで True に設定されます。True の場合、上記のルール\n" +" に一致しないユーザーはチームから削除されます。" + +#: sso/conf.py:119 +msgid "Authentication Backends" +msgstr "認証バックエンド" + +#: sso/conf.py:120 +msgid "" +"List of authentication backends that are enabled based on license features " +"and other authentication settings." +msgstr "ライセンスの特長およびその他の認証設定に基づいて有効にされる認証バックエンドの一覧。" + +#: sso/conf.py:133 +msgid "Social Auth Organization Map" +msgstr "ソーシャル認証組織マップ" + +#: sso/conf.py:145 +msgid "Social Auth Team Map" +msgstr "ソーシャル認証チームマップ" + +#: sso/conf.py:157 +msgid "Social Auth User Fields" +msgstr "ソーシャル認証ユーザーフィールド" + +#: sso/conf.py:158 +msgid "" +"When set to an empty list `[]`, this setting prevents new user accounts from " +"being created. Only users who have previously logged in using social auth or " +"have a user account with a matching email address will be able to login." +msgstr "" +"空リスト " +"`[]`に設定される場合、この設定により新規ユーザーアカウントは作成できなくなります。ソーシャル認証を使ってログインしたことのあるユーザーまたは一致するメールアドレスのユーザーアカウントを持つユーザーのみがログインできます。" + +#: sso/conf.py:176 +msgid "LDAP Server URI" +msgstr "LDAP サーバー URI" + +#: sso/conf.py:177 +msgid "" +"URI to connect to LDAP server, such as \"ldap://ldap.example.com:389\" (non-" +"SSL) or \"ldaps://ldap.example.com:636\" (SSL). Multiple LDAP servers may be " +"specified by separating with spaces or commas. LDAP authentication is " +"disabled if this parameter is empty." +msgstr "" +"\"ldap://ldap.example.com:389\" (非 SSL) または \"ldaps://ldap.example.com:636\" " +"(SSL) などの LDAP サーバーに接続する URI です。複数の LDAP サーバーをスペースまたはカンマで区切って指定できます。LDAP " +"認証は、このパラメーターが空の場合は無効になります。" + +#: sso/conf.py:181 +#: sso/conf.py:199 +#: sso/conf.py:211 +#: sso/conf.py:223 +#: sso/conf.py:239 +#: sso/conf.py:258 +#: sso/conf.py:279 +#: sso/conf.py:295 +#: sso/conf.py:314 +#: sso/conf.py:331 +#: sso/conf.py:347 +#: sso/conf.py:362 +#: sso/conf.py:379 +#: sso/conf.py:417 +#: sso/conf.py:458 +msgid "LDAP" +msgstr "LDAP" + +#: sso/conf.py:193 +msgid "LDAP Bind DN" +msgstr "LDAP バインド DN" + +#: sso/conf.py:194 +msgid "" +"DN (Distinguished Name) of user to bind for all search queries. Normally in " +"the format \"CN=Some User,OU=Users,DC=example,DC=com\" but may also be " +"specified as \"DOMAIN\\username\" for Active Directory. This is the system " +"user account we will use to login to query LDAP for other user information." +msgstr "" +"すべての検索クエリーについてバインドするユーザーの DN (識別名) です。通常、形式は \"CN=Some User,OU=Users,DC=" +"example,DC=com\" になりますが、Active Directory の場合 \"DOMAIN\\username\" " +"として指定することもできます。これは、他のユーザー情報についての LDAP クエリー実行時のログインに使用するシステムユーザーアカウントです。" + +#: sso/conf.py:209 +msgid "LDAP Bind Password" +msgstr "LDAP バインドパスワード" + +#: sso/conf.py:210 +msgid "Password used to bind LDAP user account." +msgstr "LDAP ユーザーアカウントをバインドするために使用されるパスワード。" + +#: sso/conf.py:221 +msgid "LDAP Start TLS" +msgstr "LDAP Start TLS" + +#: sso/conf.py:222 +msgid "Whether to enable TLS when the LDAP connection is not using SSL." +msgstr "LDAP 接続が SSL を使用していない場合に TLS を有効にするかどうか。" + +#: sso/conf.py:232 +msgid "LDAP Connection Options" +msgstr "LDAP 接続オプション" + +#: sso/conf.py:233 +msgid "" +"Additional options to set for the LDAP connection. LDAP referrals are " +"disabled by default (to prevent certain LDAP queries from hanging with AD). " +"Option names should be strings (e.g. \"OPT_REFERRALS\"). Refer to https://" +"www.python-ldap.org/doc/html/ldap.html#options for possible options and " +"values that can be set." +msgstr "" +"LDAP 設定に設定する追加オプションです。LDAP 照会はデフォルトで無効にされます (特定の LDAP クエリーが AD " +"でハングすることを避けるため)。オプション名は文字列でなければなりません (例: " +"\"OPT_REFERRALS\")。可能なオプションおよび設定できる値については、https://www.python-ldap.org/doc/" +"html/ldap.html#options を参照してください。" + +#: sso/conf.py:251 +msgid "LDAP User Search" +msgstr "LDAP ユーザー検索" + +#: sso/conf.py:252 +msgid "" +"LDAP search query to find users. Any user that matches the given pattern " +"will be able to login to Tower. The user should also be mapped into an " +"Tower organization (as defined in the AUTH_LDAP_ORGANIZATION_MAP setting). " +"If multiple search queries need to be supported use of \"LDAPUnion\" is " +"possible. See python-ldap documentation as linked at the top of this section." +"" +msgstr "" +"ユーザーを検索するための LDAP 検索クエリーです。指定パターンに一致するユーザーは Tower にログインできます。ユーザーは Tower " +"組織にマップされている必要もあります (AUTH_LDAP_ORGANIZATION_MAP " +"設定で定義)。複数の検索クエリーがサポートされる必要がある場合、\"LDAPUnion\" を使用できます。このセクションの先頭にリンクされている " +"python-ldap ドキュメントを参照してください。" + +#: sso/conf.py:273 +msgid "LDAP User DN Template" +msgstr "LDAP ユーザー DN テンプレート" + +#: sso/conf.py:274 +msgid "" +"Alternative to user search, if user DNs are all of the same format. This " +"approach will be more efficient for user lookups than searching if it is " +"usable in your organizational environment. If this setting has a value it " +"will be used instead of AUTH_LDAP_USER_SEARCH." +msgstr "" +"ユーザー DN " +"の形式がすべて同じである場合のユーザー検索の代替法になります。この方法は、組織の環境で使用可能であるかどうかを検索する場合よりも効率的なユーザー検索方法になります。この設定に値がある場合、それが " +"AUTH_LDAP_USER_SEARCH の代わりに使用されます。" + +#: sso/conf.py:289 +msgid "LDAP User Attribute Map" +msgstr "LDAP ユーザー属性マップ" + +#: sso/conf.py:290 +msgid "" +"Mapping of LDAP user schema to Tower API user attributes (key is user " +"attribute name, value is LDAP attribute name). The default setting is valid " +"for ActiveDirectory but users with other LDAP configurations may need to " +"change the values (not the keys) of the dictionary/hash-table." +msgstr "" +"LDAP ユーザースキーマの Tower API ユーザー属性へのマッピングです (キーはユーザー属性名で、値は LDAP " +"属性名です)。デフォルト設定は ActiveDirectory で有効ですが、他の LDAP 設定を持つユーザーは、辞書/ハッシュテーブルの値 " +"(キーではない) を変更する必要ある場合があります。" + +#: sso/conf.py:309 +msgid "LDAP Group Search" +msgstr "LDAP グループ検索" + +#: sso/conf.py:310 +msgid "" +"Users in Tower are mapped to organizations based on their membership in LDAP " +"groups. This setting defines the LDAP search query to find groups. Note that " +"this, unlike the user search above, does not support LDAPSearchUnion." +msgstr "" +"Tower のユーザーは LDAP グループのメンバーシップに基づいて組織にマップされます。この設定は、グループを検索できるように LDAP " +"検索クエリーを定義します。上記のユーザー検索とは異なり、これは LDAPSearchUnion をサポートしないことに注意してください。" + +#: sso/conf.py:327 +msgid "LDAP Group Type" +msgstr "LDAP グループタイプ" + +#: sso/conf.py:328 +msgid "" +"The group type may need to be changed based on the type of the LDAP server. " +"Values are listed at: http://pythonhosted.org/django-auth-ldap/groups." +"html#types-of-groups" +msgstr "" +"グループタイプは LDAP サーバーのタイプに基づいて変更する必要がある場合があります。値は以下に記載されています: http://" +"pythonhosted.org/django-auth-ldap/groups.html#types-of-groups" + +#: sso/conf.py:342 +msgid "LDAP Require Group" +msgstr "LDAP 要求グループ" + +#: sso/conf.py:343 +msgid "" +"Group DN required to login. If specified, user must be a member of this " +"group to login via LDAP. If not set, everyone in LDAP that matches the user " +"search will be able to login via Tower. Only one require group is supported." +msgstr "" +"ログインに必要なグループ DN。指定されている場合、LDAP " +"経由でログインするにはユーザーはこのグループのメンバーである必要があります。設定されていない場合は、ユーザー検索に一致する LDAP " +"のすべてのユーザーが Tower 経由でログインできます。1つの要求グループのみがサポートされます。" + +#: sso/conf.py:358 +msgid "LDAP Deny Group" +msgstr "LDAP 拒否グループ" + +#: sso/conf.py:359 +msgid "" +"Group DN denied from login. If specified, user will not be allowed to login " +"if a member of this group. Only one deny group is supported." +msgstr "" +"グループ DN がログインで拒否されます。指定されている場合、ユーザーはこのグループのメンバーの場合にログインできません。1 " +"つの拒否グループのみがサポートされます。" + +#: sso/conf.py:372 +msgid "LDAP User Flags By Group" +msgstr "LDAP ユーザーフラグ (グループ別)" + +#: sso/conf.py:373 +msgid "" +"User profile flags updated from group membership (key is user attribute " +"name, value is group DN). These are boolean fields that are matched based " +"on whether the user is a member of the given group. So far only " +"is_superuser is settable via this method. This flag is set both true and " +"false at login time based on current LDAP settings." +msgstr "" +"グループメンバーシップから更新されるユーザープロファイルフラグです (キーはユーザー属性名、値はグループ " +"DN)。これらは、ユーザーが指定グループのメンバーであるかに基づいて一致するブール値フィールドです。is_superuser " +"のみがこのメソッドで設定可能です。このフラグは、現在の LDAP 設定に基づいてログイン時に true および false に設定されます。" + +#: sso/conf.py:391 +msgid "LDAP Organization Map" +msgstr "LDAP 組織マップ" + +#: sso/conf.py:392 +msgid "" +"Mapping between organization admins/users and LDAP groups. This controls " +"what users are placed into what Tower organizations relative to their LDAP " +"group memberships. Keys are organization names. Organizations will be " +"created if not present. Values are dictionaries defining the options for " +"each organization's membership. For each organization it is possible to " +"specify what groups are automatically users of the organization and also " +"what groups can administer the organization.\n" +"\n" +" - admins: None, True/False, string or list of strings.\n" +" If None, organization admins will not be updated based on LDAP values.\n" +" If True, all users in LDAP will automatically be added as admins of the " +"organization.\n" +" If False, no LDAP users will be automatically added as admins of the " +"organization.\n" +" If a string or list of strings, specifies the group DN(s) that will be " +"added of the organization if they match any of the specified groups.\n" +" - remove_admins: True/False. Defaults to True.\n" +" If True, a user who is not an member of the given groups will be removed " +"from the organization's administrative list.\n" +" - users: None, True/False, string or list of strings. Same rules apply as " +"for admins.\n" +" - remove_users: True/False. Defaults to True. Same rules apply as for " +"remove_admins." +msgstr "" +"組織管理者/ユーザーと LDAP グループ間のマッピングです。これは、LDAP グループメンバーシップと相対してどのユーザーをどの Tower " +"組織に配置するかを制御します。キーは組織名です。組織は存在しない場合に作成されます。値は、各組織のメンバーシップのオプションを定義する辞書です。各組織については、自動的に組織のユーザーにするユーザーと組織を管理できるグループを指定できます。\n" +"\n" +" - admins: None、True/False、文字列または文字列の一覧。\n" +" None の場合、組織管理者は LDAP 値に基づいて更新されません。\n" +" True の場合、LDAP のすべてのユーザーが組織の管理者として自動的に追加されます。\n" +" False の場合、LDAP ユーザーは組織の管理者として自動的に追加されません。\n" +" 文字列または文字列の一覧の場合、指定されるグループのいずれかに一致する場合に組織に追加されるグループ DN を指定します。\n" +" - remove_admins: True/False。デフォルトで True に設定されます。\n" +" True の場合、指定グループのメンバーでないユーザーは組織の管理者リストから削除されます。\n" +" - users: None、True/False、文字列または文字列の一覧。管理者の場合と同じルールが適用されます。\n" +" - remove_users: True/False。デフォルトで True に設定されます。remove_admins " +"の場合と同じルールが適用されます。" + +#: sso/conf.py:440 +msgid "LDAP Team Map" +msgstr "LDAP チームマップ" + +#: sso/conf.py:441 +msgid "" +"Mapping between team members (users) and LDAP groups. Keys are team names " +"(will be created if not present). Values are dictionaries of options for " +"each team's membership, where each can contain the following parameters:\n" +"\n" +" - organization: string. The name of the organization to which the team " +"belongs. The team will be created if the combination of organization and " +"team name does not exist. The organization will first be created if it does " +"not exist.\n" +" - users: None, True/False, string or list of strings.\n" +" If None, team members will not be updated.\n" +" If True/False, all LDAP users will be added/removed as team members.\n" +" If a string or list of strings, specifies the group DN(s). User will be " +"added as a team member if the user is a member of ANY of these groups.\n" +"- remove: True/False. Defaults to True. If True, a user who is not a member " +"of the given groups will be removed from the team." +msgstr "" +"チームメンバー (ユーザー) と LDAP グループ間のマッピングです。キーはチーム名です " +"(存在しない場合に作成されます)。値は各チームのメンバーシップのオプションの辞書です。各値には以下のパラメーターが含まれます。\n" +"\n" +" - organization: 文字列。チームが属する組織の名前です。組織とチーム名の組み合わせ\n" +" が存在しない場合にチームが作成されます。組織がまず作成されます (存在しない場合)。\n" +" - users: None、True/False、文字列または文字列の一覧。\n" +" None の場合、チームメンバーは更新されません。\n" +" True/False の場合、すべての LDAP ユーザーがチームメンバーとして追加/削除されます。\n" +" 文字列または文字列の一覧の場合、グループ DN を指定します。\n" +" ユーザーがこれらのグループのいずれかのメンバーである場合、チームメンバーとして追加されます。\n" +"- remove: True/False。デフォルトで True に設定されます。True " +"の場合、指定グループのメンバーでないユーザーはチームから削除されます。" + +#: sso/conf.py:484 +msgid "RADIUS Server" +msgstr "RADIUS サーバー" + +#: sso/conf.py:485 +msgid "" +"Hostname/IP of RADIUS server. RADIUS authentication will be disabled if this " +"setting is empty." +msgstr "RADIUS サーバーのホスト名/IP です。この設定が空の場合は RADIUS 認証は無効にされます。" + +#: sso/conf.py:487 +#: sso/conf.py:501 +#: sso/conf.py:513 +msgid "RADIUS" +msgstr "RADIUS" + +#: sso/conf.py:499 +msgid "RADIUS Port" +msgstr "RADIUS ポート" + +#: sso/conf.py:500 +msgid "Port of RADIUS server." +msgstr "RADIUS サーバーのポート。" + +#: sso/conf.py:511 +msgid "RADIUS Secret" +msgstr "RADIUS シークレット" + +#: sso/conf.py:512 +msgid "Shared secret for authenticating to RADIUS server." +msgstr "RADIUS サーバーに対して認証するための共有シークレット。" + +#: sso/conf.py:528 +msgid "Google OAuth2 Callback URL" +msgstr "Google OAuth2 コールバック URL" + +#: sso/conf.py:529 +msgid "" +"Create a project at https://console.developers.google.com/ to obtain an " +"OAuth2 key and secret for a web application. Ensure that the Google+ API is " +"enabled. Provide this URL as the callback URL for your application." +msgstr "" +"web アプリケーションの OAuth2 キーおよびシークレットを取得するために https://console.developers.google." +"com/ にプロジェクトを作成します。Google+ API が有効であることを確認します。この URL をアプリケーションのコールバック URL " +"として指定します。" + +#: sso/conf.py:533 +#: sso/conf.py:544 +#: sso/conf.py:555 +#: sso/conf.py:568 +#: sso/conf.py:582 +#: sso/conf.py:594 +#: sso/conf.py:606 +msgid "Google OAuth2" +msgstr "Google OAuth2" + +#: sso/conf.py:542 +msgid "Google OAuth2 Key" +msgstr "Google OAuth2 キー" + +#: sso/conf.py:543 +msgid "" +"The OAuth2 key from your web application at https://console.developers." +"google.com/." +msgstr "web アプリケーションの OAuth2 キー (https://console.developers.google.com/)。" + +#: sso/conf.py:553 +msgid "Google OAuth2 Secret" +msgstr "Google OAuth2 シークレット" + +#: sso/conf.py:554 +msgid "" +"The OAuth2 secret from your web application at https://console.developers." +"google.com/." +msgstr "web アプリケーションの OAuth2 シークレット (https://console.developers.google.com/)。" + +#: sso/conf.py:565 +msgid "Google OAuth2 Whitelisted Domains" +msgstr "Google OAuth2 ホワイトリストドメイン" + +#: sso/conf.py:566 +msgid "" +"Update this setting to restrict the domains who are allowed to login using " +"Google OAuth2." +msgstr "この設定を更新し、Google OAuth2 を使用してログインできるドメインを制限します。" + +#: sso/conf.py:577 +msgid "Google OAuth2 Extra Arguments" +msgstr "Google OAuth2 追加引数" + +#: sso/conf.py:578 +msgid "" +"Extra arguments for Google OAuth2 login. When only allowing a single domain " +"to authenticate, set to `{\"hd\": \"yourdomain.com\"}` and Google will not " +"display any other accounts even if the user is logged in with multiple " +"Google accounts." +msgstr "" +"Google OAuth2 ログインの追加引数です。単一ドメインの認証のみを許可する場合、`{\"hd\": \"yourdomain.com\"}` " +"に設定すると、Google はユーザーが複数の Google アカウントでログインしている場合でもその他のアカウントを表示しません。" + +#: sso/conf.py:592 +msgid "Google OAuth2 Organization Map" +msgstr "Google OAuth2 組織マップ" + +#: sso/conf.py:604 +msgid "Google OAuth2 Team Map" +msgstr "Google OAuth2 チームマップ" + +#: sso/conf.py:620 +msgid "GitHub OAuth2 Callback URL" +msgstr "GitHub OAuth2 コールバック URL" + +#: sso/conf.py:621 +msgid "" +"Create a developer application at https://github.com/settings/developers to " +"obtain an OAuth2 key (Client ID) and secret (Client Secret). Provide this " +"URL as the callback URL for your application." +msgstr "" +"OAuth2 キー (クライアント ID) およびシークレット (クライアントシークレット) を取得するために https://github.com/" +"settings/developers に開発者アプリケーションを作成します。この URL をアプリケーションのコールバック URL として指定します。" + +#: sso/conf.py:625 +#: sso/conf.py:636 +#: sso/conf.py:646 +#: sso/conf.py:658 +#: sso/conf.py:670 +msgid "GitHub OAuth2" +msgstr "GitHub OAuth2" + +#: sso/conf.py:634 +msgid "GitHub OAuth2 Key" +msgstr "GitHub OAuth2 キー" + +#: sso/conf.py:635 +msgid "The OAuth2 key (Client ID) from your GitHub developer application." +msgstr "GitHub 開発者アプリケーションからの OAuth2 キー (クライアント ID)。" + +#: sso/conf.py:644 +msgid "GitHub OAuth2 Secret" +msgstr "GitHub OAuth2 シークレット" + +#: sso/conf.py:645 +msgid "" +"The OAuth2 secret (Client Secret) from your GitHub developer application." +msgstr "GitHub 開発者アプリケーションからの OAuth2 シークレット (クライアントシークレット)。" + +#: sso/conf.py:656 +msgid "GitHub OAuth2 Organization Map" +msgstr "GitHub OAuth2 組織マップ" + +#: sso/conf.py:668 +msgid "GitHub OAuth2 Team Map" +msgstr "GitHub OAuth2 チームマップ" + +#: sso/conf.py:684 +msgid "GitHub Organization OAuth2 Callback URL" +msgstr "GitHub 組織 OAuth2 コールバック URL" + +#: sso/conf.py:685 +#: sso/conf.py:760 +msgid "" +"Create an organization-owned application at https://github.com/organizations/" +"/settings/applications and obtain an OAuth2 key (Client ID) and " +"secret (Client Secret). Provide this URL as the callback URL for your " +"application." +msgstr "" +"組織が所有するアプリケーションを https://github.com/organizations//settings/" +"applications に作成し、OAuth2 キー (クライアント ID) およびシークレット (クライアントシークレット) を取得します。この " +"URL をアプリケーションのコールバック URL として指定します。" + +#: sso/conf.py:689 +#: sso/conf.py:700 +#: sso/conf.py:710 +#: sso/conf.py:722 +#: sso/conf.py:733 +#: sso/conf.py:745 +msgid "GitHub Organization OAuth2" +msgstr "GitHub 組織 OAuth2" + +#: sso/conf.py:698 +msgid "GitHub Organization OAuth2 Key" +msgstr "GitHub 組織 OAuth2 キー" + +#: sso/conf.py:699 +#: sso/conf.py:774 +msgid "The OAuth2 key (Client ID) from your GitHub organization application." +msgstr "GitHub 組織アプリケーションからの OAuth2 キー (クライアント ID)。" + +#: sso/conf.py:708 +msgid "GitHub Organization OAuth2 Secret" +msgstr "GitHub 組織 OAuth2 シークレット" + +#: sso/conf.py:709 +#: sso/conf.py:784 +msgid "" +"The OAuth2 secret (Client Secret) from your GitHub organization application." +msgstr "GitHub 組織アプリケーションからの OAuth2 シークレット (クライアントシークレット)。" + +#: sso/conf.py:719 +msgid "GitHub Organization Name" +msgstr "GitHub 組織名" + +#: sso/conf.py:720 +msgid "" +"The name of your GitHub organization, as used in your organization's URL: " +"https://github.com//." +msgstr "GitHub 組織の名前で、組織の URL (https://github.com//) で使用されます。" + +#: sso/conf.py:731 +msgid "GitHub Organization OAuth2 Organization Map" +msgstr "GitHub 組織 OAuth2 組織マップ" + +#: sso/conf.py:743 +msgid "GitHub Organization OAuth2 Team Map" +msgstr "GitHub 組織 OAuth2 チームマップ" + +#: sso/conf.py:759 +msgid "GitHub Team OAuth2 Callback URL" +msgstr "GitHub チーム OAuth2 コールバック URL" + +#: sso/conf.py:764 +#: sso/conf.py:775 +#: sso/conf.py:785 +#: sso/conf.py:797 +#: sso/conf.py:808 +#: sso/conf.py:820 +msgid "GitHub Team OAuth2" +msgstr "GitHub チーム OAuth2" + +#: sso/conf.py:773 +msgid "GitHub Team OAuth2 Key" +msgstr "GitHub チーム OAuth2 キー" + +#: sso/conf.py:783 +msgid "GitHub Team OAuth2 Secret" +msgstr "GitHub チーム OAuth2 シークレット" + +#: sso/conf.py:794 +msgid "GitHub Team ID" +msgstr "GitHub チーム ID" + +#: sso/conf.py:795 +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 "" +"Github API を使用して数値のチーム ID を検索します: http://fabian-kostadinov.github.io/2015/01/" +"16/how-to-find-a-github-team-id/" + +#: sso/conf.py:806 +msgid "GitHub Team OAuth2 Organization Map" +msgstr "GitHub チーム OAuth2 組織マップ" + +#: sso/conf.py:818 +msgid "GitHub Team OAuth2 Team Map" +msgstr "GitHub チーム OAuth2 チームマップ" + +#: sso/conf.py:834 +msgid "Azure AD OAuth2 Callback URL" +msgstr "Azure AD OAuth2 コールバック URL" + +#: sso/conf.py:835 +msgid "" +"Register an Azure AD application as described by https://msdn.microsoft.com/" +"en-us/library/azure/dn132599.aspx and obtain an OAuth2 key (Client ID) and " +"secret (Client Secret). Provide this URL as the callback URL for your " +"application." +msgstr "" +"Azure AD アプリケーションを https://msdn.microsoft.com/en-us/library/azure/dn132599." +"aspx の説明に従って登録し、OAuth2 キー (クライアント ID) およびシークレット (クライアントシークレット) を取得します。この URL " +"をアプリケーションのコールバック URL として指定します。" + +#: sso/conf.py:839 +#: sso/conf.py:850 +#: sso/conf.py:860 +#: sso/conf.py:872 +#: sso/conf.py:884 +msgid "Azure AD OAuth2" +msgstr "Azure AD OAuth2" + +#: sso/conf.py:848 +msgid "Azure AD OAuth2 Key" +msgstr "Azure AD OAuth2 キー" + +#: sso/conf.py:849 +msgid "The OAuth2 key (Client ID) from your Azure AD application." +msgstr "Azure AD アプリケーションからの OAuth2 キー (クライアント ID)。" + +#: sso/conf.py:858 +msgid "Azure AD OAuth2 Secret" +msgstr "Azure AD OAuth2 シークレット" + +#: sso/conf.py:859 +msgid "The OAuth2 secret (Client Secret) from your Azure AD application." +msgstr "Azure AD アプリケーションからの OAuth2 シークレット (クライアントシークレット)。" + +#: sso/conf.py:870 +msgid "Azure AD OAuth2 Organization Map" +msgstr "Azure AD OAuth2 組織マップ" + +#: sso/conf.py:882 +msgid "Azure AD OAuth2 Team Map" +msgstr "Azure AD OAuth2 チームマップ" + +#: sso/conf.py:903 +msgid "SAML Service Provider Callback URL" +msgstr "SAML サービスプロバイダーコールバック URL" + +#: sso/conf.py:904 +msgid "" +"Register Tower as a service provider (SP) with each identity provider (IdP) " +"you have configured. Provide your SP Entity ID and this callback URL for " +"your application." +msgstr "" +"設定済みの各アイデンティティープロバイダー (IdP) で Tower をサービスプロバイダー (SP) として登録します。SP エンティティー ID " +"およびアプリケーションのこのコールバック URL を指定します。" + +#: sso/conf.py:907 +#: sso/conf.py:921 +#: sso/conf.py:934 +#: sso/conf.py:948 +#: sso/conf.py:962 +#: sso/conf.py:980 +#: sso/conf.py:1002 +#: sso/conf.py:1021 +#: sso/conf.py:1041 +#: sso/conf.py:1075 +#: sso/conf.py:1088 +msgid "SAML" +msgstr "SAML" + +#: sso/conf.py:918 +msgid "SAML Service Provider Metadata URL" +msgstr "SAML サービスプロバイダーメタデータ URL" + +#: sso/conf.py:919 +msgid "" +"If your identity provider (IdP) allows uploading an XML metadata file, you " +"can download one from this URL." +msgstr "" +"アイデンティティープロバイダー (IdP) が XML メタデータファイルのアップロードを許可する場合、この URL からダウンロードできます。" + +#: sso/conf.py:931 +msgid "SAML Service Provider Entity ID" +msgstr "SAML サービスプロバイダーエンティティー ID" + +#: sso/conf.py:932 +msgid "" +"The application-defined unique identifier used as the audience of the SAML " +"service provider (SP) configuration." +msgstr "SAML サービスプロバイダー (SP) 設定の対象として使用されるアプリケーションで定義される固有識別子。" + +#: sso/conf.py:945 +msgid "SAML Service Provider Public Certificate" +msgstr "SAML サービスプロバイダーの公開証明書" + +#: sso/conf.py:946 +msgid "" +"Create a keypair for Tower to use as a service provider (SP) and include the " +"certificate content here." +msgstr "サービスプロバイダー (SP) として使用するための Tower のキーペアを作成し、ここに証明書の内容を組み込みます。" + +#: sso/conf.py:959 +msgid "SAML Service Provider Private Key" +msgstr "SAML サービスプロバイダーの秘密鍵|" + +#: sso/conf.py:960 +msgid "" +"Create a keypair for Tower to use as a service provider (SP) and include the " +"private key content here." +msgstr "サービスプロバイダー (SP) として使用するための Tower のキーペアを作成し、ここに秘密鍵の内容を組み込みます。" + +#: sso/conf.py:978 +msgid "SAML Service Provider Organization Info" +msgstr "SAML サービスプロバイダーの組織情報" + +#: sso/conf.py:979 +msgid "Configure this setting with information about your app." +msgstr "アプリの情報でこの設定を行います。" + +#: sso/conf.py:1000 +msgid "SAML Service Provider Technical Contact" +msgstr "SAML サービスプロバイダーテクニカルサポートの問い合わせ先" + +#: sso/conf.py:1001 +#: sso/conf.py:1020 +msgid "Configure this setting with your contact information." +msgstr "問い合わせ先情報で設定を行います。" + +#: sso/conf.py:1019 +msgid "SAML Service Provider Support Contact" +msgstr "SAML サービスプロバイダーサポートの問い合わせ先" + +#: sso/conf.py:1034 +msgid "SAML Enabled Identity Providers" +msgstr "SAML で有効にされたアイデンティティープロバイダー" + +#: sso/conf.py:1035 +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 " +"data using attribute names that differ from the default OIDs (https://github." +"com/omab/python-social-auth/blob/master/social/backends/saml.py#L16). " +"Attribute names may be overridden for each IdP." +msgstr "" +"使用中のそれぞれのアイデンティティープロバイダー (IdP) についてのエンティティー ID、SSO URL および証明書を設定します。複数の SAML " +"IdP がサポートされます。一部の IdP はデフォルト OID とは異なる属性名を使用してユーザーデータを提供することがあります (https://" +"github.com/omab/python-social-auth/blob/master/social/backends/saml." +"py#L16)。それぞれの IdP の属性名を上書きできます。" + +#: sso/conf.py:1073 +msgid "SAML Organization Map" +msgstr "SAML 組織マップ" + +#: sso/conf.py:1086 +msgid "SAML Team Map" +msgstr "SAML チームマップ" + +#: sso/fields.py:123 +#, python-brace-format +msgid "Invalid connection option(s): {invalid_options}." +msgstr "無効な接続オプション: {invalid_options}" + +#: sso/fields.py:182 +msgid "Base" +msgstr "ベース" + +#: sso/fields.py:183 +msgid "One Level" +msgstr "1 レベル" + +#: sso/fields.py:184 +msgid "Subtree" +msgstr "サブツリー" + +#: sso/fields.py:202 +#, python-brace-format +msgid "Expected a list of three items but got {length} instead." +msgstr "3 つの項目の一覧が予期されましが、{length} が取得されました。" + +#: sso/fields.py:203 +#, python-brace-format +msgid "Expected an instance of LDAPSearch but got {input_type} instead." +msgstr "LDAPSearch のインスタンスが予期されましたが、{input_type} が取得されました。" + +#: sso/fields.py:239 +#, python-brace-format +msgid "" +"Expected an instance of LDAPSearch or LDAPSearchUnion but got {input_type} " +"instead." +msgstr "" +"LDAPSearch または LDAPSearchUnion のインスタンスが予期されましたが、{input_type} が取得されました。" + +#: sso/fields.py:266 +#, python-brace-format +msgid "Invalid user attribute(s): {invalid_attrs}." +msgstr "無効なユーザー属性: {invalid_attrs}" + +#: sso/fields.py:283 +#, python-brace-format +msgid "Expected an instance of LDAPGroupType but got {input_type} instead." +msgstr "LDAPGroupType のインスタンスが予期されましたが、{input_type} が取得されました。" + +#: sso/fields.py:308 +#, python-brace-format +msgid "Invalid user flag: \"{invalid_flag}\"." +msgstr "無効なユーザーフラグ: \"{invalid_flag}\"" + +#: sso/fields.py:324 +#: sso/fields.py:491 +#, python-brace-format +msgid "" +"Expected None, True, False, a string or list of strings but got {input_type} " +"instead." +msgstr "None、True、False、文字列または文字列の一覧が予期されましたが、{input_type} が取得されました。" + +#: sso/fields.py:360 +#, python-brace-format +msgid "Missing key(s): {missing_keys}." +msgstr "キーがありません: {missing_keys}" + +#: sso/fields.py:361 +#, python-brace-format +msgid "Invalid key(s): {invalid_keys}." +msgstr "無効なキー: {invalid_keys}" + +#: sso/fields.py:410 +#: sso/fields.py:527 +#, python-brace-format +msgid "Invalid key(s) for organization map: {invalid_keys}." +msgstr "組織マップの無効なキー: {invalid_keys}" + +#: sso/fields.py:428 +#, python-brace-format +msgid "Missing required key for team map: {invalid_keys}." +msgstr "チームマップの必要なキーがありません: {invalid_keys}" + +#: sso/fields.py:429 +#: sso/fields.py:546 +#, python-brace-format +msgid "Invalid key(s) for team map: {invalid_keys}." +msgstr "チームマップの無効なキー: {invalid_keys}" + +#: sso/fields.py:545 +#, python-brace-format +msgid "Missing required key for team map: {missing_keys}." +msgstr "チームマップで必要なキーがありません: {missing_keys}" + +#: sso/fields.py:563 +#, python-brace-format +msgid "Missing required key(s) for org info record: {missing_keys}." +msgstr "組織情報レコードで必要なキーがありません: {missing_keys}" + +#: sso/fields.py:576 +#, python-brace-format +msgid "Invalid language code(s) for org info: {invalid_lang_codes}." +msgstr "組織情報の無効な言語コード: {invalid_lang_codes}" + +#: sso/fields.py:595 +#, python-brace-format +msgid "Missing required key(s) for contact: {missing_keys}." +msgstr "問い合わせ先の必要なキーがありません: {missing_keys}" + +#: sso/fields.py:607 +#, python-brace-format +msgid "Missing required key(s) for IdP: {missing_keys}." +msgstr "IdP で必要なキーがありません: {missing_keys}" + +#: sso/pipeline.py:24 +#, python-brace-format +msgid "An account cannot be found for {0}" +msgstr "{0} のアカウントが見つかりません" + +#: sso/pipeline.py:30 +msgid "Your account is inactive" +msgstr "アカウントが非アクティブです" + +#: sso/validators.py:19 +#: sso/validators.py:44 +#, python-format +msgid "DN must include \"%%(user)s\" placeholder for username: %s" +msgstr "DN にはユーザー名の \"%%(user)s\" プレースホルダーを含める必要があります: %s" + +#: sso/validators.py:26 +#, python-format +msgid "Invalid DN: %s" +msgstr "無効な DN: %s" + +#: sso/validators.py:56 +#, python-format +msgid "Invalid filter: %s" +msgstr "無効なフィルター: %s" + +#: templates/error.html:4 +#: ui/templates/ui/index.html:8 +msgid "Ansible Tower" +msgstr "Ansible Tower" + +#: templates/rest_framework/api.html:39 +msgid "Ansible Tower API Guide" +msgstr "Ansible Tower API ガイド" + +#: templates/rest_framework/api.html:40 +msgid "Back to Ansible Tower" +msgstr "Ansible Tower に戻る" + +#: templates/rest_framework/api.html:41 +msgid "Resize" +msgstr "サイズの変更" + +#: templates/rest_framework/base.html:78 +#: templates/rest_framework/base.html:92 +#, python-format +msgid "Make a GET request on the %(name)s resource" +msgstr "%(name)s リソースでの GET 要求" + +#: templates/rest_framework/base.html:80 +msgid "Specify a format for the GET request" +msgstr "GET 要求の形式を指定" + +#: templates/rest_framework/base.html:86 +#, python-format +msgid "" +"Make a GET request on the %(name)s resource with the format set to " +"`%(format)s`" +msgstr "形式が `%(format)s` に設定された状態での %(name)s リソースでの GET 要求" + +#: templates/rest_framework/base.html:100 +#, python-format +msgid "Make an OPTIONS request on the %(name)s resource" +msgstr "%(name)s リソースでの OPTIONS 要求" + +#: templates/rest_framework/base.html:106 +#, python-format +msgid "Make a DELETE request on the %(name)s resource" +msgstr "%(name)s リソースでの DELETE 要求" + +#: templates/rest_framework/base.html:113 +msgid "Filters" +msgstr "フィルター" + +#: templates/rest_framework/base.html:172 +#: templates/rest_framework/base.html:186 +#, python-format +msgid "Make a POST request on the %(name)s resource" +msgstr "%(name)s リソースでの POST 要求" + +#: templates/rest_framework/base.html:216 +#: templates/rest_framework/base.html:230 +#, python-format +msgid "Make a PUT request on the %(name)s resource" +msgstr "%(name)s リソースでの PUT 要求" + +#: templates/rest_framework/base.html:233 +#, python-format +msgid "Make a PATCH request on the %(name)s resource" +msgstr "%(name)s リソースでの PATCH 要求" + +#: ui/apps.py:9 +#: ui/conf.py:22 +#: ui/conf.py:38 +#: ui/conf.py:53 +msgid "UI" +msgstr "UI" + +#: ui/conf.py:16 +msgid "Off" +msgstr "オフ" + +#: ui/conf.py:17 +msgid "Anonymous" +msgstr "匿名" + +#: ui/conf.py:18 +msgid "Detailed" +msgstr "詳細" + +#: ui/conf.py:20 +msgid "Analytics Tracking State" +msgstr "アナリティクストラッキングの状態" + +#: ui/conf.py:21 +msgid "Enable or Disable Analytics Tracking." +msgstr "アナリティクストラッキングの有効化/無効化。" + +#: ui/conf.py:31 +msgid "Custom Login Info" +msgstr "カスタムログイン情報" + +#: ui/conf.py:32 +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. If multiple paragraphs of text are needed, new lines " +"(paragraphs) must be escaped as `\\n` within the block of text." +msgstr "" +"必要な場合は、この設定を使ってログインモーダルのテキストボックスに特定の情報 (法律上の通知または免責事項など) " +"を追加できます。追加されるすべてのコンテンツは、カスタム HTML " +"や他のマークアップ言語がサポートされないため、プレーンテキストでなければなりません。テキストの複数のパラグラフが必要な場合、改行 (パラグラフ) " +"をテキストのブロック内の `\\n` としてエスケープする必要があります。" + +#: ui/conf.py:48 +msgid "Custom Logo" +msgstr "カスタムロゴ" + +#: ui/conf.py:49 +msgid "" +"To set up a custom logo, provide a file that you create. For the custom logo " +"to look its best, use a `.png` file with a transparent background. GIF, PNG " +"and JPEG formats are supported." +msgstr "" +"カスタムロゴをセットアップするには、作成するファイルを指定します。カスタムロゴを最適化するには、背景が透明の「." +"png」ファイルを使用します。GIF、PNG および JPEG 形式がサポートされます。" + +#: ui/fields.py:29 +msgid "" +"Invalid format for custom logo. Must be a data URL with a base64-encoded " +"GIF, PNG or JPEG image." +msgstr "" +"カスタムロゴの無効な形式です。base64 エンコードされた GIF、PNG または JPEG イメージと共にデータ URL を指定する必要があります。" + +#: ui/fields.py:30 +msgid "Invalid base64-encoded data in data URL." +msgstr "データ URL の無効な base64 エンコードされたデータ。" + +#: ui/templates/ui/index.html:49 +msgid "" +"Your session will expire in 60 seconds, would you like to continue?" +msgstr "" +"セッションは 60 秒後に期限切れになります。続行しますか?" + +#: ui/templates/ui/index.html:64 +msgid "CANCEL" +msgstr "取り消し" + +#: ui/templates/ui/index.html:116 +msgid "Set how many days of data should be retained." +msgstr "データの保持日数を設定します。" + +#: ui/templates/ui/index.html:122 +msgid "" +"Please enter an integer that is not " +"negative that is lower than 9999." +msgstr "" +"負でない 9999 より値の小さい整数を入力してください。" + +#: ui/templates/ui/index.html:127 +msgid "" +"For facts collected older than the time period specified, save one fact scan " +"(snapshot) per time window (frequency). For example, facts older than 30 " +"days are purged, while one weekly fact scan is kept.\n" +"
\n" +"
CAUTION: Setting both numerical variables to \"0\" " +"will delete all facts.\n" +"
\n" +"
" +msgstr "" +"指定された期間の前に収集されたファクトについては、時間枠 (頻度) ごとに 1 つのファクトスキャン (スナップショット) を保存します。たとえば、30 " +"日間の前のファクトは削除され、1 つの週次ファクトは保持されます。\n" +"
\n" +"
注意: どちらの数値変数も「0」に設定すると、すべてのファクトが削除されます。\n" +"
\n" +"
" + +#: ui/templates/ui/index.html:136 +msgid "Select a time period after which to remove old facts" +msgstr "古いファクトを削除するまでの期間を選択" + +#: ui/templates/ui/index.html:150 +msgid "" +"Please enter an integer " +"that is not negative " +"that is lower than 9999." +msgstr "" +"負でない 9999 より値の小さい整数を入力してください。" + +#: ui/templates/ui/index.html:155 +msgid "Select a frequency for snapshot retention" +msgstr "スナップショットの保持頻度を選択" + +#: ui/templates/ui/index.html:169 +msgid "" +"Please enter an integer that is not negative that is " +"lower than 9999." +msgstr "" +"負でない " +"9999 よりも値の小さい整数を入力してください。" + +#: ui/templates/ui/index.html:175 +msgid "working..." +msgstr "実行中..." + diff --git a/awx/main/access.py b/awx/main/access.py index 1de7049426..460dfe7b4c 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -353,7 +353,7 @@ class BaseAccess(object): # Shortcuts in certain cases by deferring to earlier property if display_method == 'schedule': - user_capabilities['schedule'] = user_capabilities['edit'] + user_capabilities['schedule'] = user_capabilities['start'] continue elif display_method == 'delete' and not isinstance(obj, (User, UnifiedJob)): user_capabilities['delete'] = user_capabilities['edit'] @@ -363,27 +363,30 @@ class BaseAccess(object): continue # Compute permission - data = {} - access_method = getattr(self, "can_%s" % method) - if method in ['change']: # 3 args - user_capabilities[display_method] = access_method(obj, data) - elif method in ['delete', 'run_ad_hoc_commands', 'copy']: - user_capabilities[display_method] = access_method(obj) - elif method in ['start']: - user_capabilities[display_method] = access_method(obj, validate_license=False) - elif method in ['add']: # 2 args with data - user_capabilities[display_method] = access_method(data) - elif method in ['attach', 'unattach']: # parent/sub-object call - if type(parent_obj) == Team: - relationship = 'parents' - parent_obj = parent_obj.member_role - else: - relationship = 'members' - user_capabilities[display_method] = access_method( - obj, parent_obj, relationship, skip_sub_obj_read_check=True, data=data) + user_capabilities[display_method] = self.get_method_capability(method, obj, parent_obj) return user_capabilities + def get_method_capability(self, method, obj, parent_obj): + if method in ['change']: # 3 args + return self.can_change(obj, {}) + elif method in ['delete', 'run_ad_hoc_commands', 'copy']: + access_method = getattr(self, "can_%s" % method) + return access_method(obj) + elif method in ['start']: + return self.can_start(obj, validate_license=False) + elif method in ['add']: # 2 args with data + return self.can_add({}) + elif method in ['attach', 'unattach']: # parent/sub-object call + access_method = getattr(self, "can_%s" % method) + if type(parent_obj) == Team: + relationship = 'parents' + parent_obj = parent_obj.member_role + else: + relationship = 'members' + return access_method(obj, parent_obj, relationship, skip_sub_obj_read_check=True, data={}) + return False + class UserAccess(BaseAccess): ''' @@ -982,8 +985,6 @@ class ProjectUpdateAccess(BaseAccess): @check_superuser def can_cancel(self, obj): - if not obj.can_cancel: - return False if self.user == obj.created_by: return True # Project updates cascade delete with project, admin role descends from org admin @@ -1040,7 +1041,7 @@ class JobTemplateAccess(BaseAccess): Project.accessible_objects(self.user, 'use_role').exists() or Inventory.accessible_objects(self.user, 'use_role').exists()) - # if reference_obj is provided, determine if it can be coppied + # if reference_obj is provided, determine if it can be copied reference_obj = data.get('reference_obj', None) if 'job_type' in data and data['job_type'] == PERM_INVENTORY_SCAN: @@ -1392,7 +1393,8 @@ class WorkflowJobTemplateNodeAccess(BaseAccess): qs = self.model.objects.filter( workflow_job_template__in=WorkflowJobTemplate.accessible_objects( self.user, 'read_role')) - qs = qs.prefetch_related('success_nodes', 'failure_nodes', 'always_nodes') + qs = qs.prefetch_related('success_nodes', 'failure_nodes', 'always_nodes', + 'unified_job_template') return qs def can_use_prompted_resources(self, data): @@ -1478,8 +1480,14 @@ class WorkflowJobNodeAccess(BaseAccess): qs = qs.prefetch_related('success_nodes', 'failure_nodes', 'always_nodes') return qs + @check_superuser def can_add(self, data): - return False + if data is None: # Hide direct creation in API browser + return False + return ( + self.check_related('unified_job_template', UnifiedJobTemplate, data, role_field='execute_role') and + self.check_related('credential', Credential, data, role_field='use_role') and + self.check_related('inventory', Inventory, data, role_field='use_role')) def can_change(self, obj, data): return False @@ -1528,22 +1536,28 @@ class WorkflowJobTemplateAccess(BaseAccess): def can_copy(self, obj): if self.save_messages: - wfjt_errors = {} + missing_ujt = [] + missing_credentials = [] + missing_inventories = [] qs = obj.workflow_job_template_nodes qs.select_related('unified_job_template', 'inventory', 'credential') for node in qs.all(): node_errors = {} if node.inventory and self.user not in node.inventory.use_role: - node_errors['inventory'] = 'Prompted inventory %s can not be coppied.' % node.inventory.name + missing_inventories.append(node.inventory.name) if node.credential and self.user not in node.credential.use_role: - node_errors['credential'] = 'Prompted credential %s can not be coppied.' % node.credential.name + missing_credentials.append(node.credential.name) ujt = node.unified_job_template if ujt and not self.user.can_access(UnifiedJobTemplate, 'start', ujt, validate_license=False): - node_errors['unified_job_template'] = ( - 'Prompted %s %s can not be coppied.' % (ujt._meta.verbose_name_raw, ujt.name)) + missing_ujt.append(ujt.name) if node_errors: wfjt_errors[node.id] = node_errors - self.messages.update(wfjt_errors) + if missing_ujt: + self.messages['templates_unable_to_copy'] = missing_ujt + if missing_credentials: + self.messages['credentials_unable_to_copy'] = missing_credentials + if missing_inventories: + self.messages['inventories_unable_to_copy'] = missing_inventories return self.check_related('organization', Organization, {'reference_obj': obj}, mandatory=True) @@ -1611,11 +1625,19 @@ class WorkflowJobAccess(BaseAccess): def can_change(self, obj, data): return False + @check_superuser def can_delete(self, obj): - if obj.workflow_job_template is None: - # only superusers can delete orphaned workflow jobs - return self.user.is_superuser - return self.user in obj.workflow_job_template.admin_role + return (obj.workflow_job_template and + obj.workflow_job_template.organization and + self.user in obj.workflow_job_template.organization.admin_role) + + def get_method_capability(self, method, obj, parent_obj): + if method == 'start': + # Return simplistic permission, will perform detailed check on POST + if not obj.workflow_job_template: + return self.user.is_superuser + return self.user in obj.workflow_job_template.execute_role + return super(WorkflowJobAccess, self).get_method_capability(method, obj, parent_obj) def can_start(self, obj, validate_license=True): if validate_license: @@ -1624,7 +1646,29 @@ class WorkflowJobAccess(BaseAccess): if self.user.is_superuser: return True - return (obj.workflow_job_template and self.user in obj.workflow_job_template.execute_role) + wfjt = obj.workflow_job_template + # only superusers can relaunch orphans + if not wfjt: + return False + + # execute permission to WFJT is mandatory for any relaunch + if self.user not in wfjt.execute_role: + return False + + # user's WFJT access doesn't guarentee permission to launch, introspect nodes + return self.can_recreate(obj) + + def can_recreate(self, obj): + node_qs = obj.workflow_job_nodes.all().prefetch_related('inventory', 'credential', 'unified_job_template') + node_access = WorkflowJobNodeAccess(user=self.user) + wj_add_perm = True + for node in node_qs: + if not node_access.can_add({'reference_obj': node}): + wj_add_perm = False + if not wj_add_perm and self.save_messages: + self.messages['workflow_job_template'] = _('You do not have permission to the workflow job ' + 'resources required for relaunch.') + return wj_add_perm def can_cancel(self, obj): if not obj.can_cancel: @@ -1912,11 +1956,17 @@ class ScheduleAccess(BaseAccess): @check_superuser def can_add(self, data): - return self.check_related('unified_job_template', UnifiedJobTemplate, data, mandatory=True) + return self.check_related('unified_job_template', UnifiedJobTemplate, data, role_field='execute_role', mandatory=True) @check_superuser def can_change(self, obj, data): - return self.check_related('unified_job_template', UnifiedJobTemplate, data, obj=obj, mandatory=True) + if self.check_related('unified_job_template', UnifiedJobTemplate, data, obj=obj, mandatory=True): + return True + # Users with execute role can modify the schedules they created + return ( + obj.created_by == self.user and + self.check_related('unified_job_template', UnifiedJobTemplate, data, obj=obj, role_field='execute_role', mandatory=True)) + def can_delete(self, obj): return self.can_change(obj, {}) diff --git a/awx/main/management/commands/cleanup_facts.py b/awx/main/management/commands/cleanup_facts.py index a709f81c1a..f6b3c76b26 100644 --- a/awx/main/management/commands/cleanup_facts.py +++ b/awx/main/management/commands/cleanup_facts.py @@ -96,12 +96,12 @@ class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('--older_than', dest='older_than', - default=None, - help='Specify the relative time to consider facts older than (w)eek (d)ay or (y)ear (i.e. 5d, 2w, 1y).'), + default='30d', + help='Specify the relative time to consider facts older than (w)eek (d)ay or (y)ear (i.e. 5d, 2w, 1y). Defaults to 30d.'), make_option('--granularity', dest='granularity', - default=None, - help='Window duration to group same hosts by for deletion (w)eek (d)ay or (y)ear (i.e. 5d, 2w, 1y).'), + default='1w', + help='Window duration to group same hosts by for deletion (w)eek (d)ay or (y)ear (i.e. 5d, 2w, 1y). Defaults to 1w.'), make_option('--module', dest='module', default=None, diff --git a/awx/main/management/commands/cleanup_jobs.py b/awx/main/management/commands/cleanup_jobs.py index 3f7270c9b2..536ce61e39 100644 --- a/awx/main/management/commands/cleanup_jobs.py +++ b/awx/main/management/commands/cleanup_jobs.py @@ -12,7 +12,7 @@ from django.db import transaction from django.utils.timezone import now # AWX -from awx.main.models import Job, AdHocCommand, ProjectUpdate, InventoryUpdate, SystemJob +from awx.main.models import Job, AdHocCommand, ProjectUpdate, InventoryUpdate, SystemJob, WorkflowJob class Command(NoArgsCommand): @@ -30,19 +30,22 @@ class Command(NoArgsCommand): 'be removed)'), make_option('--jobs', dest='only_jobs', action='store_true', default=False, - help='Only remove jobs'), + help='Remove jobs'), make_option('--ad-hoc-commands', dest='only_ad_hoc_commands', action='store_true', default=False, - help='Only remove ad hoc commands'), + help='Remove ad hoc commands'), make_option('--project-updates', dest='only_project_updates', action='store_true', default=False, - help='Only remove project updates'), + help='Remove project updates'), make_option('--inventory-updates', dest='only_inventory_updates', action='store_true', default=False, - help='Only remove inventory updates'), + help='Remove inventory updates'), make_option('--management-jobs', default=False, action='store_true', dest='only_management_jobs', - help='Only remove management jobs') + help='Remove management jobs'), + make_option('--workflow-jobs', default=False, + action='store_true', dest='only_workflow_jobs', + help='Remove workflow jobs') ) def cleanup_jobs(self): @@ -169,6 +172,28 @@ class Command(NoArgsCommand): self.logger.addHandler(handler) self.logger.propagate = False + def cleanup_workflow_jobs(self): + skipped, deleted = 0, 0 + for workflow_job in WorkflowJob.objects.all(): + workflow_job_display = '"{}" (started {}, {} nodes)'.format( + unicode(workflow_job), unicode(workflow_job.created), + workflow_job.workflow_nodes.count()) + if workflow_job.status in ('pending', 'waiting', 'running'): + action_text = 'would skip' if self.dry_run else 'skipping' + self.logger.debug('%s %s job %s', action_text, workflow_job.status, workflow_job_display) + skipped += 1 + elif workflow_job.created >= self.cutoff: + action_text = 'would skip' if self.dry_run else 'skipping' + self.logger.debug('%s %s', action_text, workflow_job_display) + skipped += 1 + else: + action_text = 'would delete' if self.dry_run else 'deleting' + self.logger.info('%s %s', action_text, workflow_job_display) + if not self.dry_run: + workflow_job.delete() + deleted += 1 + return skipped, deleted + @transaction.atomic def handle_noargs(self, **options): self.verbosity = int(options.get('verbosity', 1)) @@ -179,7 +204,7 @@ class Command(NoArgsCommand): self.cutoff = now() - datetime.timedelta(days=self.days) except OverflowError: raise CommandError('--days specified is too large. Try something less than 99999 (about 270 years).') - model_names = ('jobs', 'ad_hoc_commands', 'project_updates', 'inventory_updates', 'management_jobs') + model_names = ('jobs', 'ad_hoc_commands', 'project_updates', 'inventory_updates', 'management_jobs', 'workflow_jobs') models_to_cleanup = set() for m in model_names: if options.get('only_%s' % m, False): diff --git a/awx/main/management/commands/inventory_import.py b/awx/main/management/commands/inventory_import.py index 5c8c9df9c4..c1399e1a11 100644 --- a/awx/main/management/commands/inventory_import.py +++ b/awx/main/management/commands/inventory_import.py @@ -64,7 +64,7 @@ class MemObject(object): all_vars = {} files_found = 0 for suffix in ('', '.yml', '.yaml', '.json'): - path = ''.join([base_path, suffix]) + path = ''.join([base_path, suffix]).encode("utf-8") if not os.path.exists(path): continue if not os.path.isfile(path): @@ -462,7 +462,7 @@ class ExecutableJsonLoader(BaseLoader): # to set their variables for k,v in self.all_group.all_hosts.iteritems(): if 'hostvars' not in _meta: - data = self.command_to_json([self.source, '--host', k]) + data = self.command_to_json([self.source, '--host', k.encode("utf-8")]) else: data = _meta['hostvars'].get(k, {}) if isinstance(data, dict): diff --git a/awx/main/models/ad_hoc_commands.py b/awx/main/models/ad_hoc_commands.py index 27d8754aa6..057924eda7 100644 --- a/awx/main/models/ad_hoc_commands.py +++ b/awx/main/models/ad_hoc_commands.py @@ -20,7 +20,7 @@ from django.core.urlresolvers import reverse # AWX from awx.main.models.base import * # noqa from awx.main.models.unified_jobs import * # noqa -from awx.main.models.notifications import JobNotificationMixin +from awx.main.models.notifications import JobNotificationMixin, NotificationTemplate from awx.main.fields import JSONField logger = logging.getLogger('awx.main.models.ad_hoc_commands') @@ -157,18 +157,20 @@ class AdHocCommand(UnifiedJob, JobNotificationMixin): @property def notification_templates(self): - all_inventory_sources = set() + all_orgs = set() for h in self.hosts.all(): - for invsrc in h.inventory_sources.all(): - all_inventory_sources.add(invsrc) + all_orgs.add(h.inventory.organization) active_templates = dict(error=set(), success=set(), any=set()) - for invsrc in all_inventory_sources: - notifications_dict = invsrc.notification_templates - for notification_type in active_templates.keys(): - for templ in notifications_dict[notification_type]: - active_templates[notification_type].add(templ) + base_notification_templates = NotificationTemplate.objects + for org in all_orgs: + for templ in base_notification_templates.filter(organization_notification_templates_for_errors=org): + active_templates['error'].add(templ) + for templ in base_notification_templates.filter(organization_notification_templates_for_success=org): + active_templates['success'].add(templ) + for templ in base_notification_templates.filter(organization_notification_templates_for_any=org): + active_templates['any'].add(templ) active_templates['error'] = list(active_templates['error']) active_templates['any'] = list(active_templates['any']) active_templates['success'] = list(active_templates['success']) diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index e7183f356d..b01d44802c 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -1002,9 +1002,8 @@ class InventorySourceOptions(BaseModel): if r not in valid_regions and r not in invalid_regions: invalid_regions.append(r) if invalid_regions: - raise ValidationError(_('Invalid %(source)s region%(plural)s: %(region)s') % { - 'source': self.source, 'plural': '' if len(invalid_regions) == 1 else 's', - 'region': ', '.join(invalid_regions)}) + raise ValidationError(_('Invalid %(source)s region: %(region)s') % { + 'source': self.source, 'region': ', '.join(invalid_regions)}) return ','.join(regions) source_vars_dict = VarsDictProperty('source_vars') @@ -1028,9 +1027,8 @@ class InventorySourceOptions(BaseModel): if instance_filter_name not in self.INSTANCE_FILTER_NAMES: invalid_filters.append(instance_filter) if invalid_filters: - raise ValidationError(_('Invalid filter expression%(plural)s: %(filter)s') % - {'plural': '' if len(invalid_filters) == 1 else 's', - 'filter': ', '.join(invalid_filters)}) + raise ValidationError(_('Invalid filter expression: %(filter)s') % + {'filter': ', '.join(invalid_filters)}) return instance_filters def clean_group_by(self): @@ -1047,9 +1045,8 @@ class InventorySourceOptions(BaseModel): if c not in valid_choices and c not in invalid_choices: invalid_choices.append(c) if invalid_choices: - raise ValidationError(_('Invalid group by choice%(plural)s: %(choice)s') % - {'plural': '' if len(invalid_choices) == 1 else 's', - 'choice': ', '.join(invalid_choices)}) + raise ValidationError(_('Invalid group by choice: %(choice)s') % + {'choice': ', '.join(invalid_choices)}) return ','.join(choices) diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 8a6b9fc91d..514b37db36 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -606,6 +606,11 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin): evars.update(extra_vars) self.update_fields(extra_vars=json.dumps(evars)) + def _resources_sufficient_for_launch(self): + if self.job_type == PERM_INVENTORY_SCAN: + return self.inventory_id is not None + return not (self.inventory_id is None or self.project_id is None) + def display_artifacts(self): ''' Hides artifacts if they are marked as no_log type artifacts. @@ -1175,7 +1180,6 @@ class JobEvent(CreatedModifiedModel): # Save UUID and parent UUID for determining parent-child relationship. job_event_uuid = kwargs.get('uuid', None) parent_event_uuid = kwargs.get('parent_uuid', None) - artifact_dict = kwargs.get('artifact_data', None) # Sanity check: Don't honor keys that we don't recognize. valid_keys = {'job_id', 'event', 'event_data', 'playbook', 'play', @@ -1185,6 +1189,11 @@ class JobEvent(CreatedModifiedModel): if key not in valid_keys: kwargs.pop(key) + event_data = kwargs.get('event_data', None) + artifact_dict = None + if event_data: + artifact_dict = event_data.pop('artifact_data', None) + # Try to find a parent event based on UUID. if parent_event_uuid: cache_key = '{}_{}'.format(kwargs['job_id'], parent_event_uuid) @@ -1208,12 +1217,21 @@ class JobEvent(CreatedModifiedModel): # Save artifact data to parent job (if provided). if artifact_dict: - event_data = kwargs.get('event_data', None) if event_data and isinstance(event_data, dict): - res = event_data.get('res', None) - if res and isinstance(res, dict): - if res.get('_ansible_no_log', False): - artifact_dict['_ansible_no_log'] = True + # Note: Core has not added support for marking artifacts as + # sensitive yet. Going forward, core will not use + # _ansible_no_log to denote sensitive set_stats calls. + # Instead, they plan to add a flag outside of the traditional + # no_log mechanism. no_log will not work for this feature, + # in core, because sensitive data is scrubbed before sending + # data to the callback. The playbook_on_stats is the callback + # in which the set_stats data is used. + + # Again, the sensitive artifact feature has not yet landed in + # core. The below is how we mark artifacts payload as + # senstive + # artifact_dict['_ansible_no_log'] = True + # parent_job = Job.objects.filter(pk=kwargs['job_id']).first() if parent_job and parent_job.artifacts != artifact_dict: parent_job.artifacts = artifact_dict diff --git a/awx/main/models/unified_jobs.py b/awx/main/models/unified_jobs.py index bda60b0c1d..773f786cbd 100644 --- a/awx/main/models/unified_jobs.py +++ b/awx/main/models/unified_jobs.py @@ -561,6 +561,9 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique "Override in child classes, None value indicates this is not configurable" return None + def _resources_sufficient_for_launch(self): + return True + def __unicode__(self): return u'%s-%s-%s' % (self.created, self.id, self.status) diff --git a/awx/main/models/workflow.py b/awx/main/models/workflow.py index 526f0a0300..11d4c37601 100644 --- a/awx/main/models/workflow.py +++ b/awx/main/models/workflow.py @@ -134,7 +134,7 @@ class WorkflowNodeBase(CreatedModifiedModel): scan_errors = ujt_obj._extra_job_type_errors(accepted_fields) ignored_dict.update(scan_errors) for fd in ['inventory', 'credential']: - if getattr(ujt_obj, fd) is None and not (ask_for_vars_dict.get(fd, False) and fd in prompts_dict): + if getattr(ujt_obj, "{}_id".format(fd)) is None and not (ask_for_vars_dict.get(fd, False) and fd in prompts_dict): missing_dict[fd] = 'Job Template does not have this field and workflow node does not provide it' data = {} @@ -418,18 +418,22 @@ class WorkflowJobTemplate(UnifiedJobTemplate, WorkflowJobOptions, SurveyJobTempl def can_start_without_user_input(self): '''Return whether WFJT can be launched without survey passwords.''' - return not bool(self.variables_needed_to_start) + return not bool( + self.variables_needed_to_start or + self.node_templates_missing() or + self.node_prompts_rejected()) - def get_warnings(self): - warning_data = {} - for node in self.workflow_job_template_nodes.all(): - if node.unified_job_template is None: - warning_data[node.pk] = 'Node is missing a linked unified_job_template' - continue + def node_templates_missing(self): + return [node.pk for node in self.workflow_job_template_nodes.filter( + unified_job_template__isnull=True).all()] + + def node_prompts_rejected(self): + node_list = [] + for node in self.workflow_job_template_nodes.select_related('unified_job_template').all(): node_prompts_warnings = node.get_prompts_warnings() if node_prompts_warnings: - warning_data[node.pk] = node_prompts_warnings - return warning_data + node_list.append(node.pk) + return node_list def user_copy(self, user): new_wfjt = self.copy_unified_jt() diff --git a/awx/main/scheduler/__init__.py b/awx/main/scheduler/__init__.py index e92eb429e1..bb98cec776 100644 --- a/awx/main/scheduler/__init__.py +++ b/awx/main/scheduler/__init__.py @@ -10,6 +10,7 @@ from sets import Set from django.conf import settings from django.db import transaction, connection from django.db.utils import DatabaseError +from django.utils.translation import ugettext_lazy as _ # AWX from awx.main.models import * # noqa @@ -114,14 +115,20 @@ class TaskManager(): dag = WorkflowDAG(workflow_job) spawn_nodes = dag.bfs_nodes_to_run() for spawn_node in spawn_nodes: + if spawn_node.unified_job_template is None: + continue kv = spawn_node.get_job_kwargs() job = spawn_node.unified_job_template.create_unified_job(**kv) spawn_node.job = job spawn_node.save() - can_start = job.signal_start(**kv) + if job._resources_sufficient_for_launch(): + can_start = job.signal_start(**kv) + else: + can_start = False if not can_start: job.status = 'failed' - job.job_explanation = "Workflow job could not start because it was not in the right state or required manual credentials" + job.job_explanation = _("Job spawned from workflow could not start because it " + "was not in the right state or required manual credentials") job.save(update_fields=['status', 'job_explanation']) connection.on_commit(lambda: job.websocket_emit_status('failed')) diff --git a/awx/main/scheduler/dag_workflow.py b/awx/main/scheduler/dag_workflow.py index c765b48678..5fc716584a 100644 --- a/awx/main/scheduler/dag_workflow.py +++ b/awx/main/scheduler/dag_workflow.py @@ -67,6 +67,8 @@ class WorkflowDAG(SimpleDAG): obj = n['node_object'] job = obj.job + if obj.unified_job_template is None: + continue if not job: return False # Job is about to run or is running. Hold our horses and wait for diff --git a/awx/main/scheduler/tasks.py b/awx/main/scheduler/tasks.py index 5c4c821606..6e169224b7 100644 --- a/awx/main/scheduler/tasks.py +++ b/awx/main/scheduler/tasks.py @@ -34,11 +34,13 @@ def run_job_complete(job_id): @task def run_task_manager(): + logger.debug("Running Tower task manager.") TaskManager().schedule() @task def run_fail_inconsistent_running_jobs(): + logger.debug("Running task to fail inconsistent running jobs.") with transaction.atomic(): # Lock try: diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 0bd62b7325..18ccf6471c 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -32,7 +32,8 @@ import pexpect # Celery from celery import Task, task -from celery.signals import celeryd_init +from celery.signals import celeryd_init, worker_process_init +from celery import current_app # Django from django.conf import settings @@ -75,7 +76,8 @@ logger = logging.getLogger('awx.main.tasks') def celery_startup(conf=None, **kwargs): # Re-init all schedules # NOTE: Rework this during the Rampart work - logger.info("Syncing Tower Schedules") + startup_logger = logging.getLogger('awx.main.tasks') + startup_logger.info("Syncing Tower Schedules") for sch in Schedule.objects.all(): try: sch.update_computed_fields() @@ -84,7 +86,28 @@ def celery_startup(conf=None, **kwargs): logger.error("Failed to rebuild schedule {}: {}".format(sch, e)) -def uwsgi_reload(): +def _setup_tower_logger(): + global logger + from django.utils.log import configure_logging + LOGGING_DICT = settings.LOGGING + if settings.LOG_AGGREGATOR_ENABLED: + LOGGING_DICT['handlers']['http_receiver']['class'] = 'awx.main.utils.handlers.HTTPSHandler' + LOGGING_DICT['handlers']['http_receiver']['async'] = False + if 'awx' in settings.LOG_AGGREGATOR_LOGGERS: + if 'http_receiver' not in LOGGING_DICT['loggers']['awx']['handlers']: + LOGGING_DICT['loggers']['awx']['handlers'] += ['http_receiver'] + configure_logging(settings.LOGGING_CONFIG, LOGGING_DICT) + logger = logging.getLogger('awx.main.tasks') + + +@worker_process_init.connect +def task_set_logger_pre_run(*args, **kwargs): + if settings.LOG_AGGREGATOR_ENABLED: + _setup_tower_logger() + logger.debug('Custom Tower logger configured for worker process.') + + +def _uwsgi_reload(): # http://uwsgi-docs.readthedocs.io/en/latest/MasterFIFO.html#available-commands logger.warn('Initiating uWSGI chain reload of server') TRIGGER_CHAIN_RELOAD = 'c' @@ -92,14 +115,28 @@ def uwsgi_reload(): awxfifo.write(TRIGGER_CHAIN_RELOAD) -@task(queue='broadcast_all') -def clear_cache_keys(cache_keys): - set_of_keys = set([key for key in cache_keys]) +def _reset_celery_logging(): + # Worker logger reloaded, now send signal to restart pool + app = current_app._get_current_object() + app.control.broadcast('pool_restart', arguments={'reload': True}, + destination=['celery@{}'.format(settings.CLUSTER_HOST_ID)], reply=False) + + +def _clear_cache_keys(set_of_keys): logger.debug('cache delete_many(%r)', set_of_keys) cache.delete_many(set_of_keys) + + +@task(queue='broadcast_all') +def process_cache_changes(cache_keys): + logger.warn('Processing cache changes, task args: {0.args!r} kwargs: {0.kwargs!r}'.format( + process_cache_changes.request)) + set_of_keys = set([key for key in cache_keys]) + _clear_cache_keys(set_of_keys) for setting_key in set_of_keys: if setting_key.startswith('LOG_AGGREGATOR_'): - uwsgi_reload() + _uwsgi_reload() + _reset_celery_logging() break @@ -129,6 +166,7 @@ def send_notifications(notification_list, job_id=None): @task(bind=True, queue='default') def run_administrative_checks(self): + logger.warn("Running administrative checks.") if not settings.TOWER_ADMIN_ALERTS: return validation_info = TaskEnhancer().validate_enhancements() @@ -150,11 +188,13 @@ def run_administrative_checks(self): @task(bind=True, queue='default') def cleanup_authtokens(self): + logger.warn("Cleaning up expired authtokens.") AuthToken.objects.filter(expires__lt=now()).delete() @task(bind=True) def cluster_node_heartbeat(self): + logger.debug("Cluster node heartbeat task.") inst = Instance.objects.filter(hostname=settings.CLUSTER_HOST_ID) if inst.exists(): inst = inst[0] @@ -1832,7 +1872,7 @@ class RunSystemJob(BaseTask): if 'days' in json_vars and system_job.job_type != 'cleanup_facts': args.extend(['--days', str(json_vars.get('days', 60))]) if system_job.job_type == 'cleanup_jobs': - args.extend(['--jobs', '--project-updates', '--inventory-updates', '--management-jobs', '--ad-hoc-commands']) + args.extend(['--jobs', '--project-updates', '--inventory-updates', '--management-jobs', '--ad-hoc-commands', '--workflow-jobs']) if system_job.job_type == 'cleanup_facts': if 'older_than' in json_vars: args.extend(['--older_than', str(json_vars['older_than'])]) diff --git a/awx/main/tests/functional/api/test_job_template.py b/awx/main/tests/functional/api/test_job_template.py index 4983aaac69..ec4286176e 100644 --- a/awx/main/tests/functional/api/test_job_template.py +++ b/awx/main/tests/functional/api/test_job_template.py @@ -65,6 +65,17 @@ def test_edit_sensitive_fields(patch, job_template_factory, alice, grant_project }, alice, expect=expect) +@pytest.mark.django_db +def test_reject_dict_extra_vars_patch(patch, job_template_factory, admin_user): + # Expect a string for extra_vars, raise 400 in this case that would + # otherwise have been saved incorrectly + jt = job_template_factory( + 'jt', organization='org1', project='prj', inventory='inv', credential='cred' + ).job_template + patch(reverse('api:job_template_detail', args=(jt.id,)), + {'extra_vars': {'foo': 5}}, admin_user, expect=400) + + @pytest.mark.django_db def test_edit_playbook(patch, job_template_factory, alice): objs = job_template_factory('jt', organization='org1', project='prj', inventory='inv', credential='cred') diff --git a/awx/main/tests/functional/test_projects.py b/awx/main/tests/functional/test_projects.py index 8d93fcf6d9..8b66c396bd 100644 --- a/awx/main/tests/functional/test_projects.py +++ b/awx/main/tests/functional/test_projects.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + import mock # noqa import pytest @@ -22,6 +24,84 @@ def team_project_list(organization_factory): return objects +@pytest.mark.django_db +def test_user_project_paged_list(get, organization_factory): + 'Test project listing that spans multiple pages' + + # 3 total projects, 1 per page, 3 pages + objects = organization_factory( + 'org1', + projects=['project-%s' % i for i in range(3)], + users=['alice'], + roles=['project-%s.admin_role:alice' % i for i in range(3)], + ) + + # first page has first project and no previous page + pk = objects.users.alice.pk + url = reverse('api:user_projects_list', args=(pk,)) + results = get(url, objects.users.alice, QUERY_STRING='page_size=1').data + assert results['count'] == 3 + assert len(results['results']) == 1 + assert results['previous'] is None + assert results['next'] == ( + '/api/v1/users/%s/projects/?page=2&page_size=1' % pk + ) + + # second page has one more, a previous and next page + results = get(url, objects.users.alice, + QUERY_STRING='page=2&page_size=1').data + assert len(results['results']) == 1 + assert results['previous'] == ( + '/api/v1/users/%s/projects/?page=1&page_size=1' % pk + ) + assert results['next'] == ( + '/api/v1/users/%s/projects/?page=3&page_size=1' % pk + ) + + # third page has last project and a previous page + results = get(url, objects.users.alice, + QUERY_STRING='page=3&page_size=1').data + assert len(results['results']) == 1 + assert results['previous'] == ( + '/api/v1/users/%s/projects/?page=2&page_size=1' % pk + ) + assert results['next'] is None + + +@pytest.mark.django_db +def test_user_project_paged_list_with_unicode(get, organization_factory): + 'Test project listing that contains unicode chars in the next/prev links' + + # Create 2 projects that contain a "cloud" unicode character, make sure we + # can search it and properly generate next/previous page links + objects = organization_factory( + 'org1', + projects=['project-☁-1','project-☁-2'], + users=['alice'], + roles=['project-☁-1.admin_role:alice','project-☁-2.admin_role:alice'], + ) + pk = objects.users.alice.pk + url = reverse('api:user_projects_list', args=(pk,)) + + # first on first page, next page link contains unicode char + results = get(url, objects.users.alice, + QUERY_STRING='page_size=1&search=%E2%98%81').data + assert results['count'] == 2 + assert len(results['results']) == 1 + assert results['next'] == ( + '/api/v1/users/%s/projects/?page=2&page_size=1&search=%%E2%%98%%81' % pk # noqa + ) + + # second project on second page, previous page link contains unicode char + results = get(url, objects.users.alice, + QUERY_STRING='page=2&page_size=1&search=%E2%98%81').data + assert results['count'] == 2 + assert len(results['results']) == 1 + assert results['previous'] == ( + '/api/v1/users/%s/projects/?page=1&page_size=1&search=%%E2%%98%%81' % pk # noqa + ) + + @pytest.mark.django_db def test_user_project_list(get, organization_factory): 'List of projects a user has access to, filtered by projects you can also see' diff --git a/awx/main/tests/functional/test_rbac_job_templates.py b/awx/main/tests/functional/test_rbac_job_templates.py index ac545dafee..13e0da8e8c 100644 --- a/awx/main/tests/functional/test_rbac_job_templates.py +++ b/awx/main/tests/functional/test_rbac_job_templates.py @@ -259,22 +259,37 @@ def test_associate_label(label, user, job_template): @pytest.mark.django_db -def test_move_schedule_to_JT_no_access(job_template, rando): - schedule = Schedule.objects.create( - unified_job_template=job_template, - rrule='DTSTART:20151117T050000Z RRULE:FREQ=DAILY;INTERVAL=1;COUNT=1') - job_template.admin_role.members.add(rando) - jt2 = JobTemplate.objects.create(name="other-jt") - access = ScheduleAccess(rando) - assert not access.can_change(schedule, data=dict(unified_job_template=jt2.pk)) +class TestJobTemplateSchedules: + + rrule = 'DTSTART:20151117T050000Z RRULE:FREQ=DAILY;INTERVAL=1;COUNT=1' + rrule2 = 'DTSTART:20151117T050000Z RRULE:FREQ=WEEKLY;INTERVAL=1;COUNT=1' + + @pytest.fixture + def jt2(self): + return JobTemplate.objects.create(name="other-jt") + + def test_move_schedule_to_JT_no_access(self, job_template, rando, jt2): + schedule = Schedule.objects.create(unified_job_template=job_template, rrule=self.rrule) + job_template.admin_role.members.add(rando) + access = ScheduleAccess(rando) + assert not access.can_change(schedule, data=dict(unified_job_template=jt2.pk)) -@pytest.mark.django_db -def test_move_schedule_from_JT_no_access(job_template, rando): - schedule = Schedule.objects.create( - unified_job_template=job_template, - rrule='DTSTART:20151117T050000Z RRULE:FREQ=DAILY;INTERVAL=1;COUNT=1') - jt2 = JobTemplate.objects.create(name="other-jt") - jt2.admin_role.members.add(rando) - access = ScheduleAccess(rando) - assert not access.can_change(schedule, data=dict(unified_job_template=jt2.pk)) + def test_move_schedule_from_JT_no_access(self, job_template, rando, jt2): + schedule = Schedule.objects.create(unified_job_template=job_template, rrule=self.rrule) + jt2.admin_role.members.add(rando) + access = ScheduleAccess(rando) + assert not access.can_change(schedule, data=dict(unified_job_template=jt2.pk)) + + + def test_can_create_schedule_with_execute(self, job_template, rando): + job_template.execute_role.members.add(rando) + access = ScheduleAccess(rando) + assert access.can_add({'unified_job_template': job_template}) + + + def test_can_modify_ones_own_schedule(self, job_template, rando): + job_template.execute_role.members.add(rando) + schedule = Schedule.objects.create(unified_job_template=job_template, rrule=self.rrule, created_by=rando) + access = ScheduleAccess(rando) + assert access.can_change(schedule, {'rrule': self.rrule2}) diff --git a/awx/main/tests/functional/test_rbac_workflow.py b/awx/main/tests/functional/test_rbac_workflow.py index a0f0348e38..8d363305d5 100644 --- a/awx/main/tests/functional/test_rbac_workflow.py +++ b/awx/main/tests/functional/test_rbac_workflow.py @@ -86,11 +86,15 @@ class TestWorkflowJobTemplateNodeAccess: @pytest.mark.django_db class TestWorkflowJobAccess: - def test_wfjt_admin_delete(self, wfjt, workflow_job, rando): - wfjt.admin_role.members.add(rando) - access = WorkflowJobAccess(rando) + def test_org_admin_can_delete_workflow_job(self, workflow_job, org_admin): + access = WorkflowJobAccess(org_admin) assert access.can_delete(workflow_job) + def test_wfjt_admin_can_delete_workflow_job(self, workflow_job, rando): + workflow_job.workflow_job_template.admin_role.members.add(rando) + access = WorkflowJobAccess(rando) + assert not access.can_delete(workflow_job) + def test_cancel_your_own_job(self, wfjt, workflow_job, rando): wfjt.execute_role.members.add(rando) workflow_job.created_by = rando @@ -120,13 +124,11 @@ class TestWorkflowJobAccess: access = WorkflowJobTemplateAccess(rando, save_messages=True) assert not access.can_copy(wfjt) warnings = access.messages - assert 1 in warnings - assert 'inventory' in warnings[1] + assert 'inventories_unable_to_copy' in warnings def test_workflow_copy_warnings_jt(self, wfjt, rando, job_template): wfjt.workflow_job_template_nodes.create(unified_job_template=job_template) access = WorkflowJobTemplateAccess(rando, save_messages=True) assert not access.can_copy(wfjt) warnings = access.messages - assert 1 in warnings - assert 'unified_job_template' in warnings[1] + assert 'templates_unable_to_copy' in warnings diff --git a/awx/main/tests/unit/api/serializers/test_workflow_serializers.py b/awx/main/tests/unit/api/serializers/test_workflow_serializers.py index b444531206..b8697db71f 100644 --- a/awx/main/tests/unit/api/serializers/test_workflow_serializers.py +++ b/awx/main/tests/unit/api/serializers/test_workflow_serializers.py @@ -125,6 +125,7 @@ class TestWorkflowJobTemplateNodeSerializerCharPrompts(): serializer = WorkflowJobTemplateNodeSerializer() node = WorkflowJobTemplateNode(pk=1) node.char_prompts = {'limit': 'webservers'} + serializer.instance = node view = FakeView(node) view.request = FakeRequest() view.request.method = "PATCH" diff --git a/awx/main/tests/unit/scheduler/test_dag.py b/awx/main/tests/unit/scheduler/test_dag.py index 54e7de4fa8..932f4436ec 100644 --- a/awx/main/tests/unit/scheduler/test_dag.py +++ b/awx/main/tests/unit/scheduler/test_dag.py @@ -5,7 +5,7 @@ import pytest # AWX from awx.main.scheduler.dag_simple import SimpleDAG from awx.main.scheduler.dag_workflow import WorkflowDAG -from awx.main.models import Job +from awx.main.models import Job, JobTemplate from awx.main.models.workflow import WorkflowJobNode @@ -72,6 +72,7 @@ def factory_node(): if status: j = Job(status=status) wfn.job = j + wfn.unified_job_template = JobTemplate(name='JT{}'.format(id)) return wfn return fn diff --git a/awx/main/utils/handlers.py b/awx/main/utils/handlers.py index 28b7c26af7..71176cbb1a 100644 --- a/awx/main/utils/handlers.py +++ b/awx/main/utils/handlers.py @@ -30,6 +30,7 @@ PARAM_NAMES = { 'password': 'LOG_AGGREGATOR_PASSWORD', 'enabled_loggers': 'LOG_AGGREGATOR_LOGGERS', 'indv_facts': 'LOG_AGGREGATOR_INDIVIDUAL_FACTS', + 'enabled_flag': 'LOG_AGGREGATOR_ENABLED', } @@ -48,6 +49,7 @@ class HTTPSHandler(logging.Handler): def __init__(self, fqdn=False, **kwargs): super(HTTPSHandler, self).__init__() self.fqdn = fqdn + self.async = kwargs.get('async', True) for fd in PARAM_NAMES: # settings values take precedence over the input params settings_name = PARAM_NAMES[fd] @@ -100,11 +102,21 @@ class HTTPSHandler(logging.Handler): payload_str = json.dumps(payload_input) else: payload_str = payload_input - return dict(data=payload_str, background_callback=unused_callback) + if self.async: + return dict(data=payload_str, background_callback=unused_callback) + else: + return dict(data=payload_str) + + def skip_log(self, logger_name): + if self.host == '' or (not self.enabled_flag): + return True + if not logger_name.startswith('awx.analytics'): + # Tower log emission is only turned off by enablement setting + return False + return self.enabled_loggers is None or logger_name.split('.')[-1] not in self.enabled_loggers def emit(self, record): - if (self.host == '' or self.enabled_loggers is None or - record.name.split('.')[-1] not in self.enabled_loggers): + if self.skip_log(record.name): return try: payload = self.format(record) @@ -123,7 +135,10 @@ class HTTPSHandler(logging.Handler): self.session.post(host, **self.get_post_kwargs(fact_payload)) return - self.session.post(host, **self.get_post_kwargs(payload)) + if self.async: + self.session.post(host, **self.get_post_kwargs(payload)) + else: + requests.post(host, auth=requests.auth.HTTPBasicAuth(self.username, self.password), **self.get_post_kwargs(payload)) except (KeyboardInterrupt, SystemExit): raise except: diff --git a/awx/main/validators.py b/awx/main/validators.py index 1c92d9a645..c045e936cb 100644 --- a/awx/main/validators.py +++ b/awx/main/validators.py @@ -185,8 +185,9 @@ def vars_validate_or_raise(vars_str): except ValueError: pass try: - yaml.safe_load(vars_str) - return vars_str + r = yaml.safe_load(vars_str) + if not (isinstance(r, basestring) and r.startswith('OrderedDict(')): + return vars_str except yaml.YAMLError: pass raise RestValidationError(_('Must be valid JSON or YAML.')) diff --git a/awx/playbooks/project_update.yml b/awx/playbooks/project_update.yml index 30eff5f6bc..0f4d354ff7 100644 --- a/awx/playbooks/project_update.yml +++ b/awx/playbooks/project_update.yml @@ -115,6 +115,12 @@ chdir: "{{project_path|quote}}/roles" when: doesRequirementsExist.stat.exists and scm_full_checkout|bool + # format provided by ansible is ["Revision: 12345", "URL: ..."] + - name: parse subversion version string properly + set_fact: + scm_version: "{{scm_version|regex_replace('^.*Revision: ([0-9]+).*$', '\\1')}}" + when: scm_type == 'svn' + - name: Repository Version debug: msg="Repository Version {{ scm_version }}" when: scm_version is defined diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 009082b4d5..4563692271 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -73,7 +73,7 @@ DATABASES = { # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. -TIME_ZONE = 'America/New_York' +TIME_ZONE = None # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html @@ -154,7 +154,7 @@ STDOUT_MAX_BYTES_DISPLAY = 1048576 # Returned in the header on event api lists as a recommendation to the UI # on how many events to display before truncating/hiding -RECOMMENDED_MAX_EVENTS_DISPLAY_HEADER = 10000 +RECOMMENDED_MAX_EVENTS_DISPLAY_HEADER = 4000 # The maximum size of the ansible callback event's res data structure # beyond this limit and the value will be removed @@ -167,6 +167,15 @@ JOB_EVENT_WORKERS = 4 JOB_EVENT_MAX_QUEUE_SIZE = 5000 +# Disallow sending session cookies over insecure connections +SESSION_COOKIE_SECURE = True + +# Disallow sending csrf cookies over insecure connections +CSRF_COOKIE_SECURE = True + +# Limit CSRF cookies to browser sessions +CSRF_COOKIE_AGE = None + TEMPLATE_CONTEXT_PROCESSORS = ( # NOQA 'django.contrib.auth.context_processors.auth', 'django.core.context_processors.debug', @@ -380,6 +389,7 @@ CELERY_ACCEPT_CONTENT = ['json'] CELERY_TRACK_STARTED = True CELERYD_TASK_TIME_LIMIT = None CELERYD_TASK_SOFT_TIME_LIMIT = None +CELERYD_POOL_RESTARTS = True CELERYBEAT_SCHEDULER = 'celery.beat.PersistentScheduler' CELERYBEAT_MAX_LOOP_INTERVAL = 60 CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend' @@ -882,7 +892,7 @@ LOGGING = { }, 'http_receiver': { 'class': 'awx.main.utils.handlers.HTTPSNullHandler', - 'level': 'INFO', + 'level': 'DEBUG', 'formatter': 'json', 'host': '', }, @@ -981,7 +991,7 @@ LOGGING = { 'handlers': ['callback_receiver'], }, 'awx.main.tasks': { - 'handlers': ['task_system'] + 'handlers': ['task_system'], }, 'awx.main.scheduler': { 'handlers': ['task_system'], @@ -1009,18 +1019,6 @@ LOGGING = { 'level': 'INFO', 'propagate': False }, - 'awx.analytics.job_events': { - 'handlers': ['null'], - 'level': 'INFO' - }, - 'awx.analytics.activity_stream': { - 'handlers': ['null'], - 'level': 'INFO' - }, - 'awx.analytics.system_tracking': { - 'handlers': ['null'], - 'level': 'INFO' - }, 'django_auth_ldap': { 'handlers': ['console', 'file', 'tower_warnings'], 'level': 'DEBUG', diff --git a/awx/settings/development.py b/awx/settings/development.py index ebe81260d1..1326c12814 100644 --- a/awx/settings/development.py +++ b/awx/settings/development.py @@ -24,11 +24,11 @@ ALLOWED_HOSTS = ['*'] mimetypes.add_type("image/svg+xml", ".svg", True) mimetypes.add_type("image/svg+xml", ".svgz", True) -MONGO_HOST = '127.0.0.1' -MONGO_PORT = 27017 -MONGO_USERNAME = None -MONGO_PASSWORD = None -MONGO_DB = 'system_tracking_dev' +# Disallow sending session cookies over insecure connections +SESSION_COOKIE_SECURE = False + +# Disallow sending csrf cookies over insecure connections +CSRF_COOKIE_SECURE = False # Override django.template.loaders.cached.Loader in defaults.py TEMPLATE_LOADERS = ( diff --git a/awx/settings/local_settings.py.docker_compose b/awx/settings/local_settings.py.docker_compose index a439d17989..1202b1cbe1 100644 --- a/awx/settings/local_settings.py.docker_compose +++ b/awx/settings/local_settings.py.docker_compose @@ -114,7 +114,7 @@ SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. -TIME_ZONE = 'America/New_York' +TIME_ZONE = None # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html diff --git a/awx/settings/local_settings.py.example b/awx/settings/local_settings.py.example index e731acc8b1..2996a8a28e 100644 --- a/awx/settings/local_settings.py.example +++ b/awx/settings/local_settings.py.example @@ -71,7 +71,7 @@ SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. -TIME_ZONE = 'America/New_York' +TIME_ZONE = None # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html diff --git a/awx/sso/fields.py b/awx/sso/fields.py index fdff68130f..174f4a6853 100644 --- a/awx/sso/fields.py +++ b/awx/sso/fields.py @@ -299,7 +299,10 @@ class LDAPGroupTypeField(fields.ChoiceField): data = super(LDAPGroupTypeField, self).to_internal_value(data) if not data: return None - return getattr(django_auth_ldap.config, data)() + if data.endswith('MemberDNGroupType'): + return getattr(django_auth_ldap.config, data)(member_attr='member') + else: + return getattr(django_auth_ldap.config, data)() class LDAPUserFlagsField(fields.DictField): diff --git a/awx/templates/rest_framework/api.html b/awx/templates/rest_framework/api.html index 746521f542..3b75c4a35c 100644 --- a/awx/templates/rest_framework/api.html +++ b/awx/templates/rest_framework/api.html @@ -52,7 +52,7 @@
diff --git a/awx/ui/client/legacy-styles/ansible-ui.less b/awx/ui/client/legacy-styles/ansible-ui.less index e925bff5d4..09ffa992b6 100644 --- a/awx/ui/client/legacy-styles/ansible-ui.less +++ b/awx/ui/client/legacy-styles/ansible-ui.less @@ -729,18 +729,6 @@ legend { .navigation { margin: 15px 0 15px 0; } - .modal-body { - .alert { - padding: 0; - border: none; - margin: 0; - } - .alert-danger { - background-color: @default-bg; - border: none; - color: @default-interface-txt; - } - } .footer-navigation { margin: 10px 0 10px 0; @@ -1638,17 +1626,19 @@ tr td button i { } /* overrides to TB modal */ +.modal-content { + padding: 20px; +} .modal-header { color: @default-interface-txt; - margin: .1em 0; white-space: nowrap; width: 90%; overflow: hidden; text-overflow: ellipsis; width: 100%; border: none; - padding: 12px 14px 0 12px; + padding: 0; } .modal { @@ -1677,8 +1667,18 @@ tr td button i { } .modal-body { - padding: 20px 14px 7px 14px; min-height: 120px; + padding: 20px 0; + + .alert { + padding: 10px; + margin: 0; + } + .alert-danger { + background-color: @default-bg; + border: none; + color: @default-interface-txt; + } } #prompt-modal .modal-body { @@ -1690,15 +1690,15 @@ tr td button i { } .modal-footer { - padding: .3em 1em .5em .4em; + padding: 0; border: none; + margin-top: 0; .btn.btn-primary { text-transform: uppercase; background-color: @default-succ; border-color: @default-succ; padding: 5px 15px; - margin: .5em .4em .5em 0; cursor: pointer; &:hover { @@ -1720,8 +1720,7 @@ tr td button i { /* PW progress bar */ -.pw-progress { - margin-top: 10px; +.pw-progress { margin-top: 10px; li { line-height: normal; @@ -2219,10 +2218,6 @@ a:hover { font-family: 'Open Sans'; } -.modal-body .alert { - padding: 10px; -} - .WorkflowBadge{ background-color: @b7grey; border-radius: 10px; diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 89ff33dd03..570a096c7e 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -44,11 +44,10 @@ color: @list-header-txt; font-size: 14px; font-weight: bold; - padding-bottom: 25px; - min-height: 45px; word-break: break-all; max-width: 90%; word-wrap: break-word; + margin-bottom: 20px; } .Form-secondaryTitle{ diff --git a/awx/ui/client/src/about/about.partial.html b/awx/ui/client/src/about/about.partial.html index bcb2a5cd33..867a5f6035 100644 --- a/awx/ui/client/src/about/about.partial.html +++ b/awx/ui/client/src/about/about.partial.html @@ -11,19 +11,19 @@
  ________________
-/  Tower {{version_str}} \\
-\\{{version}}/
+/  Tower {{version_str}} \
+\{{version}}/
  ----------------
-        \\   ^__^
-         \\  (oo)\\_______
-            (__)      A )\\/\\
+        \   ^__^
+         \  (oo)\_______
+            (__)      A )\/\
                 ||----w |
                 ||     ||
 
diff --git a/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js index 3bcdece9f6..e84b78face 100644 --- a/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js +++ b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js @@ -15,7 +15,8 @@ export default ['templateUrl', '$state', usersDataset: '=', teamsDataset: '=', resourceData: '=', - withoutTeamPermissions: '@' + withoutTeamPermissions: '@', + title: '@' }, controller: controller, templateUrl: templateUrl('access/add-rbac-resource/rbac-resource'), diff --git a/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html index 75eaeb8302..5cd8e19b1e 100644 --- a/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html +++ b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html @@ -6,9 +6,9 @@
- {{ object.name }} + {{ object.name || object.username }}
- Add Permissions + {{ title }}
diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js index f65d0324ad..7a66606e5f 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js @@ -42,8 +42,6 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', list.listTitleBadge = false; - // @issue - fix field.columnClass values for this view - switch(scope.resourceType){ case 'projects': @@ -51,6 +49,8 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', name: list.fields.name, scm_type: list.fields.scm_type }; + list.fields.name.columnClass = 'col-md-5 col-sm-5 col-xs-10'; + list.fields.scm_type.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; case 'inventories': @@ -58,6 +58,8 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', name: list.fields.name, organization: list.fields.organization }; + list.fields.name.columnClass = 'col-md-5 col-sm-5 col-xs-10'; + list.fields.organization.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; case 'job_templates': @@ -67,6 +69,8 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', name: list.fields.name, description: list.fields.description }; + list.fields.name.columnClass = 'col-md-5 col-sm-5 col-xs-10'; + list.fields.description.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; case 'workflow_templates': @@ -77,12 +81,16 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', name: list.fields.name, description: list.fields.description }; + list.fields.name.columnClass = 'col-md-5 col-sm-5 col-xs-10'; + list.fields.description.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; case 'credentials': list.fields = { name: list.fields.name, description: list.fields.description }; + list.fields.name.columnClass = 'col-md-5 col-sm-5 col-xs-10'; + list.fields.description.columnClass = 'col-md-5 col-sm-5 hidden-xs'; } list.fields = _.each(list.fields, (field) => field.nosort = true); diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js index ced1ceb744..ea4aafd2f3 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js @@ -11,7 +11,8 @@ export default ['templateUrl', return { restrict: 'E', scope: { - resolve: "=" + resolve: "=", + title: "@", }, controller: controller, templateUrl: templateUrl('access/add-rbac-user-team/rbac-user-team'), diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html index 975870944c..bc30eff1b7 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html @@ -7,9 +7,9 @@
- {{ owner.name }} + {{ owner.name || owner.username }}
- Add Permissions + {{ title }}
diff --git a/awx/ui/client/src/access/add-rbac.block.less b/awx/ui/client/src/access/add-rbac.block.less index 88f5b1211f..0bc6617ba4 100644 --- a/awx/ui/client/src/access/add-rbac.block.less +++ b/awx/ui/client/src/access/add-rbac.block.less @@ -51,6 +51,10 @@ padding-top: 20px; } +.AddPermissions-list { + margin-bottom: 20px; +} + .AddPermissions-list .List-searchRow { height: 0px; } diff --git a/awx/ui/client/src/access/rbac-multiselect/permissionsUsers.list.js b/awx/ui/client/src/access/rbac-multiselect/permissionsUsers.list.js index 8955d30aa0..58a5605281 100644 --- a/awx/ui/client/src/access/rbac-multiselect/permissionsUsers.list.js +++ b/awx/ui/client/src/access/rbac-multiselect/permissionsUsers.list.js @@ -34,7 +34,7 @@ username: { key: true, label: 'Username', - columnClass: 'col-md-3 col-sm-3 col-xs-9' + columnClass: 'col-md-5 col-sm-5 col-xs-11' }, }, diff --git a/awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js b/awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js index da80fa4a58..2f0d790317 100644 --- a/awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js +++ b/awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js @@ -43,6 +43,8 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL name: list.fields.name, scm_type: list.fields.scm_type }; + list.fields.name.columnClass = 'col-md-6 col-sm-6 col-xs-11'; + list.fields.scm_type.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; case 'Inventories': @@ -50,6 +52,8 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL name: list.fields.name, organization: list.fields.organization }; + list.fields.name.columnClass = 'col-md-6 col-sm-6 col-xs-11'; + list.fields.organization.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; case 'JobTemplates': @@ -59,6 +63,8 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL name: list.fields.name, description: list.fields.description }; + list.fields.name.columnClass = 'col-md-6 col-sm-6 col-xs-11'; + list.fields.description.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; case 'WorkflowTemplates': @@ -69,6 +75,8 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL name: list.fields.name, description: list.fields.description }; + list.fields.name.columnClass = 'col-md-6 col-sm-6 col-xs-11'; + list.fields.description.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; case 'Users': list.fields = { @@ -76,12 +84,25 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL first_name: list.fields.first_name, last_name: list.fields.last_name }; + list.fields.username.columnClass = 'col-md-5 col-sm-5 col-xs-11'; + list.fields.first_name.columnClass = 'col-md-3 col-sm-3 hidden-xs'; + list.fields.last_name.columnClass = 'col-md-3 col-sm-3 hidden-xs'; + break; + case 'Teams': + list.fields = { + name: list.fields.name, + organization: list.fields.organization, + }; + list.fields.name.columnClass = 'col-md-6 col-sm-6 col-xs-11'; + list.fields.organization.columnClass = 'col-md-5 col-sm-5 hidden-xs'; break; default: list.fields = { name: list.fields.name, description: list.fields.description }; + list.fields.name.columnClass = 'col-md-6 col-sm-6 col-xs-11'; + list.fields.description.columnClass = 'col-md-5 col-sm-5 hidden-xs'; } list_html = generateList.build({ diff --git a/awx/ui/client/src/access/rbac-role-column/roleList.partial.html b/awx/ui/client/src/access/rbac-role-column/roleList.partial.html index 1a25afead0..799edbb408 100644 --- a/awx/ui/client/src/access/rbac-role-column/roleList.partial.html +++ b/awx/ui/client/src/access/rbac-role-column/roleList.partial.html @@ -9,7 +9,7 @@
+ aw-tool-tip='
Organization: {{ entry.team_organization_name | sanitize }}
Team: {{entry.team_name | sanitize}}
' aw-tip-placement='bottom'> {{ entry.name }}
diff --git a/awx/ui/client/src/activity-stream/activitystream.controller.js b/awx/ui/client/src/activity-stream/activitystream.controller.js index 05609d3bc5..ada72d572c 100644 --- a/awx/ui/client/src/activity-stream/activitystream.controller.js +++ b/awx/ui/client/src/activity-stream/activitystream.controller.js @@ -12,6 +12,7 @@ function activityStreamController($scope, $state, subTitle, Stream, GetTargetTitle, list, Dataset) { init(); + initOmitSmartTags(); function init() { // search init @@ -33,6 +34,20 @@ function activityStreamController($scope, $state, subTitle, Stream, GetTargetTit }); } + // Specification of smart-tags omission from the UI is done in the route/state init. + // A limitation is that this specficiation is static and the key for which to be omitted from + // the smart-tags must be known at that time. + // In the case of activity stream, we won't to dynamically ommit the resource for which we are + // displaying the activity stream for. i.e. 'project', 'credential', etc. + function initOmitSmartTags() { + let defaults, route = _.find($state.$current.path, (step) => { + return step.params.hasOwnProperty('activity_search'); + }); + if (route && $state.params.target !== undefined) { + defaults = route.params.activity_search.config.value; + defaults[$state.params.target] = null; + } + } } export default ['$scope', '$state', 'subTitle', 'Stream', 'GetTargetTitle', 'StreamList', 'Dataset', activityStreamController]; diff --git a/awx/ui/client/src/activity-stream/streamDetailModal/streamDetailModal.block.less b/awx/ui/client/src/activity-stream/streamDetailModal/streamDetailModal.block.less index 6b00dc76f5..9e0cc73720 100644 --- a/awx/ui/client/src/activity-stream/streamDetailModal/streamDetailModal.block.less +++ b/awx/ui/client/src/activity-stream/streamDetailModal/streamDetailModal.block.less @@ -35,5 +35,6 @@ margin-bottom: 0; max-height: 200px; overflow: scroll; + overflow-x: auto; color: @as-detail-changes-txt; } diff --git a/awx/ui/client/src/activity-stream/streamDetailModal/streamDetailModal.partial.html b/awx/ui/client/src/activity-stream/streamDetailModal/streamDetailModal.partial.html index f5d5acf553..67e4452ebc 100644 --- a/awx/ui/client/src/activity-stream/streamDetailModal/streamDetailModal.partial.html +++ b/awx/ui/client/src/activity-stream/streamDetailModal/streamDetailModal.partial.html @@ -22,7 +22,7 @@
diff --git a/awx/ui/client/src/bread-crumb/bread-crumb.directive.js b/awx/ui/client/src/bread-crumb/bread-crumb.directive.js index 7e58100ea0..3c64a0b701 100644 --- a/awx/ui/client/src/bread-crumb/bread-crumb.directive.js +++ b/awx/ui/client/src/bread-crumb/bread-crumb.directive.js @@ -47,6 +47,9 @@ export default order_by: '-timestamp', page_size: '20', }; + if (streamConfig.activityStreamTarget && streamConfig.activityStreamId) { + stateGoParams.activity_search[streamConfig.activityStreamTarget] = $state.params[streamConfig.activityStreamId]; + } } else { stateGoParams.activity_search = { diff --git a/awx/ui/client/src/bread-crumb/bread-crumb.service.js b/awx/ui/client/src/bread-crumb/bread-crumb.service.js index c51383ef19..b3d510047d 100644 --- a/awx/ui/client/src/bread-crumb/bread-crumb.service.js +++ b/awx/ui/client/src/bread-crumb/bread-crumb.service.js @@ -21,7 +21,7 @@ export default }); }); // Remove the clone from the dom - $breadcrumbClone.remove();console.log(availableWidth); + $breadcrumbClone.remove(); if(expandedBreadcrumbWidth > availableWidth) { let widthToTrim = expandedBreadcrumbWidth - availableWidth; // Sort the crumbs from biggest to smallest diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-azure.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-azure.form.js index 17b36e67fb..bb5bbef1a1 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-azure.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-azure.form.js @@ -16,7 +16,8 @@ reset: 'SOCIAL_AUTH_AZUREAD_OAUTH2_KEY' }, SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET: { - type: 'text', + type: 'sensitive', + hasShowInputButton: true, reset: 'SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET' }, SOCIAL_AUTH_AZUREAD_OAUTH2_ORGANIZATION_MAP: { @@ -38,8 +39,8 @@ buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github-org.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github-org.form.js index bd547cf8b1..9aecc2699f 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github-org.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github-org.form.js @@ -16,7 +16,8 @@ export default ['i18n', function(i18n) { reset: 'SOCIAL_AUTH_GITHUB_ORG_KEY' }, SOCIAL_AUTH_GITHUB_ORG_SECRET: { - type: 'text', + type: 'sensitive', + hasShowInputButton: true, reset: 'SOCIAL_AUTH_GITHUB_ORG_SECRET' }, SOCIAL_AUTH_GITHUB_ORG_NAME: { @@ -28,8 +29,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github-team.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github-team.form.js index d43d8c01be..3747127132 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github-team.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github-team.form.js @@ -16,7 +16,8 @@ export default ['i18n', function(i18n) { reset: 'SOCIAL_AUTH_GITHUB_TEAM_KEY' }, SOCIAL_AUTH_GITHUB_TEAM_SECRET: { - type: 'text', + type: 'sensitive', + hasShowInputButton: true, reset: 'SOCIAL_AUTH_GITHUB_TEAM_SECRET' }, SOCIAL_AUTH_GITHUB_TEAM_ID: { @@ -28,8 +29,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github.form.js index 03af137a7c..f8af9ea74d 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-github.form.js @@ -16,7 +16,8 @@ export default ['i18n', function(i18n) { reset: 'SOCIAL_AUTH_GITHUB_KEY' }, SOCIAL_AUTH_GITHUB_SECRET: { - type: 'text', + type: 'sensitive', + hasShowInputButton: true, reset: 'SOCIAL_AUTH_GITHUB_SECRET' } }, @@ -24,8 +25,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-google-oauth2.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-google-oauth2.form.js index ac1c23545e..8842570974 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-google-oauth2.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-google-oauth2.form.js @@ -16,7 +16,8 @@ export default ['i18n', function(i18n) { reset: 'SOCIAL_AUTH_GOOGLE_OAUTH2_KEY' }, SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET: { - type: 'text', + type: 'sensitive', + hasShowInputButton: true, reset: 'SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET' }, SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS: { @@ -36,8 +37,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap.form.js index 8d38fea688..0943d21b27 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap.form.js @@ -21,7 +21,8 @@ export default ['i18n', function(i18n) { reset: 'AUTH_LDAP_BIND_DN' }, AUTH_LDAP_BIND_PASSWORD: { - type: 'password' + type: 'sensitive', + hasShowInputButton: true, }, AUTH_LDAP_USER_SEARCH: { type: 'textarea', @@ -84,8 +85,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-radius.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-radius.form.js index b16fd649dc..f8aa37b014 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-radius.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-radius.form.js @@ -21,7 +21,8 @@ export default ['i18n', function(i18n) { reset: 'RADIUS_PORT' }, RADIUS_SECRET: { - type: 'text', + type: 'sensitive', + hasShowInputButton: true, reset: 'RADIUS_SECRET' } }, @@ -29,8 +30,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-saml.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-saml.form.js index ca2bb50dcb..698bcbc6bd 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-saml.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-saml.form.js @@ -20,7 +20,8 @@ export default ['i18n', function(i18n) { reset: 'SOCIAL_AUTH_SAML_SP_PUBLIC_CERT' }, SOCIAL_AUTH_SAML_SP_PRIVATE_KEY: { - type: 'text', + type: 'sensitive', + hasShowInputButton: true, reset: 'SOCIAL_AUTH_SAML_SP_PRIVATE_KEY' }, SOCIAL_AUTH_SAML_ORG_INFO: { @@ -56,8 +57,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/configuration.block.less b/awx/ui/client/src/configuration/configuration.block.less index 0b2a1ea0ee..b25d36e400 100644 --- a/awx/ui/client/src/configuration/configuration.block.less +++ b/awx/ui/client/src/configuration/configuration.block.less @@ -12,6 +12,19 @@ float: right } +.Form-resetAll { + border: none; + padding: 0; + background-color: @white; + margin-right: auto; + color: @default-link; + font-size: 12px; + + &:hover { + color: @default-link-hov; + } +} + .Form-tab { min-width: 77px; } diff --git a/awx/ui/client/src/configuration/jobs-form/configuration-jobs.form.js b/awx/ui/client/src/configuration/jobs-form/configuration-jobs.form.js index caf0392c24..99e52498c2 100644 --- a/awx/ui/client/src/configuration/jobs-form/configuration-jobs.form.js +++ b/awx/ui/client/src/configuration/jobs-form/configuration-jobs.form.js @@ -64,8 +64,8 @@ buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/system-form/sub-forms/system-activity-stream.form.js b/awx/ui/client/src/configuration/system-form/sub-forms/system-activity-stream.form.js index 09cf80eccd..3dc7fd89f7 100644 --- a/awx/ui/client/src/configuration/system-form/sub-forms/system-activity-stream.form.js +++ b/awx/ui/client/src/configuration/system-form/sub-forms/system-activity-stream.form.js @@ -22,8 +22,8 @@ buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/system-form/sub-forms/system-logging.form.js b/awx/ui/client/src/configuration/system-form/sub-forms/system-logging.form.js index ee99024b45..f2ed9f54e3 100644 --- a/awx/ui/client/src/configuration/system-form/sub-forms/system-logging.form.js +++ b/awx/ui/client/src/configuration/system-form/sub-forms/system-logging.form.js @@ -30,7 +30,8 @@ reset: 'LOG_AGGREGATOR_USERNAME' }, LOG_AGGREGATOR_PASSWORD: { - type: 'text', + type: 'sensitive', + hasShowInputButton: true, reset: 'LOG_AGGREGATOR_PASSWORD' }, LOG_AGGREGATOR_LOGGERS: { @@ -48,8 +49,8 @@ buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js b/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js index 690418f323..892dfd0bc0 100644 --- a/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js +++ b/awx/ui/client/src/configuration/system-form/sub-forms/system-misc.form.js @@ -26,8 +26,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/configuration/ui-form/configuration-ui.form.js b/awx/ui/client/src/configuration/ui-form/configuration-ui.form.js index 0ef2cb44ff..e566c076d1 100644 --- a/awx/ui/client/src/configuration/ui-form/configuration-ui.form.js +++ b/awx/ui/client/src/configuration/ui-form/configuration-ui.form.js @@ -32,8 +32,8 @@ export default ['i18n', function(i18n) { buttons: { reset: { ngClick: 'vm.resetAllConfirm()', - label: i18n._('Reset All'), - class: 'Form-button--left Form-cancelButton' + label: i18n._('Revert all to default'), + class: 'Form-resetAll' }, cancel: { ngClick: 'vm.formCancel()', diff --git a/awx/ui/client/src/controllers/Credentials.js b/awx/ui/client/src/controllers/Credentials.js index a64056ccd4..8fc0d4e55f 100644 --- a/awx/ui/client/src/controllers/Credentials.js +++ b/awx/ui/client/src/controllers/Credentials.js @@ -113,7 +113,7 @@ CredentialsList.$inject = ['$scope', '$rootScope', '$location', '$log', export function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $stateParams, CredentialForm, GenerateForm, Rest, Alert, ProcessErrors, - ClearScope, GetBasePath, GetChoices, Empty, KindChange, + ClearScope, GetBasePath, GetChoices, Empty, KindChange, BecomeMethodChange, OwnerChange, FormSave, $state, CreateSelect2) { ClearScope(); @@ -221,6 +221,10 @@ export function CredentialsAdd($scope, $rootScope, $compile, $location, $log, KindChange({ scope: $scope, form: form, reset: true }); }; + $scope.becomeMethodChange = function() { + BecomeMethodChange({ scope: $scope }); + }; + // Save $scope.formSave = function() { if ($scope[form.name + '_form'].$valid) { @@ -276,14 +280,14 @@ export function CredentialsAdd($scope, $rootScope, $compile, $location, $log, CredentialsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$stateParams', 'CredentialForm', 'GenerateForm', 'Rest', 'Alert', - 'ProcessErrors', 'ClearScope', 'GetBasePath', 'GetChoices', 'Empty', 'KindChange', + 'ProcessErrors', 'ClearScope', 'GetBasePath', 'GetChoices', 'Empty', 'KindChange', 'BecomeMethodChange', 'OwnerChange', 'FormSave', '$state', 'CreateSelect2' ]; export function CredentialsEdit($scope, $rootScope, $compile, $location, $log, $stateParams, CredentialForm, Rest, Alert, ProcessErrors, ClearScope, Prompt, - GetBasePath, GetChoices, KindChange, Empty, OwnerChange, FormSave, Wait, - $state, CreateSelect2, Authorization) { + GetBasePath, GetChoices, KindChange, BecomeMethodChange, Empty, OwnerChange, FormSave, Wait, + $state, CreateSelect2, Authorization, i18n) { ClearScope(); @@ -336,19 +340,15 @@ export function CredentialsEdit($scope, $rootScope, $compile, $location, $log, }); } - // if the credential is assigned to an organization, allow permission delegation - // do NOT use $scope.organization in a view directive to determine if a credential is associated with an org - // @todo why not? ^ and what is this type check for a number doing - should this be a type check for undefined? - $scope.disablePermissionAssignment = typeof($scope.organization) === 'number' ? false : true; - if ($scope.disablePermissionAssignment) { - $scope.permissionsTooltip = 'Credentials are only shared within an organization. Assign credentials to an organization to delegate credential permissions. The organization cannot be edited after credentials are assigned.'; - } - setAskCheckboxes(); - KindChange({ - scope: $scope, - form: form, - reset: false + $scope.$watch('organization', function(val) { + if (val === undefined) { + $scope.permissionsTooltip = i18n._('Credentials are only shared within an organization. Assign credentials to an organization to delegate credential permissions. The organization cannot be edited after credentials are assigned.'); + } else { + $scope.permissionsTooltip = ''; + } }); + + setAskCheckboxes(); OwnerChange({ scope: $scope }); $scope.$watch("ssh_key_data", function(val) { if (val === "" || val === null || val === undefined) { @@ -453,6 +453,13 @@ export function CredentialsEdit($scope, $rootScope, $compile, $location, $log, break; } } + + KindChange({ + scope: $scope, + form: form, + reset: false + }); + master.kind = $scope.kind; CreateSelect2({ @@ -518,6 +525,10 @@ export function CredentialsEdit($scope, $rootScope, $compile, $location, $log, KindChange({ scope: $scope, form: form, reset: true }); }; + $scope.becomeMethodChange = function() { + BecomeMethodChange({ scope: $scope }); + }; + $scope.formCancel = function() { $state.transitionTo('credentials'); }; @@ -612,6 +623,6 @@ export function CredentialsEdit($scope, $rootScope, $compile, $location, $log, CredentialsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$stateParams', 'CredentialForm', 'Rest', 'Alert', 'ProcessErrors', 'ClearScope', 'Prompt', 'GetBasePath', 'GetChoices', - 'KindChange', 'Empty', 'OwnerChange', - 'FormSave', 'Wait', '$state', 'CreateSelect2', 'Authorization' + 'KindChange', 'BecomeMethodChange', 'Empty', 'OwnerChange', + 'FormSave', 'Wait', '$state', 'CreateSelect2', 'Authorization', 'i18n', ]; diff --git a/awx/ui/client/src/credentials/ownerList.block.less b/awx/ui/client/src/credentials/ownerList.block.less new file mode 100644 index 0000000000..64f76db17b --- /dev/null +++ b/awx/ui/client/src/credentials/ownerList.block.less @@ -0,0 +1,36 @@ +/** @define OwnerList */ +@import "./client/src/shared/branding/colors.default.less"; + +.OwnerList { + display: flex; + flex-wrap: wrap; + align-items: flex-start; +} + +.OwnerList-seeBase { + display: flex; + max-width: 100%; + + color: @default-link; + text-transform: uppercase; + padding: 2px 15px; + cursor: pointer; + border-radius: 5px; + font-size: 11px; +} + +.OwnerList-seeBase:hover { + color: @default-link-hov; +} + +.OwnerList-seeLess { + .OwnerList-seeBase; +} + +.OwnerList-seeMore { + .OwnerList-seeBase; +} + +.OwnerList-Container { + margin-right: 5px; +} diff --git a/awx/ui/client/src/credentials/ownerList.partial.html b/awx/ui/client/src/credentials/ownerList.partial.html index 1ed46c081b..5c73ac4d15 100644 --- a/awx/ui/client/src/credentials/ownerList.partial.html +++ b/awx/ui/client/src/credentials/ownerList.partial.html @@ -1,5 +1,12 @@ - + \ No newline at end of file diff --git a/awx/ui/client/src/dashboard/lists/dashboard-list.block.less b/awx/ui/client/src/dashboard/lists/dashboard-list.block.less index 102188034d..0903b01c74 100644 --- a/awx/ui/client/src/dashboard/lists/dashboard-list.block.less +++ b/awx/ui/client/src/dashboard/lists/dashboard-list.block.less @@ -32,34 +32,21 @@ } .DashboardList-viewAll { - color: @btn-txt; - background-color: @btn-bg; - font-size: 12px; - border: 1px solid @default-icon-hov; - border-radius: 5px; + font-size: 11px; margin-right: 15px; - margin-top: 10px; + margin-top: 13px; margin-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-bottom: 5px; padding-top: 5px; - transition: background-color 0.2s; -} - -.DashboardList-viewAll:hover { - color: @btn-txt; - background-color: @btn-bg-hov; -} - -.DashboardList-viewAll:focus { - color: @btn-txt; } .DashboardList-container { flex: 1; width: 100%; padding: 20px; + padding-top: 0; } .DashboardList-tableHeader--name { diff --git a/awx/ui/client/src/footer/footer.partial.html b/awx/ui/client/src/footer/footer.partial.html index 9aaaeb7f75..4a34bde28a 100644 --- a/awx/ui/client/src/footer/footer.partial.html +++ b/awx/ui/client/src/footer/footer.partial.html @@ -1,3 +1,3 @@ diff --git a/awx/ui/client/src/forms/Credentials.js b/awx/ui/client/src/forms/Credentials.js index 9d816c9ce4..247981e18b 100644 --- a/awx/ui/client/src/forms/Credentials.js +++ b/awx/ui/client/src/forms/Credentials.js @@ -288,7 +288,8 @@ export default dataPlacement: 'right', dataContainer: "body", subForm: 'credentialSubForm', - ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)' + ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)', + ngChange: 'becomeMethodChange()', }, "become_username": { labelBind: 'becomeUsernameLabel', @@ -420,9 +421,12 @@ export default related: { permissions: { - disabled: 'disablePermissionAssignment', + disabled: '(organization === undefined ? true : false)', + // Do not transition the state if organization is undefined + ngClick: `(organization === undefined ? true : false)||$state.go('credentials.edit.permissions')`, awToolTip: '{{permissionsTooltip}}', dataTipWatch: 'permissionsTooltip', + awToolTipTabEnabledInEditMode: true, dataPlacement: 'top', basePath: 'api/v1/credentials/{{$stateParams.credential_id}}/access_list/', search: { diff --git a/awx/ui/client/src/forms/Groups.js b/awx/ui/client/src/forms/Groups.js index b5c876c3b9..c5bf595ca2 100644 --- a/awx/ui/client/src/forms/Groups.js +++ b/awx/ui/client/src/forms/Groups.js @@ -43,7 +43,7 @@ export default label: 'Variables', type: 'textarea', class: 'Form-textAreaLabel Form-formGroup--fullWidth', - rows: 12, + rows: 6, 'default': '---', dataTitle: 'Group Variables', dataPlacement: 'right', @@ -69,6 +69,11 @@ export default ngModel: 'source' }, credential: { + // initializes a default value for this search param + // search params with default values set will not generate user-interactable search tags + search: { + kind: null + }, label: 'Cloud Credential', type: 'lookup', list: 'CredentialList', diff --git a/awx/ui/client/src/forms/Inventories.js b/awx/ui/client/src/forms/Inventories.js index e7106b8277..5d96ebfaa5 100644 --- a/awx/ui/client/src/forms/Inventories.js +++ b/awx/ui/client/src/forms/Inventories.js @@ -78,7 +78,7 @@ angular.module('InventoryFormDefinition', ['ScanJobsListDefinition']) }, close: { ngClick: 'formCancel()', - ngHide: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' + ngShow: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' }, save: { ngClick: 'formSave()', @@ -103,7 +103,7 @@ angular.module('InventoryFormDefinition', ['ScanJobsListDefinition']) add: { label: i18n._('Add'), ngClick: "$state.go('.add')", - awToolTip: 'Add a permission', + awToolTip: i18n._('Add a permission'), actionClass: 'btn List-buttonSubmit', buttonContent: '+ ADD', ngShow: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' diff --git a/awx/ui/client/src/forms/Organizations.js b/awx/ui/client/src/forms/Organizations.js index 011ad90907..b50d7eeb3a 100644 --- a/awx/ui/client/src/forms/Organizations.js +++ b/awx/ui/client/src/forms/Organizations.js @@ -68,7 +68,7 @@ export default searchType: 'select', actions: { add: { - ngClick: "addPermission", + ngClick: "$state.go('.add')", label: i18n._('Add'), awToolTip: i18n._('Add a permission'), actionClass: 'btn List-buttonSubmit', diff --git a/awx/ui/client/src/forms/Users.js b/awx/ui/client/src/forms/Users.js index 0ef16a4aff..672dd2beea 100644 --- a/awx/ui/client/src/forms/Users.js +++ b/awx/ui/client/src/forms/Users.js @@ -121,6 +121,7 @@ export default organizations: { awToolTip: i18n._('Please save before assigning to organizations'), basePath: 'api/v1/users/{{$stateParams.user_id}}/organizations', + emptyListText: i18n._('Please add user to an Organization.'), search: { page_size: '10' }, diff --git a/awx/ui/client/src/forms/Workflows.js b/awx/ui/client/src/forms/Workflows.js index e938d42d55..a5a76d0bbd 100644 --- a/awx/ui/client/src/forms/Workflows.js +++ b/awx/ui/client/src/forms/Workflows.js @@ -122,7 +122,7 @@ export default add: { ngClick: "$state.go('.add')", label: i18n._('Add'), - awToolTip: 'Add a permission', + awToolTip: i18n._('Add a permission'), actionClass: 'btn List-buttonSubmit', buttonContent: '+ '+ i18n._('ADD'), ngShow: '(workflow_job_template_obj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)' diff --git a/awx/ui/client/src/helpers/Credentials.js b/awx/ui/client/src/helpers/Credentials.js index 23216577ba..007756d17c 100644 --- a/awx/ui/client/src/helpers/Credentials.js +++ b/awx/ui/client/src/helpers/Credentials.js @@ -74,6 +74,7 @@ angular.module('CredentialsHelper', ['Utilities']) scope.projectPopOver = "

" + i18n._("The project value") + "

"; scope.hostPopOver = "

" + i18n._("The host value") + "

"; scope.ssh_key_data_api_error = ''; + if (!Empty(scope.kind)) { // Apply kind specific settings switch (scope.kind.value) { @@ -204,6 +205,111 @@ angular.module('CredentialsHelper', ['Utilities']) } ]) +.factory('BecomeMethodChange', ['Empty', 'i18n', + function (Empty, i18n) { + return function (params) { + console.log('become method has changed'); + var scope = params.scope; + + if (!Empty(scope.kind)) { + // Apply kind specific settings + switch (scope.kind.value) { + case 'aws': + scope.aws_required = true; + break; + case 'rax': + scope.rackspace_required = true; + scope.username_required = true; + break; + case 'ssh': + scope.usernameLabel = i18n._('Username'); //formally 'SSH Username' + scope.becomeUsernameLabel = i18n._('Privilege Escalation Username'); + scope.becomePasswordLabel = i18n._('Privilege Escalation Password'); + break; + case 'scm': + scope.sshKeyDataLabel = i18n._('SCM Private Key'); + scope.passwordLabel = i18n._('Password'); + break; + case 'gce': + scope.usernameLabel = i18n._('Service Account Email Address'); + scope.sshKeyDataLabel = i18n._('RSA Private Key'); + scope.email_required = true; + scope.key_required = true; + scope.project_required = true; + scope.key_description = i18n._('Paste the contents of the PEM file associated with the service account email.'); + scope.projectLabel = i18n._("Project"); + scope.project_required = false; + scope.projectPopOver = "

" + i18n._("The Project ID is the " + + "GCE assigned identification. It is constructed as " + + "two words followed by a three digit number. Such " + + "as: ") + "

adjective-noun-000

"; + break; + case 'azure': + scope.sshKeyDataLabel = i18n._('Management Certificate'); + scope.subscription_required = true; + scope.key_required = true; + scope.key_description = i18n._("Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console."); + break; + case 'azure_rm': + scope.usernameLabel = i18n._("Username"); + scope.subscription_required = true; + scope.passwordLabel = i18n._('Password'); + scope.azure_rm_required = true; + break; + case 'vmware': + scope.username_required = true; + scope.host_required = true; + scope.password_required = true; + scope.hostLabel = "vCenter Host"; + scope.passwordLabel = i18n._('Password'); + scope.hostPopOver = i18n._("Enter the hostname or IP address which corresponds to your VMware vCenter."); + break; + case 'openstack': + scope.hostLabel = i18n._("Host (Authentication URL)"); + scope.projectLabel = i18n._("Project (Tenant Name)"); + scope.domainLabel = i18n._("Domain Name"); + scope.password_required = true; + scope.project_required = true; + scope.host_required = true; + scope.username_required = true; + scope.projectPopOver = "

" + i18n._("This is the tenant name. " + + " This value is usually the same " + + " as the username.") + "

"; + scope.hostPopOver = "

" + i18n._("The host to authenticate with.") + + "
" + i18n.sprintf(i18n._("For example, %s"), "https://openstack.business.com/v2.0/"); + break; + case 'satellite6': + scope.username_required = true; + scope.password_required = true; + scope.passwordLabel = i18n._('Password'); + scope.host_required = true; + scope.hostLabel = i18n._("Satellite 6 URL"); + scope.hostPopOver = i18n.sprintf(i18n._("Enter the URL which corresponds to your %s" + + "Red Hat Satellite 6 server. %s" + + "For example, %s"), "
", "
", "https://satellite.example.org"); + break; + case 'cloudforms': + scope.username_required = true; + scope.password_required = true; + scope.passwordLabel = i18n._('Password'); + scope.host_required = true; + scope.hostLabel = i18n._("CloudForms URL"); + scope.hostPopOver = i18n.sprintf(i18n._("Enter the URL for the virtual machine which %s" + + "corresponds to your CloudForm instance. %s" + + "For example, %s"), "
", "
", "https://cloudforms.example.org"); + break; + case 'net': + scope.username_required = true; + scope.password_required = false; + scope.passwordLabel = i18n._('Password'); + scope.sshKeyDataLabel = i18n._('SSH Key'); + break; + } + } + }; + } +]) + .factory('OwnerChange', [ function () { diff --git a/awx/ui/client/src/helpers/Jobs.js b/awx/ui/client/src/helpers/Jobs.js index 9f64ac8906..d7649d1c33 100644 --- a/awx/ui/client/src/helpers/Jobs.js +++ b/awx/ui/client/src/helpers/Jobs.js @@ -233,7 +233,7 @@ export default hdr: hdr, body: (action_label === 'cancel' || job.status === 'new') ? cancelBody : deleteBody, action: action, - actionText: (action_label === 'cancel' || job.status === 'new') ? "YES" : "DELETE" + actionText: (action_label === 'cancel' || job.status === 'new') ? "OK" : "DELETE" }); }); diff --git a/awx/ui/client/src/i18n.js b/awx/ui/client/src/i18n.js index 9471e04616..b37d05a8c0 100644 --- a/awx/ui/client/src/i18n.js +++ b/awx/ui/client/src/i18n.js @@ -24,10 +24,7 @@ export default var langUrl = langInfo.replace('-', '_'); //gettextCatalog.debug = true; gettextCatalog.setCurrentLanguage(langInfo); - // TODO: the line below is commented out temporarily until - // the .po files are received from the i18n team, in order to avoid - // 404 file not found console errors in dev - // gettextCatalog.loadRemote('/static/languages/' + langUrl + '.json'); + gettextCatalog.loadRemote('/static/languages/' + langUrl + '.json'); }; }]) .factory('i18n', ['gettextCatalog', diff --git a/awx/ui/client/src/inventories/add/inventory-add.controller.js b/awx/ui/client/src/inventories/add/inventory-add.controller.js index 7f08e716a6..e6f9b7e3a3 100644 --- a/awx/ui/client/src/inventories/add/inventory-add.controller.js +++ b/awx/ui/client/src/inventories/add/inventory-add.controller.js @@ -11,10 +11,16 @@ */ function InventoriesAdd($scope, $rootScope, $compile, $location, $log, - $stateParams, GenerateForm, InventoryForm, Rest, Alert, ProcessErrors, + $stateParams, GenerateForm, InventoryForm, rbacUiControlService, Rest, Alert, ProcessErrors, ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON, $state) { + $scope.canAdd = false; + rbacUiControlService.canAdd(GetBasePath('inventory')) + .then(function(canAdd) { + $scope.canAdd = canAdd; + }); + Rest.setUrl(GetBasePath('inventory')); Rest.options() .success(function(data) { @@ -91,7 +97,7 @@ function InventoriesAdd($scope, $rootScope, $compile, $location, $log, } export default ['$scope', '$rootScope', '$compile', '$location', - '$log', '$stateParams', 'GenerateForm', 'InventoryForm', 'Rest', 'Alert', + '$log', '$stateParams', 'GenerateForm', 'InventoryForm', 'rbacUiControlService', 'Rest', 'Alert', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange', 'Wait', 'ToJSON', '$state', InventoriesAdd ]; diff --git a/awx/ui/client/src/inventories/edit/inventory-edit.controller.js b/awx/ui/client/src/inventories/edit/inventory-edit.controller.js index ba6de0f183..3e26dec8dc 100644 --- a/awx/ui/client/src/inventories/edit/inventory-edit.controller.js +++ b/awx/ui/client/src/inventories/edit/inventory-edit.controller.js @@ -32,7 +32,7 @@ function InventoriesEdit($scope, $rootScope, $compile, $location, form.formFieldSize = null; $scope.inventory_id = inventory_id; - $scope.$watch('invnentory_obj.summary_fields.user_capabilities.edit', function(val) { + $scope.$watch('inventory_obj.summary_fields.user_capabilities.edit', function(val) { if (val === false) { $scope.canAdd = false; } diff --git a/awx/ui/client/src/inventories/main.js b/awx/ui/client/src/inventories/main.js index 8505c9b80f..ac031283cd 100644 --- a/awx/ui/client/src/inventories/main.js +++ b/awx/ui/client/src/inventories/main.js @@ -66,7 +66,19 @@ angular.module('inventory', [ ], ParentObject: ['groupData', function(groupData) { return groupData; - }] + }], + UnifiedJobsOptions: ['Rest', 'GetBasePath', '$stateParams', '$q', + function(Rest, GetBasePath, $stateParams, $q) { + Rest.setUrl(GetBasePath('unified_jobs')); + var val = $q.defer(); + Rest.options() + .then(function(data) { + val.resolve(data.data); + }, function(data) { + val.reject(data); + }); + return val.promise; + }] }, views: { // clear form template when views render in this substate diff --git a/awx/ui/client/src/inventories/manage/copy-move/copy-move-groups.controller.js b/awx/ui/client/src/inventories/manage/copy-move/copy-move-groups.controller.js index 9231e7a5b2..9153dad34d 100644 --- a/awx/ui/client/src/inventories/manage/copy-move/copy-move-groups.controller.js +++ b/awx/ui/client/src/inventories/manage/copy-move/copy-move-groups.controller.js @@ -11,7 +11,7 @@ $scope.item = group; $scope.submitMode = $stateParams.groups === undefined ? 'move' : 'copy'; - $scope['toggle_'+ list.iterator] = function(id){ + $scope.toggle_row = function(id){ // toggle off anything else currently selected _.forEach($scope.groups, (item) => {return item.id === id ? item.checked = 1 : item.checked = null;}); // yoink the currently selected thing @@ -60,9 +60,6 @@ }; function init(){ - var url = GetBasePath('inventory') + $stateParams.inventory_id + '/groups/'; - url += $stateParams.group ? '?not__id__in=' + group.id + ',' + _.last($stateParams.group) : '?not__id=' + group.id; - list.basePath = url; $scope.atRootLevel = $stateParams.group ? false : true; // search init diff --git a/awx/ui/client/src/inventories/manage/copy-move/copy-move-hosts.controller.js b/awx/ui/client/src/inventories/manage/copy-move/copy-move-hosts.controller.js index a01387c173..5c95523036 100644 --- a/awx/ui/client/src/inventories/manage/copy-move/copy-move-hosts.controller.js +++ b/awx/ui/client/src/inventories/manage/copy-move/copy-move-hosts.controller.js @@ -8,10 +8,10 @@ ['$scope', '$state', '$stateParams', 'generateList', 'HostManageService', 'GetBasePath', 'CopyMoveGroupList', 'host', 'Dataset', function($scope, $state, $stateParams, GenerateList, HostManageService, GetBasePath, CopyMoveGroupList, host, Dataset){ var list = CopyMoveGroupList; - + $scope.item = host; $scope.submitMode = 'copy'; - $scope['toggle_'+ list.iterator] = function(id){ + $scope.toggle_row = function(id){ // toggle off anything else currently selected _.forEach($scope.groups, (item) => {return item.id === id ? item.checked = 1 : item.checked = null;}); // yoink the currently selected thing diff --git a/awx/ui/client/src/inventories/manage/copy-move/copy-move.route.js b/awx/ui/client/src/inventories/manage/copy-move/copy-move.route.js index f15705778d..b93e5e1e0f 100644 --- a/awx/ui/client/src/inventories/manage/copy-move/copy-move.route.js +++ b/awx/ui/client/src/inventories/manage/copy-move/copy-move.route.js @@ -30,8 +30,8 @@ var copyMoveGroupRoute = { resolve: { Dataset: ['CopyMoveGroupList', 'QuerySet', '$stateParams', 'GetBasePath', 'group', function(list, qs, $stateParams, GetBasePath, group) { - $stateParams.copy_search.not__id__in = ($stateParams.group.length > 0 ? group.id + ',' + _.last($stateParams.group) : group.id); - let path = GetBasePath(list.name); + $stateParams.copy_search.not__id__in = ($stateParams.group && $stateParams.group.length > 0 ? group.id + ',' + _.last($stateParams.group) : group.id.toString()); + let path = GetBasePath('inventory') + $stateParams.inventory_id + '/groups/'; return qs.search(path, $stateParams.copy_search); } ], @@ -66,7 +66,7 @@ var copyMoveHostRoute = { resolve: { Dataset: ['CopyMoveGroupList', 'QuerySet', '$stateParams', 'GetBasePath', function(list, qs, $stateParams, GetBasePath) { - let path = GetBasePath(list.name); + let path = GetBasePath('inventory') + $stateParams.inventory_id + '/hosts/'; return qs.search(path, $stateParams.copy_search); } ], @@ -80,7 +80,9 @@ var copyMoveHostRoute = { controller: CopyMoveHostsController, }, 'copyMoveList@inventoryManage.copyMoveHost': { - templateProvider: function(CopyMoveGroupList, generateList) { + templateProvider: function(CopyMoveGroupList, generateList, $stateParams, GetBasePath) { + let list = CopyMoveGroupList; + list.basePath = GetBasePath('inventory') + $stateParams.inventory_id + '/hosts/'; let html = generateList.build({ list: CopyMoveGroupList, mode: 'lookup', diff --git a/awx/ui/client/src/inventories/manage/groups/groups-add.controller.js b/awx/ui/client/src/inventories/manage/groups/groups-add.controller.js index 031cf03f8a..9229595d96 100644 --- a/awx/ui/client/src/inventories/manage/groups/groups-add.controller.js +++ b/awx/ui/client/src/inventories/manage/groups/groups-add.controller.js @@ -31,9 +31,10 @@ export default ['$state', '$stateParams', '$scope', 'GroupForm', 'CredentialList } $scope.lookupCredential = function(){ + let kind = ($scope.source.value === "ec2") ? "aws" : $scope.source.value; $state.go('.credential', { credential_search: { - kind: $scope.source.value, + kind: kind, page_size: '5', page: '1' } diff --git a/awx/ui/client/src/inventories/manage/groups/groups-edit.controller.js b/awx/ui/client/src/inventories/manage/groups/groups-edit.controller.js index 796dee5066..ae90cae8bf 100644 --- a/awx/ui/client/src/inventories/manage/groups/groups-edit.controller.js +++ b/awx/ui/client/src/inventories/manage/groups/groups-edit.controller.js @@ -58,9 +58,10 @@ export default ['$state', '$stateParams', '$scope', 'ToggleNotification', 'Parse }; $scope.lookupCredential = function(){ + let kind = ($scope.source.value === "ec2") ? "aws" : $scope.source.value; $state.go('.credential', { credential_search: { - kind: $scope.source.value, + kind: kind, page_size: '5', page: '1' } @@ -122,7 +123,7 @@ export default ['$state', '$stateParams', '$scope', 'ToggleNotification', 'Parse $scope.source = source; if (source.value === 'ec2' || source.value === 'custom' || source.value === 'vmware' || source.value === 'openstack') { - $scope[source.value + '_variables'] = $scope[source.value + '_variables'] === null ? '---' : $scope[source.value + '_variables']; + $scope[source.value + '_variables'] = $scope[source.value + '_variables'] === (null || undefined) ? '---' : $scope[source.value + '_variables']; ParseTypeChange({ scope: $scope, field_id: source.value + '_variables', diff --git a/awx/ui/client/src/inventories/manage/inventory-manage.route.js b/awx/ui/client/src/inventories/manage/inventory-manage.route.js index ddcbf85e1d..ca7589a3e1 100644 --- a/awx/ui/client/src/inventories/manage/inventory-manage.route.js +++ b/awx/ui/client/src/inventories/manage/inventory-manage.route.js @@ -98,9 +98,17 @@ export default { }, // target ui-views with name@inventoryManage state 'groupsList@inventoryManage': { - templateProvider: function(InventoryGroups, generateList, $templateRequest) { + templateProvider: function(InventoryGroups, generateList, $templateRequest, $stateParams, GetBasePath) { + let list = _.cloneDeep(InventoryGroups); + if($stateParams && $stateParams.group) { + list.basePath = GetBasePath('groups') + _.last($stateParams.group) + '/children'; + } + else { + //reaches here if the user is on the root level group + list.basePath = GetBasePath('inventory') + $stateParams.inventory_id + '/root_groups'; + } let html = generateList.build({ - list: InventoryGroups, + list: list, mode: 'edit' }); html = generateList.wrapPanel(html); @@ -112,9 +120,17 @@ export default { controller: GroupsListController }, 'hostsList@inventoryManage': { - templateProvider: function(InventoryHosts, generateList) { + templateProvider: function(InventoryHosts, generateList, $stateParams, GetBasePath) { + let list = _.cloneDeep(InventoryHosts); + if($stateParams && $stateParams.group) { + list.basePath = GetBasePath('groups') + _.last($stateParams.group) + '/all_hosts'; + } + else { + //reaches here if the user is on the root level group + list.basePath = GetBasePath('inventory') + $stateParams.inventory_id + '/hosts'; + } let html = generateList.build({ - list: InventoryHosts, + list: list, mode: 'edit' }); return generateList.wrapPanel(html); diff --git a/awx/ui/client/src/job-results/host-status-bar/host-status-bar.directive.js b/awx/ui/client/src/job-results/host-status-bar/host-status-bar.directive.js index f7fbd2e8f6..778d238e47 100644 --- a/awx/ui/client/src/job-results/host-status-bar/host-status-bar.directive.js +++ b/awx/ui/client/src/job-results/host-status-bar/host-status-bar.directive.js @@ -15,7 +15,7 @@ export default [ 'templateUrl', link: function(scope) { // as count is changed by event data coming in, // update the host status bar - scope.$watch('count', function(val) { + var toDestroy = scope.$watch('count', function(val) { if (val) { Object.keys(val).forEach(key => { // reposition the hosts status bar by setting @@ -38,6 +38,10 @@ export default [ 'templateUrl', .filter(key => (val[key] > 0)).length > 0); } }); + + scope.$on('$destroy', function(){ + toDestroy(); + }); } }; }]; diff --git a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.block.less b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.block.less index 408e4cbb32..7ff93d17ee 100644 --- a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.block.less +++ b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.block.less @@ -162,6 +162,7 @@ .JobResultsStdOut-stdoutColumn { padding-left: 20px; + padding-right: 20px; padding-top: 2px; padding-bottom: 2px; color: @default-interface-txt; @@ -171,6 +172,12 @@ width:100%; } +.JobResultsStdOut-stdoutColumn--tooMany { + font-weight: bold; + text-transform: uppercase; + color: @default-err; +} + .JobResultsStdOut-stdoutColumn { cursor: pointer; } @@ -216,6 +223,11 @@ color: @default-interface-txt; } +.JobResultsStdOut-cappedLine { + color: @b7grey; + font-style: italic; +} + @media (max-width: @breakpoint-md) { .JobResultsStdOut-numberColumnPreload { display: none; diff --git a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.directive.js b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.directive.js index 77c87c74da..14a34a607a 100644 --- a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.directive.js +++ b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.directive.js @@ -12,6 +12,18 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll', templateUrl: templateUrl('job-results/job-results-stdout/job-results-stdout'), restrict: 'E', link: function(scope, element) { + var toDestroy = [], + resizer, + scrollWatcher; + + scope.$on('$destroy', function(){ + $(window).off("resize", resizer); + $(window).off("scroll", scrollWatcher); + $(".JobResultsStdOut-stdoutContainer").off('scroll', + scrollWatcher); + toDestroy.forEach(closureFunc => closureFunc()); + }); + scope.stdoutContainerAvailable.resolve("container available"); // utility function used to find the top visible line and // parent header in the pane @@ -115,9 +127,15 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll', // stop iterating over the standard out // lines once the first one has been // found + + $this = null; return false; - } - }); + } + + $this = null; + }); + + $container = null; return { visLine: visItem, @@ -131,22 +149,24 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll', } else { scope.isMobile = false; } - // watch changes to the window size - $(window).resize(function() { + + resizer = function() { // and update the isMobile var accordingly if (window.innerWidth <= 1200 && !scope.isMobile) { scope.isMobile = true; } else if (window.innerWidth > 1200 & scope.isMobile) { scope.isMobile = false; } - }); + }; + // watch changes to the window size + $(window).resize(resizer); var lastScrollTop; var initScrollTop = function() { lastScrollTop = 0; }; - var scrollWatcher = function() { + scrollWatcher = function() { var st = $(this).scrollTop(); var netScroll = st + $(this).innerHeight(); var fullHeight; @@ -178,11 +198,15 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll', } lastScrollTop = st; + + st = null; + netScroll = null; + fullHeight = null; }; // update scroll watchers when isMobile changes based on // window resize - scope.$watch('isMobile', function(val) { + toDestroy.push(scope.$watch('isMobile', function(val) { if (val === true) { // make sure ^ TOP always shown for mobile scope.stdoutOverflowed = true; @@ -204,7 +228,7 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll', $(".JobResultsStdOut-stdoutContainer").on('scroll', scrollWatcher); } - }); + })); // called to scroll to follow anchor scope.followScroll = function() { @@ -237,7 +261,7 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll', // if following becomes active, go ahead and get to the bottom // of the standard out pane - scope.$watch('followEngaged', function(val) { + toDestroy.push(scope.$watch('followEngaged', function(val) { // scroll to follow point if followEngaged is true if (val) { scope.followScroll(); @@ -251,7 +275,7 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll', scope.followTooltip = "Click to follow standard out as it comes in."; } } - }); + })); // follow button ng-click function scope.followToggleClicked = function() { diff --git a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.partial.html b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.partial.html index 0ba992b146..63e41b8fa8 100644 --- a/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.partial.html +++ b/awx/ui/client/src/job-results/job-results-stdout/job-results-stdout.partial.html @@ -34,6 +34,13 @@

+
+
+ +
+
The standard output is too large to display. Please specify additional filters to narrow the standard out.
+
val[0] === status) .map(val => val[1])[0]; $scope.status_tooltip = "Job " + $scope.status_label; } - }); + })); // update the job_status value. Use the cached rootScope value if there // is one. This is a workaround when the rest call for the jobData is @@ -185,7 +191,12 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy // This is where the async updates to the UI actually happen. // Flow is event queue munging in the service -> $scope setting in here - var processEvent = function(event) { + var processEvent = function(event, context) { + // only care about filter context checking when the event comes + // as a rest call + if (context && context !== currentContext) { + return; + } // put the event in the queue var mungedEvent = eventQueue.populate(event); @@ -278,6 +289,9 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy .stdout)($scope.events[mungedEvent .counter])); } + + classList = null; + putIn = null; } else { // this is a header or recap line, so just // append to the bottom @@ -357,99 +371,113 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy getSkeleton(jobData.related.job_events + "?order_by=id&or__event__in=playbook_on_start,playbook_on_play_start,playbook_on_task_start,playbook_on_stats"); }); + var getEvents; + + var processPage = function(events, context) { + // currentContext is the context of the filter when this request + // to processPage was made + // + // currentContext is the context of the filter currently + // + // if they are not the same, make sure to stop process events/ + // making rest calls for next pages/etc. (you can see context is + // also passed into getEvents and processEvent and similar checks + // exist in these functions) + // + // also, if the page doesn't contain results (i.e.: the response + // returns an error), don't process the page + if (context !== currentContext || events === undefined || + events.results === undefined) { + return; + } + + events.results.forEach(event => { + // get the name in the same format as the data + // coming over the websocket + event.event_name = event.event; + delete event.event; + + processEvent(event, context); + }); + if (events.next && !cancelRequests) { + getEvents(events.next, context); + } else { + // put those paused events into the pane + $scope.gotPreviouslyRanEvents.resolve(""); + } + }; + // grab non-header recap lines - var getEvents = function(url) { + getEvents = function(url, context) { + if (context !== currentContext) { + return; + } + jobResultsService.getEvents(url) .then(events => { - events.results.forEach(event => { - // get the name in the same format as the data - // coming over the websocket - event.event_name = event.event; - delete event.event; - processEvent(event); - }); - if (events.next) { - getEvents(events.next); - } else { - // put those paused events into the pane - $scope.gotPreviouslyRanEvents.resolve(""); - } + processPage(events, context); }); }; // grab non-header recap lines - $scope.$watch('job_event_dataset', function(val) { + toDestroy.push($scope.$watch('job_event_dataset', function(val) { + eventQueue.initialize(); + + Object.keys($scope.events) + .forEach(v => { + // dont destroy scope events for skeleton lines + let name = $scope.events[v].event.name; + + if (!(name === "playbook_on_play_start" || + name === "playbook_on_task_start" || + name === "playbook_on_stats")) { + $scope.events[v].$destroy(); + $scope.events[v] = null; + delete $scope.events[v]; + } + }); + // pause websocket events from coming in to the pane $scope.gotPreviouslyRanEvents = $q.defer(); + currentContext += 1; + + let context = currentContext; $( ".JobResultsStdOut-aLineOfStdOut.not_skeleton" ).remove(); $scope.hasSkeleton.promise.then(() => { - val.results.forEach(event => { - // get the name in the same format as the data - // coming over the websocket - event.event_name = event.event; - delete event.event; - processEvent(event); - }); - if (val.next) { - getEvents(val.next); + if (val.count > parseInt(val.maxEvents)) { + $(".header_task").hide(); + $(".header_play").hide(); + $scope.tooManyEvents = true; } else { - // put those paused events into the pane - $scope.gotPreviouslyRanEvents.resolve(""); + $(".header_task").show(); + $(".header_play").show(); + $scope.tooManyEvents = false; + processPage(val, context); } }); - }); + })); // Processing of job_events messages from the websocket - $scope.$on(`ws-job_events-${$scope.job.id}`, function(e, data) { + toDestroy.push($scope.$on(`ws-job_events-${$scope.job.id}`, function(e, data) { $q.all([$scope.gotPreviouslyRanEvents.promise, $scope.hasSkeleton.promise]).then(() => { - var url = Dataset - .config.url.split("?")[0] + - QuerySet.encodeQueryset($state.params.job_event_search); - var noFilter = (url.split("&") - .filter(v => v.indexOf("page=") !== 0 && - v.indexOf("/api/v1") !== 0 && - v.indexOf("order_by=id") !== 0 && - v.indexOf("not__event__in=playbook_on_start,playbook_on_play_start,playbook_on_task_start,playbook_on_stats") !== 0).length === 0); - - if(data.event_name === "playbook_on_start" || - data.event_name === "playbook_on_play_start" || - data.event_name === "playbook_on_task_start" || - data.event_name === "playbook_on_stats" || - noFilter) { - // for header and recap lines, as well as if no filters - // were added by the user, just put the line in the - // standard out pane (and increment play and task - // count) - if (data.event_name === "playbook_on_play_start") { - $scope.playCount++; - } else if (data.event_name === "playbook_on_task_start") { - $scope.taskCount++; - } - processEvent(data); - } else { - // to make sure host event/verbose lines go through a - // user defined filter, appent the id to the url, and - // make a request to the job_events endpoint with the - // id of the incoming event appended. If the event, - // is returned, put the line in the standard out pane - Rest.setUrl(`${url}&id=${data.id}`); - Rest.get() - .success(function(isHere) { - if (isHere.count) { - processEvent(data); - } - }); + // put the line in the + // standard out pane (and increment play and task + // count if applicable) + if (data.event_name === "playbook_on_play_start") { + $scope.playCount++; + } else if (data.event_name === "playbook_on_task_start") { + $scope.taskCount++; } - + processEvent(data); }); - }); + })); // Processing of job-status messages from the websocket - $scope.$on(`ws-jobs`, function(e, data) { + toDestroy.push($scope.$on(`ws-jobs`, function(e, data) { if (parseInt(data.unified_job_id, 10) === parseInt($scope.job.id,10)) { // controller is defined, so set the job_status @@ -477,5 +505,19 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy // for this job. cache the socket status on root scope $rootScope['lastSocketStatus' + data.unified_job_id] = data.status; } + })); + + $scope.$on('$destroy', function(){ + $( ".JobResultsStdOut-aLineOfStdOut" ).remove(); + cancelRequests = true; + eventQueue.initialize(); + Object.keys($scope.events) + .forEach(v => { + $scope.events[v].$destroy(); + $scope.events[v] = null; + }); + $scope.events = {}; + clearInterval(elapsedInterval); + toDestroy.forEach(closureFunc => closureFunc()); }); }]; diff --git a/awx/ui/client/src/job-results/job-results.partial.html b/awx/ui/client/src/job-results/job-results.partial.html index 6fe760b55e..16fc0bf3c0 100644 --- a/awx/ui/client/src/job-results/job-results.partial.html +++ b/awx/ui/client/src/job-results/job-results.partial.html @@ -36,9 +36,9 @@
@@ -520,11 +524,15 @@
+ +
+ + +
Please enter the number of days you would like to keep this data.
Please enter a valid number.
Please enter a non-negative number.
Please enter a number smaller than 9999.
-
diff --git a/awx/ui/client/src/notifications/add/add.controller.js b/awx/ui/client/src/notifications/add/add.controller.js index 1f007c3e2f..60eee42408 100644 --- a/awx/ui/client/src/notifications/add/add.controller.js +++ b/awx/ui/client/src/notifications/add/add.controller.js @@ -115,6 +115,17 @@ export default ['$rootScope', 'Rest', 'Wait', 'NotificationsFormObject', }); }; + $scope.emailOptionsChange = function () { + if ($scope.email_options === 'use_ssl') { + $scope.use_ssl = true; + $scope.use_tls = false; + } + else if ($scope.email_options === 'use_tls') { + $scope.use_ssl = false; + $scope.use_tls = true; + } + }; + // Save $scope.formSave = function() { var params, @@ -143,7 +154,7 @@ export default ['$rootScope', 'Rest', 'Wait', 'NotificationsFormObject', if (field.type === 'number') { $scope[i] = Number($scope[i]); } - if (field.name === "username" && $scope.notification_type.value === "email" && value === null) { + if (i === "username" && $scope.notification_type.value === "email" && value === null) { $scope[i] = ""; } if (field.type === 'sensitive' && value === null) { @@ -156,13 +167,13 @@ export default ['$rootScope', 'Rest', 'Wait', 'NotificationsFormObject', .filter(i => (form.fields[i].ngShow && form.fields[i].ngShow.indexOf(v) > -1)) .map(i => [i, processValue($scope[i], i, form.fields[i])])); - delete params.notification_configuration.checkbox_group; + delete params.notification_configuration.email_options; - for (var j = 0; j < form.fields.checkbox_group.fields.length; j++) { - if (form.fields.checkbox_group.fields[j].ngShow && form.fields.checkbox_group.fields[j].ngShow.indexOf(v) > -1) { - params.notification_configuration[form.fields.checkbox_group.fields[j].name] = Boolean($scope[form.fields.checkbox_group.fields[j].name]); + for(var j = 0; j < form.fields.email_options.options.length; j++) { + if(form.fields.email_options.options[j].ngShow && form.fields.email_options.options[j].ngShow.indexOf(v) > -1) { + params.notification_configuration[form.fields.email_options.options[j].value] = Boolean($scope[form.fields.email_options.options[j].value]); + } } - } Wait('start'); Rest.setUrl(url); diff --git a/awx/ui/client/src/notifications/edit/edit.controller.js b/awx/ui/client/src/notifications/edit/edit.controller.js index 57f4a25055..0126416555 100644 --- a/awx/ui/client/src/notifications/edit/edit.controller.js +++ b/awx/ui/client/src/notifications/edit/edit.controller.js @@ -67,15 +67,25 @@ export default ['Rest', 'Wait', master[fld] = data[fld]; } - if (form.fields[fld].type === 'checkbox_group') { - // Loop across the group and put the child data on scope - for (var j = 0; j < form.fields[fld].fields.length; j++) { - if (data.notification_configuration[form.fields[fld].fields[j].name]) { - $scope[form.fields[fld].fields[j].name] = data.notification_configuration[form.fields[fld].fields[j].name]; - master[form.fields[fld].fields[j].name] = data.notification_configuration[form.fields[fld].fields[j].name]; - } + if(form.fields[fld].type === 'radio_group') { + if(data.notification_configuration.use_ssl === true){ + $scope.email_options = "use_ssl"; + master.email_options = "use_ssl"; + $scope.use_ssl = true; + master.use_ssl = true; + $scope.use_tls = false; + master.use_tls = false; } - } else { + if(data.notification_configuration.use_tls === true){ + $scope.email_options = "use_tls"; + master.email_options = "use_tls"; + $scope.use_ssl = false; + master.use_ssl = false; + $scope.use_tls = true; + master.use_tls = true; + } + } + else { if (data.notification_configuration[fld]) { $scope[fld] = data.notification_configuration[fld]; master[fld] = data.notification_configuration[fld]; @@ -84,7 +94,7 @@ export default ['Rest', 'Wait', if (form.fields[fld].name === 'headers') { $scope[fld] = JSON.stringify($scope[fld], null, 2); } else { - $scope[fld] = $scope[fld].toString().replace(',', '\n'); + $scope[fld] = $scope[fld].toString().replace(/,/g, '\n'); } } } @@ -193,6 +203,17 @@ export default ['Rest', 'Wait', }); }; + $scope.emailOptionsChange = function () { + if ($scope.email_options === 'use_ssl') { + $scope.use_ssl = true; + $scope.use_tls = false; + } + else if ($scope.email_options === 'use_tls') { + $scope.use_ssl = false; + $scope.use_tls = true; + } + }; + $scope.formSave = function() { var params, v = $scope.notification_type.value; @@ -220,10 +241,10 @@ export default ['Rest', 'Wait', if (field.type === 'number') { $scope[i] = Number($scope[i]); } - if (field.name === "username" && $scope.notification_type.value === "email" && value === null) { + if (i === "username" && $scope.notification_type.value === "email" && (value === null || value === undefined)) { $scope[i] = ""; } - if (field.type === 'sensitive' && value === null) { + if (field.type === 'sensitive' && (value === null || value === undefined)) { $scope[i] = ""; } return $scope[i]; @@ -233,13 +254,10 @@ export default ['Rest', 'Wait', .filter(i => (form.fields[i].ngShow && form.fields[i].ngShow.indexOf(v) > -1)) .map(i => [i, processValue($scope[i], i, form.fields[i])])); - delete params.notification_configuration.checkbox_group; + delete params.notification_configuration.email_options; - for (var j = 0; j < form.fields.checkbox_group.fields.length; j++) { - if (form.fields.checkbox_group.fields[j].ngShow && form.fields.checkbox_group.fields[j].ngShow.indexOf(v) > -1) { - params.notification_configuration[form.fields.checkbox_group.fields[j].name] = Boolean($scope[form.fields.checkbox_group.fields[j].name]); - } - } + params.notification_configuration.use_ssl = Boolean($scope.use_ssl); + params.notification_configuration.use_tls = Boolean($scope.use_tls); Wait('start'); Rest.setUrl(url + id + '/'); diff --git a/awx/ui/client/src/notifications/notificationTemplates.form.js b/awx/ui/client/src/notifications/notificationTemplates.form.js index 48fcbad9d7..63a87c3bb2 100644 --- a/awx/ui/client/src/notifications/notificationTemplates.form.js +++ b/awx/ui/client/src/notifications/notificationTemplates.form.js @@ -323,6 +323,7 @@ export default ['i18n', function(i18n) { headers: { label: i18n._('HTTP Headers'), type: 'textarea', + name: 'headers', rows: 5, 'class': 'Form-formGroup--fullWidth', awRequiredWhen: { @@ -387,25 +388,23 @@ export default ['i18n', function(i18n) { subForm: 'typeSubForm', ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)' }, - checkbox_group: { - label: i18n._('Options'), - type: 'checkbox_group', + email_options: { + label: 'Options', + type: 'radio_group', subForm: 'typeSubForm', ngShow: "notification_type.value == 'email'", - fields: [{ - name: 'use_tls', - label: i18n._('Use TLS'), - type: 'checkbox', + class: 'squeeze', + ngChange: "emailOptionsChange()", + options: [{ + value: 'use_tls', + label: 'Use TLS', ngShow: "notification_type.value == 'email' ", - labelClass: 'checkbox-options stack-inline', - ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)' + labelClass: 'checkbox-options stack-inline' }, { - name: 'use_ssl', - label: i18n._('Use SSL'), - type: 'checkbox', + value: 'use_ssl', + label: 'Use SSL', ngShow: "notification_type.value == 'email'", - labelClass: 'checkbox-options stack-inline', - ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)' + labelClass: 'checkbox-options stack-inline' }] } }, diff --git a/awx/ui/client/src/organizations/list/organizations-list.controller.js b/awx/ui/client/src/organizations/list/organizations-list.controller.js index 9bae54afc8..3849c123a4 100644 --- a/awx/ui/client/src/organizations/list/organizations-list.controller.js +++ b/awx/ui/client/src/organizations/list/organizations-list.controller.js @@ -127,6 +127,16 @@ export default ['$stateParams', '$scope', '$rootScope', '$location', }); }; + function isDeletedOrganizationBeingEdited(deleted_organization_id, editing_organization_id) { + if (editing_organization_id === undefined) { + return false; + } + if (deleted_organization_id === editing_organization_id) { + return true; + } + return false; + } + $scope.deleteOrganization = function(id, name) { var action = function() { @@ -137,7 +147,11 @@ export default ['$stateParams', '$scope', '$rootScope', '$location', Rest.destroy() .success(function() { Wait('stop'); - $state.reload('organizations'); + if (isDeletedOrganizationBeingEdited(id, parseInt($stateParams.organization_id)) === true) { + $state.go('^', null, { reload: true }); + } else { + $state.reload('organizations'); + } }) .error(function(data, status) { ProcessErrors($scope, data, status, null, { diff --git a/awx/ui/client/src/partials/job-template-smart-status.html b/awx/ui/client/src/partials/job-template-smart-status.html index 1c45c5fe36..d4f8d860b3 100644 --- a/awx/ui/client/src/partials/job-template-smart-status.html +++ b/awx/ui/client/src/partials/job-template-smart-status.html @@ -1 +1 @@ - + diff --git a/awx/ui/client/src/partials/jobs.html b/awx/ui/client/src/partials/jobs.html index 00de9af821..46f7b09761 100644 --- a/awx/ui/client/src/partials/jobs.html +++ b/awx/ui/client/src/partials/jobs.html @@ -16,7 +16,7 @@ -
+
diff --git a/awx/ui/client/src/portal-mode/portal-mode-jobs.controller.js b/awx/ui/client/src/portal-mode/portal-mode-jobs.controller.js index 6f7f5380f5..71e1747a8d 100644 --- a/awx/ui/client/src/portal-mode/portal-mode-jobs.controller.js +++ b/awx/ui/client/src/portal-mode/portal-mode-jobs.controller.js @@ -9,27 +9,25 @@ export function PortalModeJobsController($scope, $rootScope, $state, $stateParam var list = PortalJobsList; $scope.$on('ws-jobs', function() { - // @issue: OLD SEARCH - //$scope.search('job'); - }); - if ($rootScope.removeJobStatusChange) { - $rootScope.removeJobStatusChange(); - } - $rootScope.removeJobStatusChange = $rootScope.$on('JobStatusChange-portal', function() { $state.go('.', null, { reload: true }); }); init(); - function init() { + function init(data) { + let d = (!data) ? Dataset : data; // search init $scope.list = list; - $scope[`${list.iterator}_dataset`] = Dataset.data; + $scope[`${list.iterator}_dataset`] = d.data; $scope[list.name] = $scope[`${list.iterator}_dataset`].results; $scope.iterator = list.iterator; } + $scope.$on('filterPortalJobs', function(e, data){ + init(data); + }); + $scope.refresh = function() { $state.go('.', null, {reload: true}); }; diff --git a/awx/ui/client/src/portal-mode/portal-mode.route.js b/awx/ui/client/src/portal-mode/portal-mode.route.js index 9f9f159085..403ace5795 100644 --- a/awx/ui/client/src/portal-mode/portal-mode.route.js +++ b/awx/ui/client/src/portal-mode/portal-mode.route.js @@ -47,14 +47,18 @@ export default { $scope.activeFilter = 'user'; path = GetBasePath('jobs'); $stateParams.job_search.created_by = $rootScope.current_user.id; - qs.search(path, $stateParams.job_search); + qs.search(path, $stateParams.job_search).then((response) => { + $scope.$broadcast('filterPortalJobs', response); + }); }; $scope.filterAll = function() { $scope.activeFilter = 'all'; delete $stateParams.job_search.created_by; path = GetBasePath('jobs'); - qs.search(path, $stateParams.job_search); + qs.search(path, $stateParams.job_search).then((response) => { + $scope.$broadcast('filterPortalJobs', response); + }); }; } ] diff --git a/awx/ui/client/src/scheduler/main.js b/awx/ui/client/src/scheduler/main.js index f8620c880e..9e04feae66 100644 --- a/awx/ui/client/src/scheduler/main.js +++ b/awx/ui/client/src/scheduler/main.js @@ -285,9 +285,7 @@ export default } }, data: { - activityStream: true, - activityStreamTarget: 'job', - activityStreamId: 'id' + activityStream: false, }, ncyBreadcrumb: { parent: 'jobs', diff --git a/awx/ui/client/src/shared/Utilities.js b/awx/ui/client/src/shared/Utilities.js index 9bc18dfd13..3bb9c02de0 100644 --- a/awx/ui/client/src/shared/Utilities.js +++ b/awx/ui/client/src/shared/Utilities.js @@ -198,6 +198,8 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter']) msg += 'Please contact your system administrator.'; } Alert(defaultMsg.hdr, msg); + } else if (status === 409) { + Alert('Conflict', data.conflict || "Resource currently in use."); } else if (status === 410) { Alert('Deleted Object', 'The requested object was previously deleted and can no longer be accessed.'); } else if ((status === 'Token is expired') || (status === 401 && data.detail && data.detail === 'Token is expired') || diff --git a/awx/ui/client/src/shared/directives.js b/awx/ui/client/src/shared/directives.js index 1da55f80f8..f2e2b1d58d 100644 --- a/awx/ui/client/src/shared/directives.js +++ b/awx/ui/client/src/shared/directives.js @@ -484,7 +484,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper']) function applyValidation(viewValue) { basePath = GetBasePath(elm.attr('data-basePath')) || elm.attr('data-basePath'); query = elm.attr('data-query'); - query = query.replace(/\:value/, encodeURI(viewValue)); + query = query.replace(/\:value/, encodeURIComponent(viewValue)); Rest.setUrl(`${basePath}${query}`); // https://github.com/ansible/ansible-tower/issues/3549 // capturing both success/failure conditions in .then() promise @@ -620,12 +620,10 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper']) if (attrs.tipWatch) { // Add dataTipWatch: 'variable_name' - scope.$watch(attrs.tipWatch, function(newVal, oldVal) { - if (newVal !== oldVal) { - // Where did fixTitle come from?: - // http://stackoverflow.com/questions/9501921/change-twitter-bootstrap-tooltip-content-on-click - $(element).tooltip('hide').attr('data-original-title', newVal).tooltip('fixTitle'); - } + scope.$watch(attrs.tipWatch, function(newVal) { + // Where did fixTitle come from?: + // http://stackoverflow.com/questions/9501921/change-twitter-bootstrap-tooltip-content-on-click + $(element).tooltip('hide').attr('data-original-title', newVal).tooltip('fixTitle'); }); } } diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index 63146ce890..7c0804d499 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -1479,7 +1479,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += `
+ ng-hide="${itm}.length === 0 && (searchTags | isEmpty)"> + ng-show="${itm}.length === 0 && !(searchTags | isEmpty)">
No records matched your search.
@@ -1865,7 +1865,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat // Show the "no items" box when loading is done and the user isn't actively searching and there are no results var emptyListText = (collection.emptyListText) ? collection.emptyListText : i18n._("PLEASE ADD ITEMS TO THIS LIST"); html += `
`; - html += `
${emptyListText}
`; + html += `
${emptyListText}
`; html += '
'; html += ` diff --git a/awx/ui/client/src/shared/generator-helpers.js b/awx/ui/client/src/shared/generator-helpers.js index e6d517b7f0..34978cdf5e 100644 --- a/awx/ui/client/src/shared/generator-helpers.js +++ b/awx/ui/client/src/shared/generator-helpers.js @@ -591,6 +591,9 @@ angular.module('GeneratorHelpers', [systemStatus.name]) } } else { + if(field.simpleTip) { + html += ``; + } // Add icon: if (field.ngShowIcon) { html += " "; @@ -615,6 +618,9 @@ angular.module('GeneratorHelpers', [systemStatus.name]) if (field.text) { html += field.text; } + if(field.simpleTip) { + html += ``; + } } if (list.name === 'hosts' || list.name === 'groups') { diff --git a/awx/ui/client/src/shared/list-generator/list-generator.factory.js b/awx/ui/client/src/shared/list-generator/list-generator.factory.js index fd664dc167..36cb5e5a65 100644 --- a/awx/ui/client/src/shared/list-generator/list-generator.factory.js +++ b/awx/ui/client/src/shared/list-generator/list-generator.factory.js @@ -134,7 +134,7 @@ export default ['$location', '$compile', '$rootScope', 'Attr', 'Icon', base, action, fld, cnt, field_action, fAction, itm; if (options.mode !== 'lookup') { - if (options.title !== false) { + if (options.title !== false && list.title !== false) { html += "
"; html += "
"; @@ -311,7 +311,7 @@ export default ['$location', '$compile', '$rootScope', 'Attr', 'Icon', } if (list.multiSelect) { - innerTable += ''; + innerTable += ''; } // Change layout if a lookup list, place radio buttons before labels diff --git a/awx/ui/client/src/shared/multi-select-list/select-list-item.directive.js b/awx/ui/client/src/shared/multi-select-list/select-list-item.directive.js index 4867c5e07c..a9eeff647e 100644 --- a/awx/ui/client/src/shared/multi-select-list/select-list-item.directive.js +++ b/awx/ui/client/src/shared/multi-select-list/select-list-item.directive.js @@ -30,13 +30,12 @@ export default item: '=item' }, require: '^multiSelectList', - template: '', + template: '', link: function(scope, element, attrs, multiSelectList) { scope.decoratedItem = multiSelectList.registerItem(scope.item); - scope.isSelected = scope.decoratedItem.isSelected ? true : false; - scope.$watch('isSelected', function(value) { + scope.$watch('item.isSelected', function(value) { if (value === true) { multiSelectList.selectItem(scope.decoratedItem); } else if (value === false) { diff --git a/awx/ui/client/src/shared/paginate/paginate.controller.js b/awx/ui/client/src/shared/paginate/paginate.controller.js index fdd80000c7..bd9ff29032 100644 --- a/awx/ui/client/src/shared/paginate/paginate.controller.js +++ b/awx/ui/client/src/shared/paginate/paginate.controller.js @@ -59,7 +59,7 @@ export default ['$scope', '$stateParams', '$state', '$filter', 'GetBasePath', 'Q return `1 - ${pageSize}`; } else { let floor = (($scope.current() - 1) * parseInt(pageSize)) + 1; - let ceil = floor + parseInt(pageSize); + let ceil = floor + parseInt(pageSize) < $scope.dataset.count ? floor + parseInt(pageSize) : $scope.dataset.count; return `${floor} - ${ceil}`; } } diff --git a/awx/ui/client/src/shared/smart-search/main.js b/awx/ui/client/src/shared/smart-search/main.js index 7653df7bd7..e7aaf825a7 100644 --- a/awx/ui/client/src/shared/smart-search/main.js +++ b/awx/ui/client/src/shared/smart-search/main.js @@ -2,11 +2,12 @@ import directive from './smart-search.directive'; import controller from './smart-search.controller'; import service from './queryset.service'; import DjangoSearchModel from './django-search-model.class'; - +import smartSearchService from './smart-search.service'; export default angular.module('SmartSearchModule', []) .directive('smartSearch', directive) .controller('SmartSearchController', controller) .service('QuerySet', service) + .service('SmartSearchService', smartSearchService) .constant('DjangoSearchModel', DjangoSearchModel); diff --git a/awx/ui/client/src/shared/smart-search/queryset.service.js b/awx/ui/client/src/shared/smart-search/queryset.service.js index 359245bed4..3b7fb90c5e 100644 --- a/awx/ui/client/src/shared/smart-search/queryset.service.js +++ b/awx/ui/client/src/shared/smart-search/queryset.service.js @@ -1,5 +1,5 @@ -export default ['$q', 'Rest', 'ProcessErrors', '$rootScope', 'Wait', 'DjangoSearchModel', '$cacheFactory', - function($q, Rest, ProcessErrors, $rootScope, Wait, DjangoSearchModel, $cacheFactory) { +export default ['$q', 'Rest', 'ProcessErrors', '$rootScope', 'Wait', 'DjangoSearchModel', '$cacheFactory', 'SmartSearchService', + function($q, Rest, ProcessErrors, $rootScope, Wait, DjangoSearchModel, $cacheFactory, SmartSearchService) { return { // kick off building a model for a specific endpoint // this is usually a list's basePath @@ -67,29 +67,124 @@ export default ['$q', 'Rest', 'ProcessErrors', '$rootScope', 'Wait', 'DjangoSear return angular.isObject(params) ? `?${queryset}` : ''; function encodeTerm(value, key){ + + key = key.replace(/__icontains_DEFAULT/g, "__icontains"); + key = key.replace(/__search_DEFAULT/g, "__search"); + if (Array.isArray(value)){ - return _.map(value, (item) => `${key}=${item}`).join('&') + '&'; + let concated = ''; + angular.forEach(value, function(item){ + if(item && typeof item === 'string') { + item = item.replace(/"|'/g, ""); + } + concated += `${key}=${item}&`; + }); + return concated; } else { + if(value && typeof value === 'string') { + value = value.replace(/"|'/g, ""); + } return `${key}=${value}&`; } } }, // encodes a ui smart-search param to a django-friendly param // operand:key:comparator:value => {operand__key__comparator: value} - encodeParam(param){ - let split = param.split(':'); - return {[split.slice(0,split.length -1).join('__')] : split[split.length-1]}; + encodeParam(params){ + // Assumption here is that we have a key and a value so the length + // of the paramParts array will be 2. [0] is the key and [1] the value + let paramParts = SmartSearchService.splitTermIntoParts(params.term); + let keySplit = paramParts[0].split('.'); + let exclude = false; + let lessThanGreaterThan = paramParts[1].match(/^(>|<).*$/) ? true : false; + if(keySplit[0].match(/^-/g)) { + exclude = true; + keySplit[0] = keySplit[0].replace(/^-/, ''); + } + let paramString = exclude ? "not__" : ""; + let valueString = paramParts[1]; + if(keySplit.length === 1) { + if(params.searchTerm && !lessThanGreaterThan) { + paramString += keySplit[0] + '__icontains_DEFAULT'; + } + else if(params.relatedSearchTerm) { + paramString += keySplit[0] + '__search_DEFAULT'; + } + else { + paramString += keySplit[0]; + } + } + else { + paramString += keySplit.join('__'); + } + + if(lessThanGreaterThan) { + if(paramParts[1].match(/^>=.*$/)) { + paramString += '__gte'; + valueString = valueString.replace(/^(>=)/,""); + } + else if(paramParts[1].match(/^<=.*$/)) { + paramString += '__lte'; + valueString = valueString.replace(/^(<=)/,""); + } + else if(paramParts[1].match(/^<.*$/)) { + paramString += '__lt'; + valueString = valueString.replace(/^(<)/,""); + } + else if(paramParts[1].match(/^>.*$/)) { + paramString += '__gt'; + valueString = valueString.replace(/^(>)/,""); + } + } + + return {[paramString] : valueString}; }, // decodes a django queryset param into a ui smart-search tag or set of tags decodeParam(value, key){ + + let decodeParamString = function(searchString) { + if(key === 'search') { + // Don't include 'search:' in the search tag + return decodeURIComponent(`${searchString}`); + } + else { + key = key.replace(/__icontains_DEFAULT/g, ""); + key = key.replace(/__search_DEFAULT/g, ""); + let split = key.split('__'); + let decodedParam = searchString; + let exclude = false; + if(key.startsWith('not__')) { + exclude = true; + split = split.splice(1, split.length); + } + if(key.endsWith('__gt')) { + decodedParam = '>' + decodedParam; + split = split.splice(0, split.length-1); + } + else if(key.endsWith('__lt')) { + decodedParam = '<' + decodedParam; + split = split.splice(0, split.length-1); + } + else if(key.endsWith('__gte')) { + decodedParam = '>=' + decodedParam; + split = split.splice(0, split.length-1); + } + else if(key.endsWith('__lte')) { + decodedParam = '<=' + decodedParam; + split = split.splice(0, split.length-1); + } + return exclude ? `-${split.join('.')}:${decodedParam}` : `${split.join('.')}:${decodedParam}`; + } + }; + if (Array.isArray(value)){ return _.map(value, (item) => { - return `${key.split('__').join(':')}:${item}`; + return decodeParamString(item); }); } else { - return `${key.split('__').join(':')}:${value}`; + return decodeParamString(value); } }, @@ -147,20 +242,33 @@ export default ['$q', 'Rest', 'ProcessErrors', '$rootScope', 'Wait', 'DjangoSear Wait('start'); this.url = `${endpoint}${this.encodeQueryset(params)}`; Rest.setUrl(this.url); + return Rest.get() - .success(this.success.bind(this)) - .error(this.error.bind(this)) - .finally(Wait('stop')); + .then(function(response) { + Wait('stop'); + + if (response + .headers('X-UI-Max-Events') !== null) { + response.data.maxEvents = response. + headers('X-UI-Max-Events'); + } + + return response; + }) + .catch(function(response) { + Wait('stop'); + + this.error(response.data, response.status); + + return response; + }.bind(this)); }, error(data, status) { ProcessErrors($rootScope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + this.url + '. GET returned: ' + status }); - }, - success(data) { - return data; - }, + } }; } ]; diff --git a/awx/ui/client/src/shared/smart-search/smart-search.block.less b/awx/ui/client/src/shared/smart-search/smart-search.block.less index 0b22331d5a..8d3a1e3b49 100644 --- a/awx/ui/client/src/shared/smart-search/smart-search.block.less +++ b/awx/ui/client/src/shared/smart-search/smart-search.block.less @@ -186,8 +186,6 @@ .SmartSearch-keyPane { max-height: 200px; overflow: auto; - display: flex; - flex-wrap: wrap; margin: 0px 0px 20px 0px; font-size: 12px; width: 100%; @@ -197,29 +195,11 @@ border: 1px solid @login-notice-border; background-color: @login-notice-bg; color: @login-notice-text; -} - -.SmartSearch-relations{ - margin-top: 15px; + position: relative; } .SmartSearch-keyRow { - width: 33%; - flex: 1 1 auto; - flex-direction: column; margin-bottom: 15px; - padding-right: 50px; -} -// 100% rows in a modal -.modal-body .SmartSearch-keyRow{ - width: 100%; -} -// `.${list.name}List` class can be used to set add custom class overrides -.groupsList .SmartSearch-keyRow, .hostsList .SmartSearch-keyRow, .PortalMode .SmartSearch-keyRow{ - width: 100%; -} -.SmartSearch-keyRow:nth-child(3){ - padding-right: 0px; } .SmartSearch-keyName { @@ -232,3 +212,30 @@ .SmartSearch-keyComparators { flex: 1 0 auto; } + +.SmartSearch-keyPane--exitHolder { + position: absolute; + right: 10px; + top: 10px; +} + +.SmartSearch-keyPane--exit { + background-color: @login-notice-bg; +} + +.SmartSearch-examples { + display: flex; +} + +.SmartSearch-examples--title { + margin-right: 5px; +} + +.SmartSearch-examples--search { + color: @default-err; + background-color: @default-bg; + border: 1px solid @default-border; + border-radius: 5px; + padding: 0px 5px; + margin-right: 5px; +} diff --git a/awx/ui/client/src/shared/smart-search/smart-search.controller.js b/awx/ui/client/src/shared/smart-search/smart-search.controller.js index 95f3be3adb..b1baca4346 100644 --- a/awx/ui/client/src/shared/smart-search/smart-search.controller.js +++ b/awx/ui/client/src/shared/smart-search/smart-search.controller.js @@ -1,5 +1,5 @@ -export default ['$stateParams', '$scope', '$state', 'QuerySet', 'GetBasePath', 'QuerySet', - function($stateParams, $scope, $state, QuerySet, GetBasePath, qs) { +export default ['$stateParams', '$scope', '$state', 'QuerySet', 'GetBasePath', 'QuerySet', 'SmartSearchService', + function($stateParams, $scope, $state, QuerySet, GetBasePath, qs, SmartSearchService) { let path, relations, // steps through the current tree of $state configurations, grabs default search params @@ -17,6 +17,7 @@ export default ['$stateParams', '$scope', '$state', 'QuerySet', 'GetBasePath', ' $scope.searchTags = stripDefaultParams($state.params[`${$scope.iterator}_search`]); qs.initFieldset(path, $scope.djangoModel, relations).then((data) => { $scope.models = data.models; + $scope.options = data.options.data; $scope.$emit(`${$scope.list.iterator}_options`, data.options); }); } @@ -27,7 +28,20 @@ export default ['$stateParams', '$scope', '$state', 'QuerySet', 'GetBasePath', ' // setting the default value of a term to null in a state definition is a very explicit way to ensure it will NEVER generate a search tag, even with a non-default value return defaults[key] !== value && key !== 'order_by' && key !== 'page' && key !== 'page_size' && defaults[key] !== null; }); - return _(stripped).map(qs.decodeParam).flatten().value(); + let strippedCopy = _.cloneDeep(stripped); + if(_.keys(_.pick(defaults, _.keys(strippedCopy))).length > 0){ + for (var key in strippedCopy) { + if (strippedCopy.hasOwnProperty(key)) { + let value = strippedCopy[key]; + if(_.isArray(value)){ + let index = _.indexOf(value, defaults[key]); + value = value.splice(index, 1)[0]; + } + } + } + stripped = strippedCopy; + } + return _(strippedCopy).map(qs.decodeParam).flatten().value(); } // searchable relationships @@ -38,6 +52,16 @@ export default ['$stateParams', '$scope', '$state', 'QuerySet', 'GetBasePath', ' return flat; } + function setDefaults(term) { + if ($scope.list.defaultSearchParams) { + return $scope.list.defaultSearchParams(term); + } else { + return { + search: encodeURIComponent(term) + }; + } + } + $scope.toggleKeyPane = function() { $scope.showKeyPane = !$scope.showKeyPane; }; @@ -56,10 +80,37 @@ export default ['$stateParams', '$scope', '$state', 'QuerySet', 'GetBasePath', ' // remove tag, merge new queryset, $state.go $scope.remove = function(index) { - let removed = qs.encodeParam($scope.searchTags.splice(index, 1)[0]); + let tagToRemove = $scope.searchTags.splice(index, 1)[0]; + let termParts = SmartSearchService.splitTermIntoParts(tagToRemove); + let removed; + if (termParts.length === 1) { + removed = setDefaults(tagToRemove); + } + else { + let root = termParts[0].split(".")[0].replace(/^-/, ''); + let encodeParams = { + term: tagToRemove + }; + if(_.has($scope.options.actions.GET, root)) { + if($scope.options.actions.GET[root].type && $scope.options.actions.GET[root].type === 'field') { + encodeParams.relatedSearchTerm = true; + } + else { + encodeParams.searchTerm = true; + } + removed = qs.encodeParam(encodeParams); + } + else { + removed = setDefaults(tagToRemove); + } + } _.each(removed, (value, key) => { if (Array.isArray(queryset[key])){ _.remove(queryset[key], (item) => item === value); + // If the array is now empty, remove that key + if(queryset[key].length === 0) { + delete queryset[key]; + } } else { delete queryset[key]; @@ -79,26 +130,46 @@ export default ['$stateParams', '$scope', '$state', 'QuerySet', 'GetBasePath', ' let params = {}, origQueryset = _.clone(queryset); - function setDefaults(term) { - // "name" and "description" are sane defaults for MOST models, but not ALL! - // defaults may be configured in ListDefinition.defaultSearchParams - if ($scope.list.defaultSearchParams) { - return $scope.list.defaultSearchParams(term); - } else { - return { - or__name__icontains: term, - or__description__icontains: term - }; - } - } + // Remove leading/trailing whitespace if there is any + terms = terms.trim(); if(terms && terms !== '') { - _.forEach(terms.split(' '), (term) => { + // Split the terms up + let splitTerms = SmartSearchService.splitSearchIntoTerms(terms); + _.forEach(splitTerms, (term) => { + + let termParts = SmartSearchService.splitTermIntoParts(term); + + function combineSameSearches(a,b){ + if (_.isArray(a)) { + return a.concat(b); + } + else { + if(a) { + return [a,b]; + } + } + } + // if only a value is provided, search using default keys - if (term.split(':').length === 1) { - params = _.merge(params, setDefaults(term)); + if (termParts.length === 1) { + params = _.merge(params, setDefaults(term), combineSameSearches); } else { - params = _.merge(params, qs.encodeParam(term)); + // Figure out if this is a search term + let root = termParts[0].split(".")[0].replace(/^-/, ''); + if(_.has($scope.options.actions.GET, root)) { + if($scope.options.actions.GET[root].type && $scope.options.actions.GET[root].type === 'field') { + params = _.merge(params, qs.encodeParam({term: term, relatedSearchTerm: true}), combineSameSearches); + } + else { + params = _.merge(params, qs.encodeParam({term: term, searchTerm: true}), combineSameSearches); + } + } + // Its not a search term or a related search term - treat it as a string + else { + params = _.merge(params, setDefaults(term), combineSameSearches); + } + } }); diff --git a/awx/ui/client/src/shared/smart-search/smart-search.partial.html b/awx/ui/client/src/shared/smart-search/smart-search.partial.html index 073cb6f8d1..57a3bfb52c 100644 --- a/awx/ui/client/src/shared/smart-search/smart-search.partial.html +++ b/awx/ui/client/src/shared/smart-search/smart-search.partial.html @@ -33,25 +33,29 @@
-
-
-
-
- {{ key }} -
-
-
Type: {{ value.type }}
-
Description: {{value.help_text}}
-
- Enumerated: {{ choice[0] }} +
+
+
+ EXAMPLES:
+ + +
-
- Searchable relationships: {{ relation }}, +
+ FIELDS: {{ key }}, +
+
+ RELATED FIELDS: {{ relation }}, +
+
+ ADDITIONAL INFORMATION: For additional information on advanced search search syntax please see the Ansible Tower documentation.
diff --git a/awx/ui/client/src/shared/smart-search/smart-search.service.js b/awx/ui/client/src/shared/smart-search/smart-search.service.js new file mode 100644 index 0000000000..fe683c08d7 --- /dev/null +++ b/awx/ui/client/src/shared/smart-search/smart-search.service.js @@ -0,0 +1,19 @@ +export default [function() { + return { + splitSearchIntoTerms(searchString) { + return searchString.match(/(?:[^\s("')]+|"[^"]*"|'[^']*')+/g); + }, + splitTermIntoParts(searchTerm) { + let breakOnColon = searchTerm.match(/(?:[^:"]+|"[^"]*")+/g); + + if(breakOnColon.length > 2) { + // concat all the strings after the first one together + let stringsToJoin = breakOnColon.slice(1,breakOnColon.length); + return [breakOnColon[0], stringsToJoin.join(':')]; + } + else { + return breakOnColon; + } + } + }; +}]; diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js index 65cd07d475..0d13e4ed7f 100644 --- a/awx/ui/client/src/shared/stateDefinitions.factory.js +++ b/awx/ui/client/src/shared/stateDefinitions.factory.js @@ -177,7 +177,7 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat break; case 'edit': url = params.urls && params.urls.edit ? params.urls.edit : (params.url ? params.url : `/:${form.name}_id`); - formNode = $stateExtender.buildDefinition({ + let formNodeState = { name: params.name || `${params.parent}.edit`, url: url, ncyBreadcrumb: { @@ -215,8 +215,15 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat return Rest.get(); } ] - } - }); + }, + }; + if (params.data && params.data.activityStreamTarget) { + formNodeState.data = {}; + formNodeState.data.activityStreamId = params.data.activityStreamTarget + '_id'; + + } + formNode = $stateExtender.buildDefinition(formNodeState); + if (params.resolve && params.resolve.edit) { formNode.resolve = _.merge(formNode.resolve, params.resolve.edit); } @@ -267,7 +274,7 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat }, views: { [`modal@${formStateDefinition.name}`]: { - template: `` + template: `` } }, resolve: { @@ -332,7 +339,7 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat }, views: { [`modal@${formStateDefinition.name}`]: { - template: `` + template: `` } }, resolve: { @@ -501,7 +508,7 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat }, views: { [`modal@${formStateDefinition.name}`]: { - template: `` + template: `` } }, resolve: { diff --git a/awx/ui/client/src/smart-status/smart-status.controller.js b/awx/ui/client/src/smart-status/smart-status.controller.js index 10762de15d..1283552a55 100644 --- a/awx/ui/client/src/smart-status/smart-status.controller.js +++ b/awx/ui/client/src/smart-status/smart-status.controller.js @@ -15,9 +15,21 @@ export default ['$scope', '$filter', var singleJobStatus = true; var firstJobStatus; var recentJobs = $scope.jobs; + var detailsBaseUrl; + if(!recentJobs){ return; } + + // unless we explicitly define a value for the template-type attribute when invoking the + // directive, assume the status icons are for a regular (non-workflow) job when building + // the details url path + if (typeof $scope.templateType !== 'undefined' && $scope.templateType === 'workflow_job_template') { + detailsBaseUrl = '/#/workflows/'; + } else { + detailsBaseUrl = '/#/jobs/'; + } + var sparkData = _.sortBy(recentJobs.map(function(job) { @@ -38,6 +50,7 @@ export default ['$scope', '$filter', data.sortDate = job.finished || "running" + data.jobId; data.finished = $filter('longDate')(job.finished) || job.status+""; data.status_tip = "JOB ID: " + data.jobId + "
STATUS: " + data.smartStatus + "
FINISHED: " + data.finished; + data.detailsUrl = detailsBaseUrl + data.jobId; // If we've already determined that there are both failed and successful jobs OR if the current job in the loop is // pending/waiting/running then we don't worry about checking for a single job status diff --git a/awx/ui/client/src/smart-status/smart-status.directive.js b/awx/ui/client/src/smart-status/smart-status.directive.js index 1ed0ecdcc5..a4486e125e 100644 --- a/awx/ui/client/src/smart-status/smart-status.directive.js +++ b/awx/ui/client/src/smart-status/smart-status.directive.js @@ -9,7 +9,8 @@ export default [ 'templateUrl', function(templateUrl) { return { scope: { - jobs: '=' + jobs: '=', + templateType: '=?', }, templateUrl: templateUrl('smart-status/smart-status'), restrict: 'E', diff --git a/awx/ui/client/src/smart-status/smart-status.partial.html b/awx/ui/client/src/smart-status/smart-status.partial.html index a0545ec814..ec1a81fac3 100644 --- a/awx/ui/client/src/smart-status/smart-status.partial.html +++ b/awx/ui/client/src/smart-status/smart-status.partial.html @@ -1,6 +1,6 @@
- - + diff --git a/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.partial.html b/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.partial.html index 2c627888e8..66b790bb74 100644 --- a/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.partial.html +++ b/awx/ui/client/src/standard-out/inventory-sync/standard-out-inventory-sync.partial.html @@ -133,7 +133,7 @@ - + diff --git a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.partial.html b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.partial.html index 0739c6d5ce..f5a4e2a78d 100644 --- a/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.partial.html +++ b/awx/ui/client/src/standard-out/scm-update/standard-out-scm-update.partial.html @@ -98,7 +98,7 @@ - + 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 bbb97b3684..07d72a615d 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 @@ -287,20 +287,18 @@ if (data.related && data.related.callback) { Alert('Callback URL', -`
-

Host callbacks are enabled for this template. The callback URL is:

-

- - ${$scope.callback_server_path} - ${data.related.callback} - -

-

The host configuration key is: - - ${$filter('sanitize')(data.host_config_key)} - -

-
`, +`Host callbacks are enabled for this template. The callback URL is: +

+ + ${$scope.callback_server_path} + ${data.related.callback} + +

+

The host configuration key is: + + ${$filter('sanitize')(data.host_config_key)} + +

`, 'alert-danger', saveCompleted, null, null, null, true); } diff --git a/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js b/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js index 83df997d81..16904cdaf1 100644 --- a/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js +++ b/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js @@ -423,23 +423,20 @@ export default if (data.related && data.related.callback) { Alert('Callback URL', -` -
-

Host callbacks are enabled for this template. The callback URL is:

-

- - ${$scope.callback_server_path} - ${data.related.callback} - -

-

The host configuration key is: - - ${$filter('sanitize')(data.host_config_key)} - -

-
+`Host callbacks are enabled for this template. The callback URL is: +

+ + ${$scope.callback_server_path} + ${data.related.callback} + +

+

The host configuration key is: + + ${$filter('sanitize')(data.host_config_key)} + +

`, - 'alert-info', saveCompleted, null, null, + 'alert-danger', saveCompleted, null, null, null, true); } var orgDefer = $q.defer(); diff --git a/awx/ui/client/src/templates/list/templates-list.controller.js b/awx/ui/client/src/templates/list/templates-list.controller.js index 5bcd659a38..d0b910e6b9 100644 --- a/awx/ui/client/src/templates/list/templates-list.controller.js +++ b/awx/ui/client/src/templates/list/templates-list.controller.js @@ -131,7 +131,7 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', handleSuccessfulDelete(); }, function (data) { Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', + ProcessErrors($scope, data, data.status, null, { hdr: 'Error!', msg: 'Call to delete workflow job template failed. DELETE returned status: ' + status }); }); } @@ -141,8 +141,8 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', handleSuccessfulDelete(); }, function (data) { Wait('stop'); - ProcessErrors($scope, data, status, null, { hdr: 'Error!', - msg: 'Call to delete job template failed. DELETE returned status: ' + status }); + ProcessErrors($scope, data, data.status, null, { hdr: 'Error!', + msg: 'Call to delete job template failed. DELETE returned status: ' + data.status }); }); } else { @@ -220,7 +220,7 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', .then(function(result) { if(result.data.can_copy) { - if(!result.data.warnings || _.isEmpty(result.data.warnings)) { + if(result.data.can_copy_without_user_input) { // Go ahead and copy the workflow - the user has full priveleges on all the resources TemplateCopyService.copyWorkflow(template.id) .then(function(result) { @@ -235,18 +235,40 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest', let bodyHtml = `
- You may not have access to all resources used by this workflow. Resources that you don\'t have access to will not be copied and may result in an incomplete workflow. + You do not have access to all resources used by this workflow. Resources that you don\'t have access to will not be copied and will result in an incomplete workflow.
`; - // Go and grab all of the warning strings - _.forOwn(result.data.warnings, function(warning) { - if(warning) { - _.forOwn(warning, function(warningString) { - bodyHtml += '
' + warningString + '
'; - }); - } - } ); + // List the unified job templates user can not access + if (result.data.templates_unable_to_copy.length > 0) { + bodyHtml += '
Unified Job Templates that can not be copied
    '; + _.forOwn(result.data.templates_unable_to_copy, function(ujt) { + if(ujt) { + bodyHtml += '
  • ' + ujt + '
  • '; + } + }); + bodyHtml += '
'; + } + // List the prompted inventories user can not access + if (result.data.inventories_unable_to_copy.length > 0) { + bodyHtml += '
Node prompted inventories that can not be copied
    '; + _.forOwn(result.data.inventories_unable_to_copy, function(inv) { + if(inv) { + bodyHtml += '
  • ' + inv + '
  • '; + } + }); + bodyHtml += '
'; + } + // List the prompted credentials user can not access + if (result.data.credentials_unable_to_copy.length > 0) { + bodyHtml += '
Node prompted credentials that can not be copied
    '; + _.forOwn(result.data.credentials_unable_to_copy, function(cred) { + if(cred) { + bodyHtml += '
  • ' + cred + '
  • '; + } + }); + bodyHtml += '
'; + } bodyHtml += '
'; diff --git a/awx/ui/client/src/templates/main.js b/awx/ui/client/src/templates/main.js index e925b2e9f6..d712faa3d8 100644 --- a/awx/ui/client/src/templates/main.js +++ b/awx/ui/client/src/templates/main.js @@ -103,7 +103,8 @@ angular.module('templates', [surveyMaker.name, templatesList.name, jobTemplatesA }, inventory_source_search: { value: { - page_size: '5' + page_size: '5', + not__source: '' }, squash: true, dynamic: true diff --git a/awx/ui/client/src/templates/survey-maker/surveys/delete.factory.js b/awx/ui/client/src/templates/survey-maker/surveys/delete.factory.js index 0dbe5b4c94..48565727f4 100644 --- a/awx/ui/client/src/templates/survey-maker/surveys/delete.factory.js +++ b/awx/ui/client/src/templates/survey-maker/surveys/delete.factory.js @@ -13,6 +13,7 @@ export default var scope = params.scope, id = params.id, + templateType = params.templateType, url; @@ -35,7 +36,8 @@ export default scope.$emit("SurveyDeleted"); } else { - url = GetBasePath('job_templates')+ id + '/survey_spec/'; + let basePath = templateType === 'workflow_job_template' ? GetBasePath('workflow_job_templates') : GetBasePath('job_templates'); + url = basePath + id + '/survey_spec/'; Rest.setUrl(url); Rest.destroy() diff --git a/awx/ui/client/src/templates/survey-maker/surveys/init.factory.js b/awx/ui/client/src/templates/survey-maker/surveys/init.factory.js index d72148875d..e1508e4c4a 100644 --- a/awx/ui/client/src/templates/survey-maker/surveys/init.factory.js +++ b/awx/ui/client/src/templates/survey-maker/surveys/init.factory.js @@ -52,7 +52,8 @@ export default // and closing the modal after success DeleteSurvey({ scope: scope, - id: id + id: id, + templateType: templateType }); }; diff --git a/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.directive.js b/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.directive.js index 01b935127a..5a2f0c80cc 100644 --- a/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.directive.js +++ b/awx/ui/client/src/templates/workflows/workflow-chart/workflow-chart.directive.js @@ -174,7 +174,20 @@ export default [ '$state','moment', nodeEnter.each(function(d) { let thisNode = d3.select(this); - if(d.isStartNode) { + if(d.isStartNode && scope.mode === 'details') { + // Overwrite the default root height and width and replace it with a small blue square + rootW = 25; + rootH = 25; + thisNode.append("rect") + .attr("width", rootW) + .attr("height", rootH) + .attr("y", 10) + .attr("rx", 5) + .attr("ry", 5) + .attr("fill", "#337ab7") + .attr("class", "WorkflowChart-rootNode"); + } + else if(d.isStartNode && scope.mode !== 'details') { thisNode.append("rect") .attr("width", rootW) .attr("height", rootH) @@ -190,7 +203,6 @@ export default [ '$state','moment', .attr("dy", ".35em") .attr("class", "WorkflowChart-startText") .text(function () { return "START"; }) - .attr("display", function() { return scope.mode === 'details' ? 'none' : null;}) .call(add_node); } else { @@ -200,15 +212,15 @@ export default [ '$state','moment', .attr("rx", 5) .attr("ry", 5) .attr('stroke', function(d) { - if(d.edgeType) { - if(d.edgeType === "failure") { - return "#d9534f"; - } - else if(d.edgeType === "success") { + if(d.job && d.job.status) { + if(d.job.status === "successful"){ return "#5cb85c"; } - else if(d.edgeType === "always"){ - return "#337ab7"; + else if (d.job.status === "failed" || d.job.status === "error" || d.job.status === "cancelled") { + return "#d9534f"; + } + else { + return "#D7D7D7"; } } else { @@ -593,15 +605,15 @@ export default [ '$state','moment', t.selectAll(".rect") .attr('stroke', function(d) { - if(d.edgeType) { - if(d.edgeType === "failure") { - return "#d9534f"; - } - else if(d.edgeType === "success") { + if(d.job && d.job.status) { + if(d.job.status === "successful"){ return "#5cb85c"; } - else if(d.edgeType === "always"){ - return "#337ab7"; + else if (d.job.status === "failed" || d.job.status === "error" || d.job.status === "cancelled") { + return "#d9534f"; + } + else { + return "#D7D7D7"; } } else { diff --git a/awx/ui/client/src/workflow-results/workflow-results.block.less b/awx/ui/client/src/workflow-results/workflow-results.block.less index edd5412d2d..0173ed8eb8 100644 --- a/awx/ui/client/src/workflow-results/workflow-results.block.less +++ b/awx/ui/client/src/workflow-results/workflow-results.block.less @@ -110,3 +110,27 @@ text-transform: uppercase; margin-left: 20px; } + +.WorkflowResults-extraVarsHelp { + margin-left: 10px; + color: @default-icon; +} + +.WorkflowResults .CodeMirror.cm-s-default, +.WorkflowResults .CodeMirror-line { + background-color: #f6f6f6; +} + +.WorkflowResults .CodeMirror-gutter.CodeMirror-lint-markers, +.WorkflowResults .CodeMirror-gutter.CodeMirror-linenumbers { + background-color: #ebebeb; + color: @b7grey; +} + +.WorkflowResults .CodeMirror-lines { + cursor: default; +} + +.WorkflowResults .CodeMirror-cursors { + display: none; +} diff --git a/awx/ui/client/src/workflow-results/workflow-results.partial.html b/awx/ui/client/src/workflow-results/workflow-results.partial.html index ff2cd94a0d..4ff65548c6 100644 --- a/awx/ui/client/src/workflow-results/workflow-results.partial.html +++ b/awx/ui/client/src/workflow-results/workflow-results.partial.html @@ -121,6 +121,10 @@