move credential to prompt-for mechanism

This commit is contained in:
AlanCoding
2016-04-11 15:39:06 -04:00
parent 0dff851f62
commit b0bbeb2ca8
12 changed files with 108 additions and 51 deletions

View File

@@ -1675,7 +1675,7 @@ class JobTemplateSerializer(UnifiedJobTemplateSerializer, JobOptionsSerializer):
model = JobTemplate
fields = ('*', 'host_config_key', 'ask_variables_on_launch', 'ask_limit_on_launch',
'ask_tags_on_launch', 'ask_job_type_on_launch', 'ask_inventory_on_launch',
'survey_enabled', 'become_enabled')
'ask_credential_on_launch', 'survey_enabled', 'become_enabled')
def get_related(self, obj):
res = super(JobTemplateSerializer, self).get_related(obj)
@@ -2104,6 +2104,7 @@ class JobLaunchSerializer(BaseSerializer):
can_start_without_user_input = serializers.BooleanField(read_only=True)
variables_needed_to_start = serializers.ReadOnlyField()
credential_needed_to_start = serializers.SerializerMethodField()
inventory_needed_to_start = serializers.SerializerMethodField()
survey_enabled = serializers.SerializerMethodField()
extra_vars = VerbatimField(required=False, write_only=True)
@@ -2111,13 +2112,13 @@ class JobLaunchSerializer(BaseSerializer):
model = JobTemplate
fields = ('can_start_without_user_input', 'passwords_needed_to_start',
'extra_vars', 'limit', 'job_tags', 'skip_tags', 'job_type', 'inventory',
'ask_variables_on_launch', 'ask_tags_on_launch', 'ask_job_type_on_launch',
'ask_inventory_on_launch', 'ask_limit_on_launch',
'credential', 'ask_variables_on_launch', 'ask_tags_on_launch',
'ask_job_type_on_launch', 'ask_inventory_on_launch', 'ask_limit_on_launch',
'survey_enabled', 'variables_needed_to_start',
'credential', 'credential_needed_to_start',)
'credential_needed_to_start', 'inventory_needed_to_start',)
read_only_fields = ('ask_variables_on_launch', 'ask_limit_on_launch',
'ask_tags_on_launch', 'ask_job_type_on_launch',
'ask_inventory_on_launch')
'ask_inventory_on_launch', 'ask_credential_on_launch')
extra_kwargs = {
'credential': {'write_only': True,},
'limit': {'write_only': True,},
@@ -2130,6 +2131,9 @@ class JobLaunchSerializer(BaseSerializer):
def get_credential_needed_to_start(self, obj):
return not (obj and obj.credential)
def get_inventory_needed_to_start(self, obj):
return not (obj and obj.inventory)
def get_survey_enabled(self, obj):
if obj:
return obj.survey_enabled and 'spec' in obj.survey_spec
@@ -2140,10 +2144,8 @@ class JobLaunchSerializer(BaseSerializer):
obj = self.context.get('obj')
data = self.context.get('data')
if obj and obj.credential is not None:
# force job template to override runtime credential, if present
if (not obj.ask_credential_on_launch) or (not attrs.get('credential', None)):
credential = obj.credential
attrs.pop('credential', None)
else:
credential = attrs.get('credential', None)
if not credential:
@@ -2191,6 +2193,7 @@ class JobLaunchSerializer(BaseSerializer):
JT_job_tags = obj.job_tags
JT_skip_tags = obj.skip_tags
JT_inventory = obj.inventory
JT_credential = obj.credential
attrs = super(JobLaunchSerializer, self).validate(attrs)
obj.extra_vars = JT_extra_vars
obj.limit = JT_limit
@@ -2198,6 +2201,7 @@ class JobLaunchSerializer(BaseSerializer):
obj.skip_tags = JT_skip_tags
obj.job_tags = JT_job_tags
obj.inventory = JT_inventory
obj.credential = JT_credential
return attrs
class NotifierSerializer(BaseSerializer):

View File

@@ -6,6 +6,16 @@ The response will include the following fields:
* `ask_variables_on_launch`: Flag indicating whether the job_template is
configured to prompt for variables upon launch (boolean, read-only)
* `ask_tags_on_launch`: Flag indicating whether the job_template is
configured to prompt for tags upon launch (boolean, read-only)
* `ask_job_type_on_launch`: Flag indicating whether the job_template is
configured to prompt for job_type upon launch (boolean, read-only)
* `ask_limit_on_launch`: Flag indicating whether the job_template is
configured to prompt for limit upon launch (boolean, read-only)
* `ask_inventory_on_launch`: Flag indicating whether the job_template is
configured to prompt for limit upon launch (boolean, read-only)
* `ask_credential_on_launch`: Flag indicating whether the job_template is
configured to prompt for limit upon launch (boolean, read-only)
* `can_start_without_user_input`: Flag indicating if the job_template can be
launched without user-input (boolean, read-only)
* `passwords_needed_to_start`: Password names required to launch the
@@ -17,13 +27,19 @@ The response will include the following fields:
* `credential_needed_to_start`: Flag indicating the presence of a credential
associated with the job template. If not then one should be supplied when
launching the job (boolean, read-only)
* `inventory_needed_to_start`: Flag indicating the presence of an inventory
associated with the job template. If not then one should be supplied when
launching the job (boolean, read-only)
Make a POST request to this resource to launch the job_template. If any
passwords or extra variables (extra_vars) are required, they must be passed
via POST data, with extra_vars given as a YAML or JSON string and escaped
parentheses. If `credential_needed_to_start` is `True` then the `credential`
field is required as well.
passwords, inventory, or extra variables (extra_vars) are required, they must
be passed via POST data, with extra_vars given as a YAML or JSON string and
escaped parentheses. If `credential_needed_to_start` is `True` then the
`credential` field is required and if the `inventory_needed_to_start` is
`True` then the `inventory` is required as well.
If successful, the response status code will be 202. If any required passwords
If successful, the response status code will be 201. If any required passwords
are not provided, a 400 status code will be returned. If the job cannot be
launched, a 405 status code will be returned.
launched, a 405 status code will be returned. If the provided credential or
inventory are not allowed to be used by the user, then a 403 status code will
be returned.

View File

@@ -2086,10 +2086,6 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView):
if obj:
for p in obj.passwords_needed_to_start:
data[p] = u''
if obj.credential:
data.pop('credential', None)
else:
data['credential'] = None
for v in obj.variables_needed_to_start:
extra_vars.setdefault(v, u'')
ask_for_vars_dict = obj._ask_for_vars_dict()
@@ -2098,12 +2094,8 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView):
data.pop(field, None)
elif field == 'extra_vars':
data[field] = extra_vars
elif field == 'inventory':
inv_obj = getattr(obj, field)
if inv_obj in ('', None):
data[field] = None
else:
data[field] = inv_obj.id
elif field == 'inventory' or field == 'credential':
data[field] = getattrd(obj, "%s.%s" % (field, 'id'), None)
else:
data[field] = getattr(obj, field)
return data
@@ -2123,22 +2115,19 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView):
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# At this point, a credential is gauranteed to exist at serializer.instance.credential
if not request.user.can_access(Credential, 'read', serializer.instance.credential):
raise PermissionDenied()
kv = {
'credential': serializer.instance.credential.pk,
}
prompted_fields, ignored_fields = obj._accept_or_ignore_job_kwargs(**request.data)
if 'inventory' in prompted_fields:
if 'credential' in prompted_fields and prompted_fields['credential'] != getattrd(obj, 'credential.pk', None):
new_credential = Credential.objects.get(pk=prompted_fields['credential'])
if not request.user.can_access(Credential, 'read', new_credential):
raise PermissionDenied()
if 'inventory' in prompted_fields and prompted_fields['inventory'] != getattrd(obj, 'inventory.pk', None):
new_inventory = Inventory.objects.get(pk=prompted_fields['inventory'])
if not request.user.can_access(Inventory, 'read', new_inventory):
raise PermissionDenied()
kv.update(prompted_fields)
kv = prompted_fields
kv.update(passwords)
new_job = obj.create_unified_job(**kv)
@@ -2435,7 +2424,7 @@ class JobTemplateCallback(GenericAPIView):
# Return the location of the new job.
headers = {'Location': job.get_absolute_url()}
return Response(status=status.HTTP_202_ACCEPTED, headers=headers)
return Response(status=status.HTTP_201_CREATED, headers=headers)
class JobTemplateJobsList(SubListCreateAPIView):
@@ -2483,7 +2472,7 @@ class SystemJobTemplateLaunch(GenericAPIView):
new_job = obj.create_unified_job(**request.data)
new_job.signal_start(**request.data)
data = dict(system_job=new_job.id)
return Response(data, status=status.HTTP_202_ACCEPTED)
return Response(data, status=status.HTTP_201_CREATED)
class SystemJobTemplateSchedulesList(SubListCreateAttachDetachAPIView):