prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Unable to use CCP lookup plugin with empty webservice_id
  ### Please confirm the following
  
  - [X] I agree to follow this project's [code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).
  - [X] I have checked the [current issues](https://github.com/ansible/awx/issues) for duplicates.
  - [X] I understand that AWX is open source software provided for free and that I might not receive a timely response.
  
  ### Bug Summary
  
  When job uses the  `CyberArk Central Credential Provider Lookup` credential plugin with an empty web service id, it fails with the exception: 
  
  ```
  Traceback (most recent call last):
    File "/awx_devel/awx/main/tasks/jobs.py", line 508, in run
      args = self.build_args(self.instance, private_data_dir, passwords)
    File "/awx_devel/awx/main/tasks/jobs.py", line 941, in build_args
      ssh_username = creds.get_input('username', default='')
    File "/awx_devel/awx/main/models/credential/__init__.py", line 275, in get_input
      return self._get_dynamic_input(field_name)
    File "/awx_devel/awx/main/models/credential/__init__.py", line 309, in _get_dynamic_input
      return input_source.get_input_value()
    File "/awx_devel/awx/main/models/credential/__init__.py", line 1250, in get_input_value
      return backend(**backend_kwargs)
    File "/awx_devel/awx/main/credential_plugins/aim.py", line 73, in aim_backend
      webservice_id = kwargs['webservice_id']
  KeyError: 'webservice_id'
  ```
  
  The issue is only reproducible if we create a CCP lookup credential using API and we do not provide the `webservice_id` key as the input.  If you create CCP lookup with UI - everything works fine. 
  
  ### AWX version
  
  devel
  
  ### Select the relevant components
  
  - [ ] UI
  - [X] API
  - [ ] Docs
  - [ ] Collection
  - [ ] CLI
  - [ ] Other
  
  ### Installation method
  
  docker development environment
  
  ### Modifications
  
  no
  
  ### Ansible version
  
  _No response_
  
  ### Operating system
  
  _No response_
  
  ### Web browser
  
  _No response_
  
  ### Steps to reproduce
  
  1. Create CyberArk Central Credential Provider Lookup credential. Do not provide the WebService ID value, keep it empty. I used API to create credetnail and the webservice_id was missing in the inputs: 
  
  ```
  inputs = {
              'url': url,
              'app_id': app_id,
              'client_key': client_key,
              'client_cert': client_cert,
              'verify': verify
  }
  
  payload = factories.credential.payload(
      name=fauxfactory.gen_utf8(),
      description=fauxfactory.gen_utf8(),
      credential_type=cred_type,
      inputs=inputs
  )
  ```
  
  2. Create Machine credential that uses the CCP lookup credential. Set proper Object query. 
  3. Create Job Template that uses this credential. Run the job. 
  
  
  
  ### Expected results
  
  The lookup should use default webservice id: `AIMWebService`
  
  ### Actual results
  
  Exception occured. See description. 
  
  
  
  ### Additional information
  
  _No response_
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `awx/main/credential_plugins/aim.py`
  Content:
  ```
  1 from .plugin import CredentialPlugin, CertFiles, raise_for_status
  2 
  3 from urllib.parse import quote, urlencode, urljoin
  4 
  5 from django.utils.translation import gettext_lazy as _
  6 import requests
  7 
  8 aim_inputs = {
  9     'fields': [
  10         {
  11             'id': 'url',
  12             'label': _('CyberArk CCP URL'),
  13             'type': 'string',
  14             'format': 'url',
  15         },
  16         {
  17             'id': 'webservice_id',
  18             'label': _('Web Service ID'),
  19             'type': 'string',
  20             'help_text': _('The CCP Web Service ID. Leave blank to default to AIMWebService.'),
  21         },
  22         {
  23             'id': 'app_id',
  24             'label': _('Application ID'),
  25             'type': 'string',
  26             'secret': True,
  27         },
  28         {
  29             'id': 'client_key',
  30             'label': _('Client Key'),
  31             'type': 'string',
  32             'secret': True,
  33             'multiline': True,
  34         },
  35         {
  36             'id': 'client_cert',
  37             'label': _('Client Certificate'),
  38             'type': 'string',
  39             'secret': True,
  40             'multiline': True,
  41         },
  42         {
  43             'id': 'verify',
  44             'label': _('Verify SSL Certificates'),
  45             'type': 'boolean',
  46             'default': True,
  47         },
  48     ],
  49     'metadata': [
  50         {
  51             'id': 'object_query',
  52             'label': _('Object Query'),
  53             'type': 'string',
  54             'help_text': _('Lookup query for the object. Ex: Safe=TestSafe;Object=testAccountName123'),
  55         },
  56         {'id': 'object_query_format', 'label': _('Object Query Format'), 'type': 'string', 'default': 'Exact', 'choices': ['Exact', 'Regexp']},
  57         {
  58             'id': 'reason',
  59             'label': _('Reason'),
  60             'type': 'string',
  61             'help_text': _('Object request reason. This is only needed if it is required by the object\'s policy.'),
  62         },
  63     ],
  64     'required': ['url', 'app_id', 'object_query'],
  65 }
  66 
  67 
  68 def aim_backend(**kwargs):
  69     url = kwargs['url']
  70     client_cert = kwargs.get('client_cert', None)
  71     client_key = kwargs.get('client_key', None)
  72     verify = kwargs['verify']
  73     webservice_id = kwargs['webservice_id']
  74     app_id = kwargs['app_id']
  75     object_query = kwargs['object_query']
  76     object_query_format = kwargs['object_query_format']
  77     reason = kwargs.get('reason', None)
  78     if webservice_id == '':
  79         webservice_id = 'AIMWebService'
  80 
  81     query_params = {
  82         'AppId': app_id,
  83         'Query': object_query,
  84         'QueryFormat': object_query_format,
  85     }
  86     if reason:
  87         query_params['reason'] = reason
  88 
  89     request_qs = '?' + urlencode(query_params, quote_via=quote)
  90     request_url = urljoin(url, '/'.join([webservice_id, 'api', 'Accounts']))
  91 
  92     with CertFiles(client_cert, client_key) as cert:
  93         res = requests.get(
  94             request_url + request_qs,
  95             timeout=30,
  96             cert=cert,
  97             verify=verify,
  98             allow_redirects=False,
  99         )
  100     raise_for_status(res)
  101     return res.json()['Content']
  102 
  103 
  104 aim_plugin = CredentialPlugin('CyberArk Central Credential Provider Lookup', inputs=aim_inputs, backend=aim_backend)
  105
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/awx/main/credential_plugins/aim.py b/awx/main/credential_plugins/aim.py
  --- a/awx/main/credential_plugins/aim.py
  +++ b/awx/main/credential_plugins/aim.py
  @@ -70,7 +70,7 @@
       client_cert = kwargs.get('client_cert', None)
       client_key = kwargs.get('client_key', None)
       verify = kwargs['verify']
  -    webservice_id = kwargs['webservice_id']
  +    webservice_id = kwargs.get('webservice_id', '')
       app_id = kwargs['app_id']
       object_query = kwargs['object_query']
       object_query_format = kwargs['object_query_format']
  
verification_info: {"golden_diff": "diff --git a/awx/main/credential_plugins/aim.py b/awx/main/credential_plugins/aim.py\n--- a/awx/main/credential_plugins/aim.py\n+++ b/awx/main/credential_plugins/aim.py\n@@ -70,7 +70,7 @@\n     client_cert = kwargs.get('client_cert', None)\n     client_key = kwargs.get('client_key', None)\n     verify = kwargs['verify']\n-    webservice_id = kwargs['webservice_id']\n+    webservice_id = kwargs.get('webservice_id', '')\n     app_id = kwargs['app_id']\n     object_query = kwargs['object_query']\n     object_query_format = kwargs['object_query_format']\n", "issue": "Unable to use CCP lookup plugin with empty webservice_id\n### Please confirm the following\r\n\r\n- [X] I agree to follow this project's [code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).\r\n- [X] I have checked the [current issues](https://github.com/ansible/awx/issues) for duplicates.\r\n- [X] I understand that AWX is open source software provided for free and that I might not receive a timely response.\r\n\r\n### Bug Summary\r\n\r\nWhen job uses the  `CyberArk Central Credential Provider Lookup` credential plugin with an empty web service id, it fails with the exception: \r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/awx_devel/awx/main/tasks/jobs.py\", line 508, in run\r\n    args = self.build_args(self.instance, private_data_dir, passwords)\r\n  File \"/awx_devel/awx/main/tasks/jobs.py\", line 941, in build_args\r\n    ssh_username = creds.get_input('username', default='')\r\n  File \"/awx_devel/awx/main/models/credential/__init__.py\", line 275, in get_input\r\n    return self._get_dynamic_input(field_name)\r\n  File \"/awx_devel/awx/main/models/credential/__init__.py\", line 309, in _get_dynamic_input\r\n    return input_source.get_input_value()\r\n  File \"/awx_devel/awx/main/models/credential/__init__.py\", line 1250, in get_input_value\r\n    return backend(**backend_kwargs)\r\n  File \"/awx_devel/awx/main/credential_plugins/aim.py\", line 73, in aim_backend\r\n    webservice_id = kwargs['webservice_id']\r\nKeyError: 'webservice_id'\r\n```\r\n\r\nThe issue is only reproducible if we create a CCP lookup credential using API and we do not provide the `webservice_id` key as the input.  If you create CCP lookup with UI - everything works fine. \r\n\r\n### AWX version\r\n\r\ndevel\r\n\r\n### Select the relevant components\r\n\r\n- [ ] UI\r\n- [X] API\r\n- [ ] Docs\r\n- [ ] Collection\r\n- [ ] CLI\r\n- [ ] Other\r\n\r\n### Installation method\r\n\r\ndocker development environment\r\n\r\n### Modifications\r\n\r\nno\r\n\r\n### Ansible version\r\n\r\n_No response_\r\n\r\n### Operating system\r\n\r\n_No response_\r\n\r\n### Web browser\r\n\r\n_No response_\r\n\r\n### Steps to reproduce\r\n\r\n1. Create CyberArk Central Credential Provider Lookup credential. Do not provide the WebService ID value, keep it empty. I used API to create credetnail and the webservice_id was missing in the inputs: \r\n\r\n```\r\ninputs = {\r\n            'url': url,\r\n            'app_id': app_id,\r\n            'client_key': client_key,\r\n            'client_cert': client_cert,\r\n            'verify': verify\r\n}\r\n\r\npayload = factories.credential.payload(\r\n    name=fauxfactory.gen_utf8(),\r\n    description=fauxfactory.gen_utf8(),\r\n    credential_type=cred_type,\r\n    inputs=inputs\r\n)\r\n```\r\n\r\n2. Create Machine credential that uses the CCP lookup credential. Set proper Object query. \r\n3. Create Job Template that uses this credential. Run the job. \r\n\r\n\r\n\r\n### Expected results\r\n\r\nThe lookup should use default webservice id: `AIMWebService`\r\n\r\n### Actual results\r\n\r\nException occured. See description. \r\n\r\n\r\n\r\n### Additional information\r\n\r\n_No response_\n", "before_files": [{"content": "from .plugin import CredentialPlugin, CertFiles, raise_for_status\n\nfrom urllib.parse import quote, urlencode, urljoin\n\nfrom django.utils.translation import gettext_lazy as _\nimport requests\n\naim_inputs = {\n    'fields': [\n        {\n            'id': 'url',\n            'label': _('CyberArk CCP URL'),\n            'type': 'string',\n            'format': 'url',\n        },\n        {\n            'id': 'webservice_id',\n            'label': _('Web Service ID'),\n            'type': 'string',\n            'help_text': _('The CCP Web Service ID. Leave blank to default to AIMWebService.'),\n        },\n        {\n            'id': 'app_id',\n            'label': _('Application ID'),\n            'type': 'string',\n            'secret': True,\n        },\n        {\n            'id': 'client_key',\n            'label': _('Client Key'),\n            'type': 'string',\n            'secret': True,\n            'multiline': True,\n        },\n        {\n            'id': 'client_cert',\n            'label': _('Client Certificate'),\n            'type': 'string',\n            'secret': True,\n            'multiline': True,\n        },\n        {\n            'id': 'verify',\n            'label': _('Verify SSL Certificates'),\n            'type': 'boolean',\n            'default': True,\n        },\n    ],\n    'metadata': [\n        {\n            'id': 'object_query',\n            'label': _('Object Query'),\n            'type': 'string',\n            'help_text': _('Lookup query for the object. Ex: Safe=TestSafe;Object=testAccountName123'),\n        },\n        {'id': 'object_query_format', 'label': _('Object Query Format'), 'type': 'string', 'default': 'Exact', 'choices': ['Exact', 'Regexp']},\n        {\n            'id': 'reason',\n            'label': _('Reason'),\n            'type': 'string',\n            'help_text': _('Object request reason. This is only needed if it is required by the object\\'s policy.'),\n        },\n    ],\n    'required': ['url', 'app_id', 'object_query'],\n}\n\n\ndef aim_backend(**kwargs):\n    url = kwargs['url']\n    client_cert = kwargs.get('client_cert', None)\n    client_key = kwargs.get('client_key', None)\n    verify = kwargs['verify']\n    webservice_id = kwargs['webservice_id']\n    app_id = kwargs['app_id']\n    object_query = kwargs['object_query']\n    object_query_format = kwargs['object_query_format']\n    reason = kwargs.get('reason', None)\n    if webservice_id == '':\n        webservice_id = 'AIMWebService'\n\n    query_params = {\n        'AppId': app_id,\n        'Query': object_query,\n        'QueryFormat': object_query_format,\n    }\n    if reason:\n        query_params['reason'] = reason\n\n    request_qs = '?' + urlencode(query_params, quote_via=quote)\n    request_url = urljoin(url, '/'.join([webservice_id, 'api', 'Accounts']))\n\n    with CertFiles(client_cert, client_key) as cert:\n        res = requests.get(\n            request_url + request_qs,\n            timeout=30,\n            cert=cert,\n            verify=verify,\n            allow_redirects=False,\n        )\n    raise_for_status(res)\n    return res.json()['Content']\n\n\naim_plugin = CredentialPlugin('CyberArk Central Credential Provider Lookup', inputs=aim_inputs, backend=aim_backend)\n", "path": "awx/main/credential_plugins/aim.py"}], "after_files": [{"content": "from .plugin import CredentialPlugin, CertFiles, raise_for_status\n\nfrom urllib.parse import quote, urlencode, urljoin\n\nfrom django.utils.translation import gettext_lazy as _\nimport requests\n\naim_inputs = {\n    'fields': [\n        {\n            'id': 'url',\n            'label': _('CyberArk CCP URL'),\n            'type': 'string',\n            'format': 'url',\n        },\n        {\n            'id': 'webservice_id',\n            'label': _('Web Service ID'),\n            'type': 'string',\n            'help_text': _('The CCP Web Service ID. Leave blank to default to AIMWebService.'),\n        },\n        {\n            'id': 'app_id',\n            'label': _('Application ID'),\n            'type': 'string',\n            'secret': True,\n        },\n        {\n            'id': 'client_key',\n            'label': _('Client Key'),\n            'type': 'string',\n            'secret': True,\n            'multiline': True,\n        },\n        {\n            'id': 'client_cert',\n            'label': _('Client Certificate'),\n            'type': 'string',\n            'secret': True,\n            'multiline': True,\n        },\n        {\n            'id': 'verify',\n            'label': _('Verify SSL Certificates'),\n            'type': 'boolean',\n            'default': True,\n        },\n    ],\n    'metadata': [\n        {\n            'id': 'object_query',\n            'label': _('Object Query'),\n            'type': 'string',\n            'help_text': _('Lookup query for the object. Ex: Safe=TestSafe;Object=testAccountName123'),\n        },\n        {'id': 'object_query_format', 'label': _('Object Query Format'), 'type': 'string', 'default': 'Exact', 'choices': ['Exact', 'Regexp']},\n        {\n            'id': 'reason',\n            'label': _('Reason'),\n            'type': 'string',\n            'help_text': _('Object request reason. This is only needed if it is required by the object\\'s policy.'),\n        },\n    ],\n    'required': ['url', 'app_id', 'object_query'],\n}\n\n\ndef aim_backend(**kwargs):\n    url = kwargs['url']\n    client_cert = kwargs.get('client_cert', None)\n    client_key = kwargs.get('client_key', None)\n    verify = kwargs['verify']\n    webservice_id = kwargs.get('webservice_id', '')\n    app_id = kwargs['app_id']\n    object_query = kwargs['object_query']\n    object_query_format = kwargs['object_query_format']\n    reason = kwargs.get('reason', None)\n    if webservice_id == '':\n        webservice_id = 'AIMWebService'\n\n    query_params = {\n        'AppId': app_id,\n        'Query': object_query,\n        'QueryFormat': object_query_format,\n    }\n    if reason:\n        query_params['reason'] = reason\n\n    request_qs = '?' + urlencode(query_params, quote_via=quote)\n    request_url = urljoin(url, '/'.join([webservice_id, 'api', 'Accounts']))\n\n    with CertFiles(client_cert, client_key) as cert:\n        res = requests.get(\n            request_url + request_qs,\n            timeout=30,\n            cert=cert,\n            verify=verify,\n            allow_redirects=False,\n        )\n    raise_for_status(res)\n    return res.json()['Content']\n\n\naim_plugin = CredentialPlugin('CyberArk Central Credential Provider Lookup', inputs=aim_inputs, backend=aim_backend)\n", "path": "awx/main/credential_plugins/aim.py"}]}