Adding table_preferences with POST is not working correctly

Problem:
When sending POST request to /api/users/:user_id/table_preferences the total number of preferences doesn’t not change thus breaking future PUT or DELETE requests.

How to reproduce:

  1. Create new table_preference for the user with 0 preferences using POST request /api/users/:user_id/table_preferences with the following body:
{
    "name": "hosts",
    "columns": [
        "power_status",
        "name"
    ]
}

(was done by user from UI on All Hosts tab in Foreman.)
2. Fetch info with GET /api/users/:user_id/table_preferences.

Expected outcome:
Response of GET request contains “total”: 1 and “subtotal”: 1

{
    "total": 1,
    "subtotal": 1,
    "page": 1,
    "per_page": 50,
    "search": null,
    "sort": {
        "by": null,
        "order": null
    },
    "results": [
        {
            "id": 8,
            "name": "hosts",
            "columns": [
                "power_status",
                "name"
            ],
            "created_at": "2023-07-13 08:27:59 UTC",
            "updated_at": "2023-08-24 11:23:34 UTC"
        }
    ]
}

Actual outcome:
Response of GET request contains “total”: 0 and “subtotal”: 0

{
    "total": 0,
    "subtotal": 0,
    "page": 1,
    "per_page": 50,
    "search": null,
    "sort": {
        "by": null,
        "order": null
    },
    "results": [
        {
            "id": 8,
            "name": "hosts",
            "columns": [
                "power_status",
                "name"
            ],
            "created_at": "2023-07-13 08:27:59 UTC",
            "updated_at": "2023-08-24 11:23:34 UTC"
        }
    ]
}

Foreman version:
v. 3.6.1

Other relevant data:
Future PUT and DELETE requests to /api/users/:user_id/table_preferences/hosts are not working with the following error:

"error": {"message": "Resource table_preference not found by id 'hosts' "}

That maybe entirely different issue or a cause of this problem. I’ve searched community and foreman issue tracker and didn’t find anything like this so I raised this question for it. Could you please advise on how to edit existing user records because some of them have all of the preferences selected on Hosts tab (making it unusable) and we can’t change it back.

Hi,
both issues you’re describing seem to be resolved in latest development branch. Sadly I don’t have any stable release deployment at hand to check there.

Before we get our hands dirty with some workaround, can’t they just use the ui to unset all the things they don’t want to see?

There is also hammer command for that:

$ hammer user table-preference -h

Can you please let us know if it’s useful for you?

Unsetting in UI sends PUT api requests that results in an error so sadly no.

Thanks for the idea, I’ll test it and will return with the results tomorrow.

Sadly the result is the same:

Listing the table_preference for a user returns exisiting prefernce:

[root@foreman cli.modules.d]# hammer user table-preference list --user-id 274
---|-------|---------------------------------------------------------------------------------
ID | NAME  | COLUMNS
---|-------|---------------------------------------------------------------------------------
14 | hosts | power_status, name, os_title, owner, hostgroup, boot_time, last_report, comme...
---|-------|---------------------------------------------------------------------------------

But deleting (or editing) this preference is impossible:

[root@foreman cli.modules.d]# hammer user table-preference delete --user-id 274 --name hosts
Could not remove table preference:
  Resource table_preference not found by id 'hosts'

[root@foreman cli.modules.d]# hammer user table-preference delete --user-id 274 --name 14
Could not remove table preference:
  Resource table_preference not found by id '14'

But during new preference creation error states that this record was found:

[root@foreman cli.modules.d]# hammer user table-preference create --user-id 274 --name hosts --columns "power_status, name, os_title, owner, hostgroup, boot_time, last_report"
Could not create table preference:
  PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_table_preferences_on_user_id_and_name"
  DETAIL:  Key (user_id, name)=(274, hosts) already exists.

@aruzicka what was the workaround you had in mind? I think deleting the user would work since his new record would have new id, am I correct?

Before we get our hands dirty with some workaround, can’t they just use the ui to unset all the things they don’t want to see?

Yeah, hammer probably hits the same api. On a related note, what ends up in /var/log/foreman/production.log when you try to modify or delete the preferences?

Probably, yes, but that’s not what I had in mind.

You could run something like this for each of the affected users to reset things to default, replacing “myuser” with the user’s login:

echo 'User.find_by(login: "myuser").table_preferences.where(name: "hosts").destroy_all' | foreman-rake console

First of all, your proposed command worked and I was able to restore default views. Thank you!

Regarding unsuccessful update, here is piece of log after sending update request from UI (log level set to debug):

2023-08-25T17:03:15 [I|app|8772c1ff] Started PUT "/api/users/533/table_preferences/hosts" for 10.203.219.131 at 2023-08-25 17:03:15 +0200
2023-08-25T17:03:15 [I|app|8772c1ff] Processing by Api::V2::TablePreferencesController#update as JSON
2023-08-25T17:03:15 [I|app|8772c1ff]   Parameters: {"columns"=>["power_status", "name", "os_title", "owner", "boot_time", "last_report", "comment", "environment"], "apiv"=>"v2", "user_id"=>"533", "id"=>"hosts", "table_preference"=>{"columns"=>["power_status", "name", "os_title", "owner", "boot_time", "last_report", "comment", "environment"]}}
2023-08-25T17:03:15 [D|tax|8772c1ff] Current location set to none
2023-08-25T17:03:15 [D|tax|8772c1ff] Current organization set to Default Organization
2023-08-25T17:03:15 [I|app|8772c1ff] ActiveRecord::RecordNotFound (ActiveRecord::RecordNotFound)
2023-08-25T17:03:15 [D|app|8772c1ff]   Rendering layout api/v2/layouts/error_layout.json.erb
2023-08-25T17:03:15 [D|app|8772c1ff]   Rendering api/v2/errors/not_found.json.rabl within api/v2/layouts/error_layout
2023-08-25T17:03:15 [I|app|8772c1ff]   Rendered api/v2/errors/not_found.json.rabl within api/v2/layouts/error_layout (Duration: 4.5ms | Allocations: 5749)
2023-08-25T17:03:15 [I|app|8772c1ff]   Rendered layout api/v2/layouts/error_layout.json.erb (Duration: 8.7ms | Allocations: 11412)
2023-08-25T17:03:15 [I|app|8772c1ff] Completed 404 Not Found in 52ms (Views: 9.8ms | ActiveRecord: 11.3ms | Allocations: 28862)