System Status is a very lightweight module that gives a overview of current used modules(core,contrib,custom) and their current version in a machine readable format (JSON). This would allow administrators to build their own monitoring interface to check on multiple installations at once.
This module will NOT check for updates, and is not the same as the Update Manager.
In time this module will not only serve 'pull' request but will also have the possibility to inform by itself using webcalls or syslog or ...
Project URL: http://drupal.org/sandbox/MrSam/1947996
Git URL: git clone --branch 7.x-1.x http://git.drupal.org/sandbox/MrSam/1947996.git system_status
Version: 7.x-1.x
Installation
Download and install the module normally as you install other contributed module.
Usage
After installation check the admin page under /admin/config/system/system_status
and allow public calls. (The default entered IP address should work fine)
Once you checked the settings you should be able to: GET $base_url/admin/reports/system_status
(ex. http://www.my-site.com/admin/reports/system_status )
Example output
{"system_status":{"core":{"block":{"version":"7.15"},"color":{"version":"7.15"},"comment":{"version":"7.15"},"contextual":{"version":"7.15"},"dashboard":{"version":"7.15"},"dblog":{"version":"7.15"},"field":{"version":"7.15"},"field_sql_storage":{"version":"7.15"},"field_ui":{"version":"7.15"},"file":{"version":"7.15"},"filter":{"version":"7.15"},"help":{"version":"7.15"},"image":{"version":"7.15"},"list":{"version":"7.15"},"menu":{"version":"7.15"},"node":{"version":"7.15"},"number":{"version":"7.15"},"options":{"version":"7.15"},"path":{"version":"7.15"},"rdf":{"version":"7.15"},"search":{"version":"7.15"},"shortcut":{"version":"7.15"},"system":{"version":"7.15"},"taxonomy":{"version":"7.15"},"text":{"version":"7.15"},"toolbar":{"version":"7.15"},"update":{"version":"7.15"},"user":{"version":"7.15"}},"contrib":{"apps":{"version":"7.x-1.0-beta7"},"ctools":{"version":"7.x-1.2"},"panels":{"version":"7.x-3.3"},"views":{"version":"7.x-3.6"}},"custom":"disabled"}}
Reviewed some modules that i would use myself :
Comments
Comment #1
PA robot commentedWe are currently quite busy with all the project applications and we prefer projects with a review bonus. Please help reviewing and we will take a look at your project right away :-)
Also, you should get your friends, colleagues or other community members involved to review this application. Let them go through the review checklist and post a comment that sets this issue to "needs work" (they found some problems with the project) or "reviewed & tested by the community" (they found no major flaws).
I'm a robot and this is an automated message from Project Applications Scraper.
Comment #1.0
Sam Hermans commentedUpdated the branch
Comment #2
vlad.pavlovic commentedYour project page is not very detailed, please have a look at the tips for a great project page, you may also use HTML-tags for better structure.
The automated review has passed on all code files, the README.txt file, however, contains single lines that are too long (limit is 80 characters per line).
Instructions in README instruct to go to /admin/config/system, yet your hook_menu implementation calls for admin/config/system/system_status.
When I pull up the list (system/status), I am not getting anything for contrib modules, only core. From what I see, the problem lies in the way you determine whether a module is 'core', 'contrib' or 'custom'. You are assuming the paths are */modules/custom/ and */modules/contrib/ instead of sites/*/modules and/or sites/*/modules/custom. It might also be a good idea to allow the users to specify their custom module directory (default to 'custom').
Another way to consider checking would be to look at:
$module_info->info['package']or$module_info->info['project']which would result in 'Core' and 'drupal' respectively.Hope that helps a bit at least.
Comment #3
trof commentedSorry, but vlad.pavlovic forgot to change the status.
Comment #4
Sam Hermans commentedI did the following things:
I really liked your input and have mentioned you in my commit messages ;)
I re-checked everything using the automated review, and no errors/warnings, but i am really struggling with this, i'm using Eclipse PDT and i tried settings from http://drupal.org/node/75242, but no success..
Comment #4.0
Sam Hermans commentedUpdated description
Comment #4.1
Sam Hermans commenteddoc update
Comment #5
Sam Hermans commentedI also added an image to the project page explaining what i'm trying to achieve.
Comment #6
trof commentedHi, Sam Hermans!
I've installed your module on a test site.
In the last paragraph of the instructions it says:
"Once you saved the settings you should be able to: GET /system/status"
though this statement is true only if the drupal installation is placed only in to the root.
Best regards.
Comment #6.0
Sam Hermans commented.
Comment #6.1
Sam Hermans commentedbase path
Comment #7
Sam Hermans commentedHmm, i'll change the documentation to GET $base_url/system/status
Comment #8
Sam Hermans commentedFixed in README.txt
Comment #9
Sam Hermans commentedReviewed some modules that i would use myself :
Comment #10
Sam Hermans commentedAdded commit 2170827 so when processing you see the difference between no modules or a disabled scan.
Comment #10.0
Sam Hermans commentedbase_url
Comment #11
luco commentedhi @Sam Hermans,
I ticked "Enable custom modules" but there wasn't a text box for their regex until I hit save. you could mention this behaviour under the box with a
'#description'property. another option is to make that text box appear - without the user having to save - simply using a'#states'property:also regex isn't very n00b-friendly; maybe you could use the more generic
{^sites\/([A-z,\.,\-]+)\/modules\/*}instead.and I can confirm the module works on a localhost :) good luck!
cheers,
Luciano
Comment #12
Sam Hermans commentedLuco,
Thank you so much for your input .. #states was exactly what i was looking for, i changed it in commit 3a61549.
I also re-did the form to make it way more n00b friendly by using a radios list :
Where are your contrib modules stored ?
I changed the default options so that no configuration is needed once installed.
I added a .install file, because a clean Drupal is a happy Drupal.
Verified that there are no formatting issues
Comment #12.0
Sam Hermans commentedadded reviews
Comment #12.1
Sam Hermans commentedchanged description
Comment #13
muhleder commentedHi Sam,
overall it looks pretty good, it works as described and I can see how it could be useful.
I've got a few suggestions, some of which are just recommendations and you can decide if you want to implement or not, and a few which I think are required. I'll differentiate them by using 'could do' and 'need to'
1. .gitignore
Need to remove this .gitignore file. You should ignore these files locally in ~/.gitignore
2. Use of the /system/status path
I think this could probably go under the /admin/reports/status route, possibly /admin/reports/status/system_status
It would be nice if this was also a clickable link on the /admin/reports/status screen, eg like the phpinfo() function.
3. You could consider moving the menu callbacks into separate include files
This makes a Drupal site more performant because it does not need to load so much code for every page, and also helps other developers looking at your code because related functions are stored in individual files.
4. Variable names used (eg in system_status_form() and system_status.install
Variables need to be prefixed with the module name to help avoid potential namespace issues.
eg system_status_public_allow_public instead of form_public_allow_public
5. Minor performance issue in system_status_access_callback()
You might see a slight performance increase by setting a variable to ip_address() rather than make repeated calls to that function.
6. Hardcoded IP check - if (system_status_match_cidr(ip_address(), "91.212.186.0/24")) {
Need to do a lookup of the domain name here, IP could conceivably change, also easier for other developers to check the code is correct. I get very concerned when I see a hardcoded IP in module code as it's one of the signature's of a hacked site.
7. Regex use
The path matching could be more usable if you used drupal_match_path() rather than a regex.
eg instead of
which works with patterns like
drupal_match_path($filename, 'sites/all/modules/*');The patterns variable can be multi-line (so input via a textarea) if several different path types want to be matched, as used on eg block config screens.
8. JSON output
Need to set the correct content type header for the returned json. You can use
drupal_json_output(array("system_status" => $res))instead ofecho drupal_json_encode(array("system_status" => $res));or you could set the headers manually if you prefer.http://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_j...
Comment #14
muhleder commentedComment #15
Sam Hermans commented@Muhleder
Thank you so much for the detailed information you have given me, i made the following changes:
1. i never knew one could use ~/.gitignore_global .. thanks for that.
2. i moved the output to the reports page
3. i moved logic to a seperate file
4. changed all of them
5. assigned ip_address to a variable
6.Let me think about this, i cant use a hostname since a range should be used. Maybe something with a checksum here.7.None of the solutions is ideal, future will have to tell where users place their modules, it would be even better if core itself had a way of telling what is contrib and what not.8. Thanks for that .. i knew there had to be a better way then using
echomyselfThanks again for the time and effort you have put in your review....
Automated test results here
Comment #15.0
Sam Hermans commentedAdded example output
Comment #16
muhleder commentedThat all looks pretty good so far.
3
For 3 you could also move system_status_access_callback() and system_status_match_cidr() into system_status_status_page.inc if you wanted.
You could also put the admin functions into a system_status_admin.inc if you like.
Optional if you want to do this, but I think it would be nice.
6
For 6. could you make a request to your server to get the range?
You could just use a plain text file with the data in, shouldn't be any need to write an api or anything.
I think fixing 6 is necessary, but I'm willing to be overruled by someone else if they don't think it's a concern.
7
I think for 7. you will eventually need to add checkboxes to allow users to select which are custom modules. Sometimes we put them in /sites/all/modules/custom but another pattern that I see more often is to name each module with a prefix for the client so for the BBC you might create a set of modules named bbc_some_module_name. I don't think 7 should be a blocker for this to be a full project though, more of a feature request really.
Comment #17
Sam Hermans commentedHi again !
3) About moving the access callback. I have been digging around and the suggested and documented way states that 'Access callbacks are called before page callback files are loaded.' so not sure what to do here :/
3) I moved the admin form to system_status_admin.inc, this really cleans up the module and it looks better now.
6) Your solution looks creative but i dislike it for two reasons: 1, not all webservers have the capability to fetch external resources since a great part of them are firewalled. 2 using hostnames requires the drupal to resolve to ip's for itself, this can be an issue as well and DNS is as easly spoofed as an ip address.
If you insist on NOT using an ip range, i removed the cidr matching code and entered a 'static' hostname 'status.drupalstatus.org' that will be resolved on every access call (it resolves to 127.0.0.1 for now, so the functionality can be tested but watch out for IPv6 when testing.
UPDATE: This actually sucks, ip_address() prefers IPv6 over IPv4, but gethostbyname prefers IPv4 over IPv6 .. the *dirty* solution would be to
if(ip_address() == "::1") { $ip_address == "127.0.0.1";}but i *wont* do that !.UPDATE 2 It seems that the correct way of resolving hostnames to ip addresses is now 'getnameinfo' and gethostbyname is deprecated, but this function is not yet implemented in PHP, i will do my best to get this done, but this is out of scope for this module.
UPDATE 3 I opened a discussion on this topic and i have a patch for PHP ready.
I will add something to the FAQ section later where they can put the hostname and IP in their /etc/hosts file so that everything will work in case that the webserver doesn't have access to nslookups.
7) Noted, i can't wait to see the initial results, and further matching strategy will depend on this outcome.
Looking forward to your reply ! ... And automated test results here.
Comment #18
garphyInstalled and enabled with no effort.
I was a little bit surprised one could not enter a subnet for IP filtering. I'm not sure if it's related to the previous reviews you received.
Another point : the name of a couple of file seems not correct, if i'm not mistaken.
I would rename system_status_admin.inc to system_status.admin.inc and system_status_status_page.inc to system_status_status.page.inc to better follow the module_load_include() API.
Last one : the callback URL of your JSON output is in the admin/* area whereas it's not really an administrative UI because it's not even a regular page. Maybe system-status/report would be more appropriate. In the same topic, I'm a bit uncomfortable with the fact that your entry adds a regular menu item in the Admin section (in admin/reports) which lead to a machine-only non-HTML output. I suggest you declare your item as a MENU_CALLBACK.
I let more experienced reviewers decide it this leads to a new 'need works'.
Nice job, by the way.
Comment #19
Sam Hermans commentedGarphy,
First of all i would like to thank you for the time you took to install this module and write your review.
About your remarks :
- subnet functionality was there, but removed in commmit f9aec75 (1) due to comments, 2) due to the fact that ip_addr can return ipv6 addresses and the subnet matcher i wrote is v4 only))
- filenames are changed in commit 2c0885e, thank you for your tip.
- Location of the JSON output.. i was thinking that if you get the page as a normal 'user' you would see a report in some kind of table format, and when it's fetched by a 'machine' the output is in JSON... But all of this is adding unnecessary code since there are allready pages with overviews of active modules.
I'm leaving it as-is for now.
Automated test results here
Comment #20
muhleder commentedHi again Sam,
that all looks great to me, thanks for making the changes. If you feel you need to put the hard coded IP back in it would be nice to add a comment and a longer note in the README explaining. I'm thinking to make it easy for users you could add a help message asking users to input the IP range manually if gethostbyname doesn't return a result. Might be good to add this value as a define so that it doesn't get changed in the code and not the help message.
Again, this is more of a feature request than a requirement for full project, so I'm going to mark this as RTBC.
Changing priority to normal as well, not sure why it was set to minor?
Thanks,
Mark
Comment #21
Sam Hermans commentedMuhleder,
Thanks for the RTBC, I'll leave the 'status.drupalstatus.org' for now, it has a nice touch to it and i can allways change it later.
I created the issue on minor priority because it's my first project and i didn't want to take precious time away from the other modules ..
Thanks again for all your input and wish me luck on the approval process ;)
Sam
Comment #22
klausiReview of the 7.x-1.x branch:
This automated report was generated with PAReview.sh, your friendly project application review script. You can also use the online version to check your project. You have to get a review bonus to get a review from me.
So the permission problem is a security blocker, but otherwise this looks almost RTBC to me. Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.
Comment #23
Sam Hermans commentedChanged the security !
Comment #24
klausiPlease don't remove the security tag, we keep that for statistics and to show examples of security problems.
Thanks for your contribution, Sam Hermans!
I updated your account to let you promote this to a full project and also create new projects as either a sandbox or a "full" project.
Here are some recommended readings to help with excellent maintainership:
You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and get involved!
Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.
Thanks to the dedicated reviewer(s) as well.
Comment #25
Sam Hermans commentedFor those interested, i rolled release 7.x.2.x right now where i addressed some of the security issues..
There are 3 levels of security that can be enabled:
1. IP based filter
An IP based filter can be used. When enabling this option only the specified IP adresses can query your server. Multiple IPv4 and IPv6 addresses can be added.
2. Token based url
Instead of having to query your server at http://www.my-site.com/admin/reports/system_status, another parameter is added to the url. This parameter is an unique token generated during the install of the module. The token can be found in the prefrences page and the URL to access your output would be http://www.my-site.com/admin/reports/system_status/YOUR_UNIQUE_TOKEN
3. Encrypted output
With this option active, all output is hashed into a encrypted string. This means that if someone would be intercepting or sniffing your network traffic, all information would still be secure. For the encryption an additional unique, private token is generated during the install of the module.
My recommendations are that for public servers you should enable both IP based filter and the Token based url.
Comment #26.0
(not verified) commentedUpdated url