prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Issue on awx.awx.export/import awx cli/collection
  ### 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.
  - [X] I am **NOT** reporting a (potential) security vulnerability. (These should be emailed to `security@ansible.com` instead.)
  
  ### Bug Summary
  
  Hi team,
  I founded tow bugs related awx cli and collection import / export.
  
  The first issue is related export module, that not work if user is a system_auditor (or not have certain admin role in object like schedule.
  I already found why this bug is present and proposed a PR: #14626 .
  
  Second "bug" is related import module  (I don't know  and don't find if someone decide it) and is related how import will be processed.
  Actually import perform a `POST`, if object not exists, or a `PUT`, if object exists. In case of we `PUT` an object that already exist api will replace it in all fields, including encrypted key, that in export are removed (correctly).
  
  So, i don't know if it's better approach with `PATCH` instead a `PUT`, but I think that here the issue is in the export itself, that will  replace value of encrypted key `$encrypted$` with `''` .
  The side effect of "restore" `$encrypted$ ` on the export is that we remove it for the POST, due to the fact that is a reseved keyword.
   
   I will propose a PR also to fix the second bugs
  
  ### AWX version
  
  23.3.1
  
  ### Select the relevant components
  
  - [ ] UI
  - [ ] UI (tech preview)
  - [X] API
  - [ ] Docs
  - [X] Collection
  - [X] CLI
  - [ ] Other
  
  ### Installation method
  
  kubernetes
  
  ### Modifications
  
  no
  
  ### Ansible version
  
  _No response_
  
  ### Operating system
  
  _No response_
  
  ### Web browser
  
  _No response_
  
  ### Steps to reproduce
  
  bug 1: execute an export of schedule with a system_auditor
  
  bug 2: import a credential already present in AWX
  
  ### Expected results
  
  bug 1: export will go fine
  
  bug 2: credential will be updated with only fields present in export
  
  ### Actual results
  
  bug 1: export will fail
  
  bug 2: credential will be replaced with exported data. But due to the fact that encrypted key are not exported and replaced the value `$encrypted$` with `''` we replace current secrets with `''`
  
  ### Additional information
  
  _No response_
  
  </issue>
  <code>
  [start of awxkit/awxkit/api/utils.py]
  1 import logging
  2 import re
  3 
  4 
  5 log = logging.getLogger(__name__)
  6 
  7 descRE = re.compile(r'^[*] `(\w+)`: [^(]*\((\w+), ([^)]+)\)')
  8 
  9 
  10 def freeze(key):
  11     if key is None:
  12         return None
  13     return frozenset((k, freeze(v) if isinstance(v, dict) else v) for k, v in key.items())
  14 
  15 
  16 def parse_description(desc):
  17     options = {}
  18     for line in desc[desc.index('POST') :].splitlines():
  19         match = descRE.match(line)
  20         if not match:
  21             continue
  22         options[match.group(1)] = {'type': match.group(2), 'required': match.group(3) == 'required'}
  23     return options
  24 
  25 
  26 def remove_encrypted(value):
  27     if value == '$encrypted$':
  28         return ''
  29     if isinstance(value, list):
  30         return [remove_encrypted(item) for item in value]
  31     if isinstance(value, dict):
  32         return {k: remove_encrypted(v) for k, v in value.items()}
  33     return value
  34 
  35 
  36 def get_post_fields(page, cache):
  37     options_page = cache.get_options(page)
  38     if options_page is None:
  39         return None
  40 
  41     if 'POST' not in options_page.r.headers.get('Allow', ''):
  42         return None
  43 
  44     if 'POST' in options_page.json['actions']:
  45         return options_page.json['actions']['POST']
  46     else:
  47         log.warning("Insufficient privileges on %s, inferring POST fields from description.", options_page.endpoint)
  48         return parse_description(options_page.json['description'])
  49
  [end of awxkit/awxkit/api/utils.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/awxkit/awxkit/api/utils.py b/awxkit/awxkit/api/utils.py
  --- a/awxkit/awxkit/api/utils.py
  +++ b/awxkit/awxkit/api/utils.py
  @@ -15,7 +15,12 @@
   
   def parse_description(desc):
       options = {}
  -    for line in desc[desc.index('POST') :].splitlines():
  +    desc_lines = []
  +    if 'POST' in desc:
  +        desc_lines = desc[desc.index('POST') :].splitlines()
  +    else:
  +        desc_lines = desc.splitlines()
  +    for line in desc_lines:
           match = descRE.match(line)
           if not match:
               continue
  
verification_info: {"golden_diff": "diff --git a/awxkit/awxkit/api/utils.py b/awxkit/awxkit/api/utils.py\n--- a/awxkit/awxkit/api/utils.py\n+++ b/awxkit/awxkit/api/utils.py\n@@ -15,7 +15,12 @@\n \n def parse_description(desc):\n     options = {}\n-    for line in desc[desc.index('POST') :].splitlines():\n+    desc_lines = []\n+    if 'POST' in desc:\n+        desc_lines = desc[desc.index('POST') :].splitlines()\n+    else:\n+        desc_lines = desc.splitlines()\n+    for line in desc_lines:\n         match = descRE.match(line)\n         if not match:\n             continue\n", "issue": "Issue on awx.awx.export/import awx cli/collection\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- [X] I am **NOT** reporting a (potential) security vulnerability. (These should be emailed to `security@ansible.com` instead.)\r\n\r\n### Bug Summary\r\n\r\nHi team,\r\nI founded tow bugs related awx cli and collection import / export.\r\n\r\nThe first issue is related export module, that not work if user is a system_auditor (or not have certain admin role in object like schedule.\r\nI already found why this bug is present and proposed a PR: #14626 .\r\n\r\nSecond \"bug\" is related import module  (I don't know  and don't find if someone decide it) and is related how import will be processed.\r\nActually import perform a `POST`, if object not exists, or a `PUT`, if object exists. In case of we `PUT` an object that already exist api will replace it in all fields, including encrypted key, that in export are removed (correctly).\r\n\r\nSo, i don't know if it's better approach with `PATCH` instead a `PUT`, but I think that here the issue is in the export itself, that will  replace value of encrypted key `$encrypted$` with `''` .\r\nThe side effect of \"restore\" `$encrypted$ ` on the export is that we remove it for the POST, due to the fact that is a reseved keyword.\r\n \r\n I will propose a PR also to fix the second bugs\r\n\r\n### AWX version\r\n\r\n23.3.1\r\n\r\n### Select the relevant components\r\n\r\n- [ ] UI\r\n- [ ] UI (tech preview)\r\n- [X] API\r\n- [ ] Docs\r\n- [X] Collection\r\n- [X] CLI\r\n- [ ] Other\r\n\r\n### Installation method\r\n\r\nkubernetes\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\nbug 1: execute an export of schedule with a system_auditor\r\n\r\nbug 2: import a credential already present in AWX\r\n\r\n### Expected results\r\n\r\nbug 1: export will go fine\r\n\r\nbug 2: credential will be updated with only fields present in export\r\n\r\n### Actual results\r\n\r\nbug 1: export will fail\r\n\r\nbug 2: credential will be replaced with exported data. But due to the fact that encrypted key are not exported and replaced the value `$encrypted$` with `''` we replace current secrets with `''`\r\n\r\n### Additional information\r\n\r\n_No response_\n", "before_files": [{"content": "import logging\nimport re\n\n\nlog = logging.getLogger(__name__)\n\ndescRE = re.compile(r'^[*] `(\\w+)`: [^(]*\\((\\w+), ([^)]+)\\)')\n\n\ndef freeze(key):\n    if key is None:\n        return None\n    return frozenset((k, freeze(v) if isinstance(v, dict) else v) for k, v in key.items())\n\n\ndef parse_description(desc):\n    options = {}\n    for line in desc[desc.index('POST') :].splitlines():\n        match = descRE.match(line)\n        if not match:\n            continue\n        options[match.group(1)] = {'type': match.group(2), 'required': match.group(3) == 'required'}\n    return options\n\n\ndef remove_encrypted(value):\n    if value == '$encrypted$':\n        return ''\n    if isinstance(value, list):\n        return [remove_encrypted(item) for item in value]\n    if isinstance(value, dict):\n        return {k: remove_encrypted(v) for k, v in value.items()}\n    return value\n\n\ndef get_post_fields(page, cache):\n    options_page = cache.get_options(page)\n    if options_page is None:\n        return None\n\n    if 'POST' not in options_page.r.headers.get('Allow', ''):\n        return None\n\n    if 'POST' in options_page.json['actions']:\n        return options_page.json['actions']['POST']\n    else:\n        log.warning(\"Insufficient privileges on %s, inferring POST fields from description.\", options_page.endpoint)\n        return parse_description(options_page.json['description'])\n", "path": "awxkit/awxkit/api/utils.py"}]}