cPanel UAPI Personalization.get through the WHM API
Hi,
I'm developing a plugin for both WHM and cPanel. The WHM admin can edit plugin global and individual cPanel user settings in WHM, cPanel users can edit only their plugin settings. After reviewing the cPanel & WHM documentation, it seems NVData should be used for saving plugin data.
On the WHM side, I'd like to query cPanel UAPI Personalization::get through the WHM API. However, piping JSON into whmapi1 with uapi_cpanel as the command, results in an error:
I've tried passing the names parameter various ways, but always results in the error below. I understand the error, just wondering if there is a way around this. "Can't use string XXX as an ARRAY ref while \"strict refs\" in use at /usr/local/cpanel/Cpanel/API/Personalization.pm line 111.\n" One example of many attempts:
Questions: 1) Is there a way to query UAPI Personalization::get through the WHM API? 2) If #1 is possible, is there a way to use the WHM API batch command with #1? This would be used to query #1 for all cPanel users in one batch command to the WHM API. 3) Since UAPI Personalization::get requires JSON input, is there a way to perform this function with the UAPI batch command?
echo '{"names":["test","test2">}' | whmapi1 --input=json uapi_cpanel cpanel.function=get cpanel.module=Personalization cpanel.user=xyz
---
metadata:
command: uapi_cpanel
reason: "API failure: uapi_cpanel does not support nested data structures\n"
result: 0
version: 1
I've tried passing the names parameter various ways, but always results in the error below. I understand the error, just wondering if there is a way around this. "Can't use string XXX as an ARRAY ref while \"strict refs\" in use at /usr/local/cpanel/Cpanel/API/Personalization.pm line 111.\n" One example of many attempts:
whmapi1 uapi_cpanel cpanel.function=get cpanel.module=Personalization cpanel.user=xyz names=["test","test2">
---
data:
uapi:
data: ~
errors:
- "Can't use string (\"[test,test2]\") as an ARRAY ref while \"strict refs\" in use at /usr/local/cpanel/Cpanel/API/Personalization.pm line 111.\n"
messages: ~
metadata: {}
status: 0
warnings: ~
metadata:
command: uapi_cpanel
reason: OK
result: 1
version: 1
Questions: 1) Is there a way to query UAPI Personalization::get through the WHM API? 2) If #1 is possible, is there a way to use the WHM API batch command with #1? This would be used to query #1 for all cPanel users in one batch command to the WHM API. 3) Since UAPI Personalization::get requires JSON input, is there a way to perform this function with the UAPI batch command?
-
I did some investigation on this in the code, as your results looked about like what I'd expect to see when multiple args for a key are *not* in fact supported for a given API call. My suspicions turned out to be right on the mark, unfortunately. I'm not going to skimp on details here with explanation, so I'll let you know right now to simply skip to the end of my post if you don't care about the details and just want to solve your problem. Investigation notes: Based on the way I'm reading the code, UAPI Personalization::get was never designed to be able to accept multiple names, as it uses the "single" arg processor instead of allowing multiple args. Changing it to allow this would be rather trivial, but goes against the desire for inputting JSON as documented (and is thus an imperfect solution): whmapi1 uapi_cpanel cpanel.function=get cpanel.module=Personalization cpanel.user=cptest names=zippy names=dippy --- data: uapi: data: personalization: dippy: reason: OK success: 1 value: ~ zippy: reason: OK success: 1 value: ~ errors: ~ messages: ~ metadata: {} status: 1 warnings: ~ metadata: command: uapi_cpanel reason: OK result: 1 version: 1
If there's an actual bug anywhere, it would be within WHMAPI itself, as the uapi_cpanel function itself does not appear to be aware that some UAPI methods in fact require nested datastructures (and thus does not whitelist the function to allow this). Unfortunately, "whether or not to trigger this error" is determined by an internal variable called `requires_json`, which in this case would then make *all* uapi functions executed via WHMAPI *require* JSON input when true. That would sadly be an even worse "cure". That said, the "easy" solution here would be to add a workaround to the API call in question which just calls the "multiple" getter for args if what we get from the single arg processor is not an ARRAYREF, but that would also mean updating documentation regarding a new calling context for that API. I've captured this concern as a bug for now -- CPANEL-43079 Answers to questions (in order of asking): 1) No, as the `names` parameter cannot be called in a manner which does not produce error. This is in fact a bug. 2 as such is also going to be a no. 3) I don't see why you couldn't batch it via UAPI batch alone, but if it's being executed via WHMAPI, you'll face the same problem of uapi_cpanel not accepting nested datastructures. Unfortunately, there's no "native" WHMAPI call which also manipulates NVData. If you whipped up a custom UAPI module, perhaps you could just directly invoke `Cpanel::NVData::NVData_get` in a loop after using `get_required_multiple` to grab the `names` arg then pass em in like `names=foo names=bar ...` so that it actually works with WHMAPI similar to one of the solutions I proposed.0 -
cPanelThomas, Thanks for investigating and the thorough response. The details helped me better understand the Perl source code for these functions. I had looked hoping to find a work around, but I am not very fluent in Perl. Re-evaluating #3, I somehow missed UAPI batch has an user parameter so it is not possible to batch request Personalization::get for all users in one go anyways. Regarding changes, bug fixes, etc, no need. I was only inquiring if they are ways around the situations I encountered. As the code will be querying all users either through CLI or LiveAPI PHP, I do not feel there will be any performance issues. I wanted to minimize queries for best efficiency. After the plugin is developed, I'll evaluate creating our own custom UAPI modules. BTW and for future viewers, I was not sure if the cmd you posted was an example of how this could work or actual real output. During my testing I had tried the same syntax, each name as separate names=X, and always resulted in an error for me. This is the output I get after changing to a valid user on our dev server: whmapi1 uapi_cpanel cpanel.function=get cpanel.module=Personalization cpanel.user=strikespeed names=zippy names=dippy --- data: uapi: data: ~ errors: - "Can't use string (\"zippy\") as an ARRAY ref while \"strict refs\" in use at /usr/local/cpanel/Cpanel/API/Personalization.pm line 111.\n" messages: ~ metadata: {} status: 0 warnings: ~ metadata: command: uapi_cpanel reason: OK result: 1 version: 1
0 -
That output was how it would have looked after I had patched things locally to use the "multiple" arg processor within the API in question. Mostly as a "This can in fact be fixed in code" thing, not necessarily as a "you can do this right now" statement. 0
Please sign in to leave a comment.
Comments
3 comments