Skip to content

[WIP] Fix widget sets with orphaned group #23404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jrafanie
Copy link
Member

TODO: I have no idea why we have ownership AND group association for a widget set and why the owner can be nil and the group pointing to an orphaned group id. This is fixing the symptoms but not really solving the problem yet. We need to understand why these things were happening and how to properly fix it going forward.

Copy link
Member

@kbrock kbrock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff

@@ -342,6 +342,10 @@ def current_user_group?
id == current_user_group.try(:id)
end

def destroy_subscribed_widget_sets
MiqWidgetSet.where(:group_id => id).destroy_all
Copy link
Member

@kbrock kbrock Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if we delete this group, a user widget set will probably want to stick around.
So if user_id is around, want to figure out the user's new group and set the widget set's group to the user's new set?

--
I do want a test around user_id and group_id set

MiqWidgetSet.where(:group_id => id, :user_id => nil).destroy_all

Comment on lines +410 to +411
next unless groups_by_id.key?(k) # Make sure the group associated with a widget set / dashboard hasn't been removed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't the next line (blank) take care of some of this.

@kbrock
Copy link
Member

kbrock commented Apr 1, 2025

psudo code - have not tested yet (will revsit when we ask questions)

Widget Set

current table

user group action
nil nil keep - default
nil valid keep - group dashboard
nil invalid delete - these don't exist
valid nil delete - these don't exist
valid invalid delete - main issue
valid valid/no membership delete
valid valid keep
invalid any delete
--- users that have dashboard (that is not in the list of the user's groups)
SELECT miq_sets.id, miq_sets.name, miq_sets.read_only,
       miq_sets.owner_type, miq_sets.owner_id, miq_sets.userid, miq_sets.group_id
FROM miq_sets
WHERE
  miq_sets.set_type = 'MiqWidgetSet'
  AND miq_sets.userid IS NOT NULL
  AND (
    -- invalid user
    (
      NOT EXISTS (SELECT 1 FROM users WHERE users.userid = userid)
    -- invalid group
    ) OR (
      NOT EXISTS (
        SELECT 1 FROM users
        join miq_groups_users on users.id = miq_groups_users.user_id
        WHERE users.userid = miq_sets.userid and miq_groups_users.miq_group_id = miq_sets.group_id
      )
    )
  )
ORDER BY userid, group_id;

--- sanity check: groups the users are in
SELECT users.id, users.userid, miq_groups_users.miq_group_id, miq_groups.description
FROM users
JOIN miq_groups_users on users.id = miq_groups_users.user_id
JOIN miq_groups ON miq_groups.id = miq_groups_users.miq_group_id
WHERE users.userid in (select userid from miq_sets where set_type = 'MiqWidgetSet')
ORDER by users.userid;

Actions

remove group from a user

DELETE miq_sets
  WHERE miq_sets.set_type = 'MiqWidgetSet'
  AND miq_sets.userid = $userid
  AND miq_sets.group_id = $old_group_id

delete user

DELETE miq_sets
  WHERE miq_sets.set_type = 'MiqWidgetSet'
  AND miq_sets.userid = $old_userid

delete group

DELETE  miq_sets
  WHERE miq_sets.set_type = 'MiqWidgetSet'
  AND   group_id = $old_group_id
-- intentionally not using owner_id (want group and user dashboards)

@kbrock
Copy link
Member

kbrock commented Apr 8, 2025

ok, updated queries to point to miq_sets for the widget sets

@jrafanie
Copy link
Member Author

jrafanie commented Apr 10, 2025

A revised version the above pseudo code was tested to verify the dashboards for invalid users, users no longer in the group (group exists but user isn't in it anymore or group does NOT exist).

DELETE FROM miq_sets
WHERE
  miq_sets.set_type = 'MiqWidgetSet'
  AND miq_sets.userid IS NOT NULL
  AND (
    -- invalid user
    (
      NOT EXISTS (SELECT 1 FROM users WHERE users.userid = userid)
    -- invalid group
    ) OR (
      NOT EXISTS (
        SELECT 1 FROM users
        join miq_groups_users on users.id = miq_groups_users.user_id
        WHERE users.userid = miq_sets.userid and miq_groups_users.miq_group_id = miq_sets.group_id
      )
    )
  );

For followup, here and elsewhere, we'll need to:

  1. Drop dashboards for users that are removed from a group
  2. Drop dashboards for users who are deleted
  3. Drop dashboards for users linked to a group that doesn't exist (similar to 1)
  4. Handle situations where a group is deleted. For user owned dashboards, their group_id should be populated and any references to the deleted group should be removed. For group owned dashboards, the owner should be the checked to see if that group was an owner. That should be handled via the has_many :miq_widget_sets, :as => :owner, :dependent => :destroy on miq_group.rb.
  5. Should a data migration be created to fix these?

@Fryguy
Copy link
Member

Fryguy commented Apr 10, 2025

  1. Drop dashboards for users that are removed from a group
  2. Drop dashboards for users who are deleted
  3. Drop dashboards for users linked to a group that doesn't exist (similar to 1)

These probably will need to be done async to deleting the user/group, maybe as a callback it's put on the queue or maybe we create a purger.

  1. is the most important one, I think...if a user is removed from a group then we need to nullify the association out because the user still exists.
  1. Should a data migration be created to fix these?

Probably for any existing ones, but maybe a purger is more appropriate to keep it clean in an ongoing manner?


I think there needs to be a 3.5 for dealing with deleting groups.

@jrafanie
Copy link
Member Author

jrafanie commented Apr 11, 2025

I think there needs to be a 3.5 for dealing with deleting groups.

Good point. That's the original code for this PR so I neglected to put it.

EDIT: Edited the comment above to remember it when I return.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants