Repository: pulp/pulpcore

Issue:
pulp rpm content upload fails with "add_for_object_creator not registered" error
**Version**
```
  "versions": [
    {
      "component": "core",
      "version": "3.20.0",
      "package": "pulpcore"
    },
    {
      "component": "rpm",
      "version": "3.17.9",
      "package": "pulp-rpm"
    }
  ],
```

**Describe the bug**
When trying to upload new rpm content, upload fails with following error:
```
# pulp rpm content upload --file /etc/pulp/scrape/splunk/splunkforwarder-9.0.0.1-9e907cedecb1-linux-2.6-x86_64.rpm --relative-path splunkforwarder-9.0.0.1-9e907cedecb1-linux-2.6-x86_64.rpm
Uploading file /etc/pulp/scrape/splunk/splunkforwarder-9.0.0.1-9e907cedecb1-linux-2.6-x86_64.rpm
.............................................Upload complete. Creating artifact.
Error: {"detail":"Creation hook 'add_for_object_creator' was not registered for this view set."}
```

**To Reproduce**
Install pulpcore with pulp_rpm plugin and try to upload rpm content

**Expected behavior**
No error is emitted

**Additional context**
We did upgrade from pulp 3.17.3 to 3.20.0 . It seems that the mentioned `add_for_object_creator` was removed in https://github.com/pulp/pulpcore/commit/4d50a746a30ba95ffab2dd3fbbc8d72df2c50c48 but maybe some migration scripts must be adjusted to ensure smooth upgrade with removal of that `add_for_object_creator` hook?


Discussion:
Can you verify that it works once you called `pulp access-policy reset --viewset-name content/file/packages` (not entirely sure about the viewset name...)?
Long story short, it unfortunately didn't help. More details below. Btw I see the problematic `add_for_object_creator` still referenced here, can it point to the problem? https://github.com/pulp/pulpcore/blob/aefd552c6fc2ec0f281e01681b8e9da96b9f9556/pulpcore/app/migrations/0042_rbac_for_tasks.py#L32

**Details:**
I listed all policies (via `pulp access-policy list`) and spotted that the `tasks` policy mentioned the `add_for_object_creator` function:
```
  {
    "pulp_href": "/pulp/api/v3/access_policies/8be638d0-e6e3-4158-8bd9-29a009467a28/",
    "pulp_created": "2021-08-19T13:14:17.036741Z",
    "permissions_assignment": [
      {
        "function": "add_for_object_creator",
        "parameters": null,
        "permissions": [
          "core.view_task",
          "core.change_task",
          "core.delete_task"
        ]
      }
    ],
    "creation_hooks": [
      {
        "function": "add_for_object_creator",
        "parameters": null,
        "permissions": [
          "core.view_task",
          "core.change_task",
          "core.delete_task"
        ]
      }
    ],
    "statements": [
      {
        "action": [
          "list"
        ],
        "effect": "allow",
        "principal": "authenticated"
      },
      {
        "action": [
          "retrieve"
        ],
        "effect": "allow",
        "condition": "has_model_or_obj_perms:core.view_task",
        "principal": "authenticated"
      },
      {
        "action": [
          "destroy"
        ],
        "effect": "allow",
        "condition": "has_model_or_obj_perms:core.delete_task",
        "principal": "authenticated"
      },
      {
        "action": [
          "update",
          "partial_update"
        ],
        "effect": "allow",
        "condition": "has_model_or_obj_perms:core.change_task",
        "principal": "authenticated"
      }
    ],
    "viewset_name": "tasks",
    "customized": true,
    "queryset_scoping": null
  }

```


