Extending checkmk using an own python Page implementation

Hello Community

This might be a question for the more experienced users and “modders” of checkmk, but anyone else is welcome to share their knowledge.

I have developed some kind of extension to our checkmk site to (beside some ther stuff) give our users an easy and comfortable opportunity to create a kind of statusbased newsletter and subscribe to them.

Currently this add-on is written in PHP and is more an “add-beside” like NagVis is. That is in some aspects very annoying. So i decided to give it a rebuild using python and the cmk-libraries to really integrate into checkmk.

Browsing through the sources and taking a look in different classes and aspects it seems that it might be the best way to implement the Page class and link it from within the site.

So i wrote a simple “hello world”-page for proof-of-concept

Show file: page_hello_world.py
#!/usr/bin/env python3

from cmk.gui.pages import Page, PageRegistry
from cmk.gui.htmllib.html import html

class PageHelloWorld(Page):
    def _title(self) -> str:
        return "Hello World Test"

    def __init__(self) -> None:
         super().__init__()

    def page(self) -> None:
        html.open_div(id_="test-page")
        html.h1("Hello World")
        html.span("Nice to see you.")
        html.close_div()

def register(page_registry: PageRegistry) -> None:
    page_registry.register_page("hello_world")(PageHelloWorld)

placed it at

~/local/lib/python3/cmk/gui/page_hello_world.py

and tried to acces it via

https://<server>/<site>/check_mk/index.py?start_url=%2F<site>%2Fcheck_mk%2Fhello_world.py

but had no success.

I moved the class around through different folders on the server, changed ownership from site-user to root, played around with the file permissions - but i can’t get any further than getting a red box telling me “This page was not found. Sorry.”

It seems my page or the python-file must be registered somewhere somehow - but i don’t know how. I really don’t want to edit the files outside the local folder to be secure to upcoming updates.

Here i am stuck. :woozy_face:

Maybe there is at least one member of this community having a good clue or even the knowledge of how to achieve the goal. In the best case scenario, someone from the development team will read along.

I would be happy about any hint, no matter how small.

Thanks in advance and best wishes
Klaus

PS: May be the registration function of my file has to be called from somewhere or it has to be a PageRegistry.register(...) like call… :thinking:

Hi

I have last done this for Checkmk 2.1, so this might no longer be fully accurate.
In 2.1 I had to:

  • place my custom page in web/plugins/wato/pages (this might be optional, not sure)
  • register the page, as you mentioned, using:
from cmk.gui.pages import page_registry, Page

@page_registry.register_page("dummy")
class DummyPage(Page):
    def __init__(self):
        super(DummyPage, self).__init__()
        self._no_html_output = True

    def page(self):
        return None

I think this should then accessible using …check_mk/dummy.py

So, looking at your code:

  • you could try doing the register as above
  • if this does not suffice, try moving the page to the aforementioned path
    Also, make sure to at least restart Apache after changing things.

HTH :slight_smile:

2 Likes

Hi ttrafelet

Thanks a lot for your help!

I did as you described:

  • Changed the registration into an @-clause,
  • moved my class file to ~/local/share/check_mk/web/plugins/wato and
  • restarted apache

and everything works as expected. :heart_eyes:

I tried so many folders but the wato folder was the last i expected. Indeed there is a pages folder besides the wato - but this one will not work.

Perhaps a developer of checkmk can reconsider this aspect, why there is a pages folder, but pages have to be placed in the wato folder.
But after i mark your answere as solution i expect no one of them ever looking into this thread again. :slightly_frowning_face:

Nevertheless… Thank you so much for helping me out in this. :kissing_heart:

Now i can start to transform my project from php to python. :sunglasses: :sunny:

Edit: I should have mentioned, that i am using CheckMK 2.3.0p11 - so the solution is even working on current releases.

3 Likes

Good that it works.

Maybe it incidentally works, while the developers didn’t have pages or wato intended for this use case. (-:

The wato folder seems to be virtually connected to the tree of folders where the hosts reside in. Perhaps when you use a file that has the same name as a host folder, conflicts might occur.

I did little customization in the nagvis part and those files ended up in ~/local/share/nagvis/htdocs/ folder. If I would be fumbling around with pages, my first guess is that the files would go to ~/local/share/check_mk/web/htdocs/.

But I’m in no way a developer in some sort, so just assumptions on my part. (-;

1 Like

Hi Yggy

Thanks for your advice! :slight_smile:

I tried to move the file to ./local/share/check_mk/web/htdocs/page_hello_world.py but after restartig apache, the page could not be found anymore. :slightly_frowning_face:
I also tried ./local/share/check_mk/web/htdocs/src/page_hello_world.py but this wont work either.

But any good suggestion which enables me to leave the wato folder will be very appreciated.

Indeed i chose the filename page_whatever.py deliberately so that no conflicts should arise. :wink:

Hi! checkmk 2.1.0p38 here :wave:t2: and maybe this helps:

I put the file here: ~/local/share/check_mk/web/plugins/pages/random_filename.py.
The actual filename doesn’t seem to matter.

This is my file:

#!/usr/bin/env python3
# code: language=python insertSpaces=true tabSize=4

from cmk.gui.pages import page_registry, Page
from cmk.gui.globals import html

############################################################
#
############################################################
@page_registry.register_page("dummy")
class PageHelloWorld(Page):
    def _title(self) -> str:
        return "Hello World Test"

    def __init__(self) -> None:
         super().__init__()

    def page(self) -> None:
        html.open_div(id_="test-page")
        html.h1("Hello World")
        html.span("Nice to see you.")
        html.close_div()

After omd restart apache I can call the new page with this URL:

http://HOST/SITE/check_mk/index.py?start_url=%2Ft33%2Fcheck_mk%2Fdummy.py
                                                                 ^^^^^

The last part is the same name that I used whithin the register call.

Hello Dirk :wave:

I did the registration via @-clause as ttrafelet describes in his solution, what indeed made the page accessible - if it’s in the wato folder. I just called my page hello_world

To test your suggestion i copied your code-snippet into ~/local/share/check_mk/web/plugins/pages/page_hello_world.py but this did not work for me. :slightly_frowning_face:

Then i recognized that - in contrast to my snippet - you importet html from cmk.gui.globals. So i decided to change this back to my import from cmk.gui.htmllib.html - and it worked! :partying_face: :star_struck: :heart_eyes:

So finally here ist the code of my file ~/local/share/check_mk/web/plugins/pages/page_hello_world.py, which is now a mixture of all our suggestions and can be accessed via https://<HOST>/<SITE>/check_mk/index.py?start_url=%2F<SITE>%2Fcheck_mk%2Fhello_world.py

#!/usr/bin/env python3
# code: language=python insertSpaces=true tabSize=4

from cmk.gui.pages import page_registry, Page
from cmk.gui.htmllib.html import html

@page_registry.register_page("hello_world")
class PageHelloWorld(Page):
    def _title(self) -> str:
        return "Hello World Test"

    def __init__(self) -> None:
         super().__init__()

    def page(self) -> None:
        html.open_div(id_="test-page")
        html.h1("Hello World")
        html.span("Nice to see you.")
        html.span("Finally i'm here.")
        html.close_div()

I’m so happy we finally found a solution for this!
Thank you all sooooo much!! :heart: :heart: :heart:

2 Likes

Hello Klaus!
Your import statement didn’t work for me (cmk 2.1). They changed the directory layout between 2.1 and 2.3 and apparently this import is also affected.

However, I’m also happy that we finally made it run. Currently I don’t know what to do with the new knowledge, but it’s good to know that I could extend checkmk this way if I wanted to. Thank you for the inspiration.

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed. Contact an admin if you think this should be re-opened.