Repository: ansible/tower-cli
Pull request #368 (2017-09-26 20:34:13)

allow association and dissassocation of extra_credentials with job_templates
Borrowing the basic logic of associating labels to job templates, this PR adds the ability to associate and disassociate extra credentials beyond the initial machine credential for a job template.


Patch:
diff --git a/tower_cli/resources/job_template.py b/tower_cli/resources/job_template.py
index 35f6ea5..a2d502f 100644
--- a/tower_cli/resources/job_template.py
+++ b/tower_cli/resources/job_template.py
@@ -150,6 +150,46 @@ class Resource(models.SurveyResource):
         """
         return self._disassoc('labels', job_template, label)
 
+    @resources.command(use_fields_as_options=False)
+    @click.option('--job-template', type=types.Related('job_template'))
+    @click.option('--credential', type=types.Related('credential'))
+    def associate_credential(self, job_template, credential):
+        """Associate a credential with this job template.
+
+        =====API DOCS=====
+        Associate a credential with this job template.
+
+        :param job_template: The job template to associate to.
+        :type job_template: str
+        :param credential: The credential to be associated.
+        :type credential: str
+        :returns: Dictionary of only one key "changed", which indicates whether the association succeeded.
+        :rtype: dict
+
+        =====API DOCS=====
+        """
+        return self._assoc('extra_credentials', job_template, credential)
+
+    @resources.command(use_fields_as_options=False)
+    @click.option('--job-template', type=types.Related('job_template'))
+    @click.option('--credential', type=types.Related('credential'))
+    def disassociate_credential(self, job_template, credential):
+        """Disassociate a credential with this job template.
+
+        =====API DOCS=====
+        Disassociate a credential from this job template.
+
+        :param job_template: The job template to disassociate fom.
+        :type job_template: str
+        :param credential: The credential to be disassociated.
+        :type credential: str
+        :returns: Dictionary of only one key "changed", which indicates whether the disassociation succeeded.
+        :rtype: dict
+
+        =====API DOCS=====
+        """
+        return self._disassoc('extra_credentials', job_template, credential)
+
     @resources.command(use_fields_as_options=False)
     @click.option('--job-template', type=types.Related('job_template'))
     @click.option('--notification-template',


Test patch:
diff --git a/tests/test_resources_job_template.py b/tests/test_resources_job_template.py
index 575cbee..dc04fd8 100644
--- a/tests/test_resources_job_template.py
+++ b/tests/test_resources_job_template.py
@@ -157,6 +157,31 @@ class TemplateTests(unittest.TestCase):
             self.assertEqual(t.requests[1].body,
                              json.dumps({'disassociate': True, 'id': 84}))
 
+    def test_associate_credential(self):
+        """Establish that the associate method makes the HTTP requests
+        that we expect.
+        """
+        with client.test_mode as t:
+            t.register_json('/job_templates/42/extra_credentials/?id=84',
+                            {'count': 0, 'results': []})
+            t.register_json('/job_templates/42/extra_credentials/', {}, method='POST')
+            self.res.associate_credential(42, 84)
+            self.assertEqual(t.requests[1].body,
+                             json.dumps({'associate': True, 'id': 84}))
+
+    def test_disassociate_credential(self):
+        """Establish that the disassociate method makes the HTTP requests
+        that we expect.
+        """
+        with client.test_mode as t:
+            t.register_json('/job_templates/42/extra_credentials/?id=84',
+                            {'count': 1, 'results': [{'id': 84}],
+                             'next': None, 'previous': None})
+            t.register_json('/job_templates/42/extra_credentials/', {}, method='POST')
+            self.res.disassociate_credential(42, 84)
+            self.assertEqual(t.requests[1].body,
+                             json.dumps({'disassociate': True, 'id': 84}))
+
     def test_associate_notification_template(self):
         """Establish that a job template should be able to associate itself
         with an existing notification template.