Bug 2213777

Summary: Can't remove GPG and SSL Keys from existing Product using the API
Product: Red Hat Satellite Reporter: Peter Tselios <tselios.petros>
Component: RepositoriesAssignee: Evgeni Golov <egolov>
Status: CLOSED ERRATA QA Contact: Ian Ballou <iballou>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 6.13.0CC: egolov, iballou, pcreech, rlavi
Target Milestone: 6.14.0Keywords: Triaged
Target Release: Unused   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: rubygem-katello-4.9.0.1-1,rubygem-katello-4.9.0.1-1 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-11-08 14:19:36 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Peter Tselios 2023-06-09 11:03:04 UTC
Description of problem:

It's not possible to unset GPG keys and/or sync plans when I use the theforeman.foreman.product module (and it's the same with the satellite modules as well. 

I have the following product defined as a variable: 

product_list:
  - name: test_product
    label: prod_test_product
    description: "Test Product"
    gpg_key: MyCustomGPG
    sync_play: Daily

I have a task in a playbook defined as follows: 

- name: Manage Satellite products
  theforeman.foreman.product:
    username: "{{ rhs_satellite_admin }}"
    password: "{{ rhs_satellite_admin_password }}"
    server_url: "{{ rhs_satellite_server_url }}"
    organization: "{{ rhs_org }}"
    validate_certs: "{{ rhs_validate_certs }}"
    gpg_key: "{{ item.gpg_key | default(omit) }}"
    name: "{{ item.product_name }}"
    label: "{{ item.label | default (omit) }}"
    description: "{{ item.description | default(omit) }}"
    sync_plan: "{{ item.sync_plan | default(omit) }}"
    ssl_ca_cert: "{{ item.ssl_ca_cert | default(omit) }}"
    ssl_client_cert: "{{ item.ssl_client_cert | default(omit) }}"
    ssl_client_key: "{{ item.ssl_client_key | default(omit) }}"
    state: "{{ item.state | default('present_with_defaults') }}"
  loop: "{{ product_list }}"

Provided that the GPG Key and/or the sync plan we define in the variable exist, the task will be completed successfully. 

Now, if for any reason I want to modify the product and disassociate the defined GPG key, or the sync plan, I change the variable as follows:

product_list:
  - name: test_product
    label: prod_test_product
    description: "Test Product"
    gpg_key: ""
    sync_play: ""

Now when I run the playbook, the specific task fails with the following error: 

-----
  msg: 'Error while performing update on products: gpg_key_id can''t be None'
-----

How reproducible: Always


Steps to Reproduce:
1. Create a new playbook with a single task as above
2. Define the variable as above
3. Run the playbook against a Satellite/Katello server

Actual results: Error

Expected results: Product is updated and the sync plan/GPG key is disassociated. 

Additional info: I don't know if the the SSL options have the same issue, but it is quite possible. I haven't tested them.

Comment 1 Evgeni Golov 2023-06-09 11:11:59 UTC
Moving over to "Repositories" component, as that's the one responsible for the "Products" model and API.

The API doc for the products update call looks like this (abbreviated):

                    {
                        "doc_url": "/apidoc/v2/products/update",
                        "name": "update",
                        "apis": [
                            {
                                "api_url": "/katello/api/products/:id",
                                "http_method": "PUT",
                                "short_description": "Updates a product",
                                "deprecated": null
                            }
                        ],
                        "formats": null,
                        "full_description": "",
                        "errors": [],
                        "params": [
…
                            {
                                "name": "gpg_key_id",
                                "full_name": "gpg_key_id",
                                "description": "\n<p>Identifier of the GPG key</p>\n",
                                "required": false,
                                "allow_nil": false,
                                "allow_blank": false,
                                "validator": "Must be a number.",
                                "expected_type": "numeric",
                                "metadata": null,
                                "show": true,
                                "validations": [],
                                "deprecated": false
                            },
                            {
                                "name": "ssl_ca_cert_id",
                                "full_name": "ssl_ca_cert_id",
                                "description": "\n<p>Idenifier of the SSL CA Cert</p>\n",
                                "required": false,
                                "allow_nil": false,
                                "allow_blank": false,
                                "validator": "Must be a number.",
                                "expected_type": "numeric",
                                "metadata": null,
                                "show": true,
                                "validations": [],
                                "deprecated": false
                            },
                            {
                                "name": "ssl_client_cert_id",
                                "full_name": "ssl_client_cert_id",
                                "description": "\n<p>Identifier of the SSL Client Cert</p>\n",
                                "required": false,
                                "allow_nil": false,
                                "allow_blank": false,
                                "validator": "Must be a number.",
                                "expected_type": "numeric",
                                "metadata": null,
                                "show": true,
                                "validations": [],
                                "deprecated": false
                            },
                            {
                                "name": "ssl_client_key_id",
                                "full_name": "ssl_client_key_id",
                                "description": "\n<p>Identifier of the SSL Client Key</p>\n",
                                "required": false,
                                "allow_nil": false,
                                "allow_blank": false,
                                "validator": "Must be a number.",
                                "expected_type": "numeric",
                                "metadata": null,
                                "show": true,
                                "validations": [],
                                "deprecated": false
                            },
…

because of the `allow_nil: false`, compliant API clients (like the Ansible Collection) refuse to unset the parameter once set.

Comment 2 Evgeni Golov 2023-06-09 11:13:08 UTC
Created redmine issue https://projects.theforeman.org/issues/36497 from this bug

Comment 3 Bryan Kearney 2023-06-09 12:03:20 UTC
Upstream bug assigned to egolov

Comment 4 Bryan Kearney 2023-06-09 12:03:22 UTC
Upstream bug assigned to egolov

Comment 5 Bryan Kearney 2023-06-10 00:03:36 UTC
Moving this bug to POST for triage into Satellite since the upstream issue https://projects.theforeman.org/issues/36497 has been resolved.

Comment 9 Bryan Kearney 2023-07-19 20:03:46 UTC
Upstream bug assigned to egolov

Comment 10 Bryan Kearney 2023-07-19 20:03:47 UTC
Upstream bug assigned to egolov

Comment 15 errata-xmlrpc 2023-11-08 14:19:36 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (Important: Satellite 6.14 security and bug fix update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2023:6818