After `pulp access-policy reset --viewset-name tasks` :
```
{
  "pulp_href": "/pulp/api/v3/access_policies/8be638d0-e6e3-4158-8bd9-29a009467a28/",
  "pulp_created": "2021-08-19T13:14:17.036741Z",
  "permissions_assignment": [
    {
      "function": "add_roles_for_object_creator",
      "parameters": {
        "roles": "core.task_owner"
      }
    }
  ],
  "creation_hooks": [
    {
      "function": "add_roles_for_object_creator",
      "parameters": {
        "roles": "core.task_owner"
      }
    }
  ],
  "statements": [
    {
      "action": [
        "list"
      ],
      "principal": "authenticated",
      "effect": "allow"
    },
    {
      "action": [
        "retrieve",
        "my_permissions"
      ],
      "principal": "authenticated",
      "effect": "allow",
      "condition": "has_model_or_obj_perms:core.view_task"
    },
    {
      "action": [
        "destroy"
      ],
      "principal": "authenticated",
      "effect": "allow",
      "condition": "has_model_or_obj_perms:core.delete_task"
    },
    {
      "action": [
        "update",
        "partial_update"
      ],
      "principal": "authenticated",
      "effect": "allow",
      "condition": "has_model_or_obj_perms:core.change_task"
    },
    {
      "action": [
        "purge"
      ],
      "principal": "authenticated",
      "effect": "allow"
    },
    {
      "action": [
        "list_roles",
        "add_role",
        "remove_role"
      ],
      "principal": "authenticated",
      "effect": "allow",
      "condition": "has_model_or_obj_perms:core.manage_roles_task"
    }
  ],
  "viewset_name": "tasks",
  "customized": false,
  "queryset_scoping": {
    "function": "scope_queryset"
  }
}
```

However it seems it still didn't help:
```
# pulp rpm content upload --file /etc/pulp/scrape/splunk/splunkforwarder-9.0.0.1-9e907cedecb1-linux-2.6-x86_64.rpm --relative-path splunkforwarder-9.0.0.1-9e907cedecb1-linux-2.6-x86_64.rpm
Uploading file /etc/pulp/scrape/splunk/splunkforwarder-9.0.0.1-9e907cedecb1-linux-2.6-x86_64.rpm
.............................................Upload complete. Creating artifact.
Error: {"detail":"Creation hook 'add_for_object_creator' was not registered for this view set."}
(pulp3)
```

Btw I spotted following log entries in system logs, not sure if it is related but it also mentions `add_for_object_creator` issues.

```
Aug 16 12:33:19 pulp3-dev01 gunicorn[503584]: pulp [f3165800d91440a5abe3fd6e411565c3]: 127.0.0.1 - admin [16/Aug/2022:10:33:19 +0000] "PUT /pulp/api/v3/uploads/20083ccd-b93f-41b3-89d9-b971326aaf9a/ HTTP/1.1" 200 135 "-" "Pulp-CLI/0.14.0"
Aug 16 12:33:19 pulp3-dev01 gunicorn[503584]: pulp [7d236724f2e74ed389c0405d74c184a7]: django.request:ERROR: Internal Server Error: /pulp/api/v3/uploads/20083ccd-b93f-41b3-89d9-b971326aaf9a/commit/
Aug 16 12:33:19 pulp3-dev01 gunicorn[503584]: pulp [7d236724f2e74ed389c0405d74c184a7]: 127.0.0.1 - admin [16/Aug/2022:10:33:19 +0000] "POST /pulp/api/v3/uploads/20083ccd-b93f-41b3-89d9-b971326aaf9a/commit/ HTTP/1.1" 500 89 "-" "Pulp-CLI/0.14.0"
Aug 16 12:33:21 pulp3-dev01 pulpcore-worker[503628]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
Aug 16 12:33:21 pulp3-dev01 pulpcore-worker[503645]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
Aug 16 12:33:22 pulp3-dev01 gunicorn[503584]: pulp [53dbc6f538454d23b6c84737a56dd3a3]: 127.0.0.1 - admin [16/Aug/2022:10:33:22 +0000] "DELETE /pulp/api/v3/uploads/20083ccd-b93f-41b3-89d9-b971326aaf9a/ HTTP/1.1" 204 0 "-" "Pulp-CLI/0.14.0"
Aug 16 12:33:31 pulp3-dev01 pulpcore-worker[503628]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
Aug 16 12:33:31 pulp3-dev01 pulpcore-worker[503645]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
Aug 16 12:33:41 pulp3-dev01 pulpcore-worker[503628]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
Aug 16 12:33:41 pulp3-dev01 pulpcore-worker[503645]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
Aug 16 12:33:51 pulp3-dev01 pulpcore-worker[503628]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
Aug 16 12:33:51 pulp3-dev01 pulpcore-worker[503645]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
Aug 16 12:34:01 pulp3-dev01 pulpcore-worker[503628]: pulp [None]: pulpcore.tasking.tasks:WARNING: Dispatching scheduled task pulpcore.app.tasks.telemetry.post_telemetry failed. Creation hook 'add_for_object_creator' was not registered for this view set.
```
Can you restart the services after changing / resetting the access policy?
Thanks for the hint and after the restart (`systemctl restart pulpcore-api.service pulpcore-worker@*.service pulpcore-content.service`), everything seems to work like a charm. Thank you!
Thank you so much for finding this!
On last question (and i think, i know the answer): Did you run `pulpcore-manager migrate` after upgrading?
It seems that the post migrate hook may have missed to update that access-policy.
Yep, I tried to run `pulpcore-manager migrate` multiple times but it didn't help, so I opened this bug report :)
I recorded the solution here:
https://discourse.pulpproject.org/t/operations-fail-with-creation-hook-add-for-object-creator-was-not-registered-for-this-view-set/565

