Repository: ansible/awx

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_


Discussion:

Resolving patch:
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 freeze(key):
 
 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


Test patch:
diff --git a/awx_collection/test/awx/test_export.py b/awx_collection/test/awx/test_export.py
--- a/awx_collection/test/awx/test_export.py
+++ b/awx_collection/test/awx/test_export.py
@@ -134,21 +134,17 @@ def test_export_simple(
 
 
 @pytest.mark.django_db
-def test_export_system_auditor(run_module, schedule, system_auditor):  # noqa: F811
+def test_export_system_auditor(run_module, organization, system_auditor):  # noqa: F811
     """
-    This test illustrates that deficiency of export when ran as non-root user (i.e. system auditor).
-    The OPTIONS endpoint does NOT return POST for a system auditor. This is bad for the export code
-    because it relies on crawling the OPTIONS POST response to determine the fields to export.
+    This test illustrates that export of resources can now happen
+    when ran as non-root user (i.e. system auditor). The OPTIONS
+    endpoint does NOT return POST for a system auditor, but now we
+    make a best-effort to parse the description string, which will
+    often have the fields.
     """
     result = run_module('export', dict(all=True), system_auditor)
-    assert result.get('failed', False), result.get('msg', result)
-
-    assert 'Failed to export assets substring not found' in result['msg'], (
-        'If you found this error then you have probably fixed a feature! The export code attempts to assertain the POST fields from the `description` field,'
-        ' but both the API side and the client inference code are lacking.'
-    )
-
-    # r = result['assets']['schedules'][0]
-    # assert r['natural_key']['name'] == 'test-sched'
+    assert not result.get('failed', False), result.get('msg', result)
+    assert 'msg' not in result
+    assert 'assets' in result
 
-    # assert 'rrule' not in r, 'If you found this error then you have probably fixed a feature! We WANT rrule to be found in the export schedule payload.'
+    find_by(result['assets'], 'organizations', 'name', 'Default')