Resolving patch:
diff --git a/pulpcore/app/apps.py b/pulpcore/app/apps.py
--- a/pulpcore/app/apps.py
+++ b/pulpcore/app/apps.py
@@ -245,15 +245,19 @@ def _populate_access_policies(sender, apps, verbosity, **kwargs):
                             )
                         )
                 if not created and not db_access_policy.customized:
+                    dirty = False
                     for key, value in access_policy.items():
-                        setattr(db_access_policy, key, value)
-                    db_access_policy.save()
-                    if verbosity >= 1:
-                        print(
-                            "Access policy for {viewset_name} updated.".format(
-                                viewset_name=viewset_name
+                        if getattr(db_access_policy, key, None) != value:
+                            setattr(db_access_policy, key, value)
+                            dirty = True
+                    if dirty:
+                        db_access_policy.save()
+                        if verbosity >= 1:
+                            print(
+                                "Access policy for {viewset_name} updated.".format(
+                                    viewset_name=viewset_name
+                                )
                             )
-                        )
 
 
 def _populate_system_id(sender, apps, verbosity, **kwargs):
diff --git a/pulpcore/app/migrations/0050_namespace_access_policies.py b/pulpcore/app/migrations/0050_namespace_access_policies.py
--- a/pulpcore/app/migrations/0050_namespace_access_policies.py
+++ b/pulpcore/app/migrations/0050_namespace_access_policies.py
@@ -12,7 +12,7 @@ def namespace_access_policies_up(apps, schema_editor):
 
 def namespace_access_policies_down(apps, schema_editor):
     AccessPolicy = apps.get_model('core', 'AccessPolicy')
-    task_policy = AccessPolicy.objects.get(viewset_name="tasks").delete()
+    task_policy = AccessPolicy.objects.get(viewset_name="tasks")
     task_policy.viewset_name = "TaskViewSet"
     task_policy.save()
 
diff --git a/pulpcore/app/viewsets/access_policy.py b/pulpcore/app/viewsets/access_policy.py
--- a/pulpcore/app/viewsets/access_policy.py
+++ b/pulpcore/app/viewsets/access_policy.py
@@ -51,7 +51,10 @@ def reset(self, request, pk=None):
         for plugin_config in pulp_plugin_configs():
             for viewset_batch in plugin_config.named_viewsets.values():
                 for viewset in viewset_batch:
-                    if get_view_urlpattern(viewset) == access_policy.viewset_name:
+                    if (
+                        hasattr(viewset, "DEFAULT_ACCESS_POLICY")
+                        and get_view_urlpattern(viewset) == access_policy.viewset_name
+                    ):
                         default_access_policy = viewset.DEFAULT_ACCESS_POLICY
                         access_policy.statements = default_access_policy["statements"]
                         access_policy.creation_hooks = default_access_policy.get(


Test patch: