How to add RABL template for new interface type?

Hello Foreman devs,

I’m working on a new plugin that adds a new interface type to Foreman. So far things turn out OK. That new interface type can be selected and created through the host edit GUI. But after saving the new interface (successfully), the host overview fails to render due to the missing RABL template (in this case, api/v2/interfaces/types/dummy.json).

The stack trace points to the app/views/api/v2/interfaces/main.json.rabl template, which wants to render a specific RABL partial matching the interface type. I need to provide such a template accordingly, but how?

  • the plugin cannot match the (relative) path for this partial (especially since it is namespaced)
  • nor can I inject my own template among those of Foreman core
  • RABL templates can neither be substituted, monkey-patched or defaced (only extended), right?

I appreciate any hints or advice for this challenge.

Thank you for your time,
Xavier.

I think I found my answer in the Katello Foreman plugin: Register an additional path to Rabl to look for templates. I’ll report back once I’ve gathered some experience with that…

Right on the money! With this snippet added to engine.rb, Foreman can display the new interface type on the overview:

initializer "foreman_dummy_interfaces.add_rabl_view_path" do
  Rabl.configure do |config|
    config.view_paths << ForemanDummyInterfaces::Engine.root.join('app', 'views')
  end
end

Of course, the actual template file needs to be added, too.

# app/views/api/v2/interfaces/types/dummy.json.rabl
attributes :virtual, :attached_to

grafik

Hope this will help plugin developers in the future. Possibly some Foreman dev will decide to add a hint about “add_rabl_view_path” to the How to Create a Plugin developer docs, too.

Kind regards,
Xavier.

One more thing, to me it looks like every plugin needs to register its own Rabl templates directory with Foreman’s Rabl renderer! Otherwise, not even absolute paths to plugin partials will be found with extend_rabl_template:

# engine.rb, register_plugin initializer
extend_rabl_template 'api/v2/interfaces/base', "#{ForemanCnames::Engine.root}/app/views/foreman_cnames/api/v2/host_aliases_attributes"
irb(main):001:0> Rabl.render(interface, 'api/v2/interfaces/show', :view_path => ['/usr/share/gems/gems/foreman_remote_
execution-8.3.3/app/views'])
Traceback (most recent call last):
        5: from lib/tasks/console.rake:5:in `block in <top (required)>'
        4: from (irb):1
        3: from config/initializers/rabl_init.rb:49:in `render'
        2: from config/initializers/rabl_init.rb:49:in `render'
        1: from config/initializers/rabl_init.rb:49:in `render'
RuntimeError (Cannot find rabl template '/usr/local/share/gems/gems/foreman_cnames-0.2.4/app/views/foreman_cnames/api/v2/host_aliases_attributes' within registered ([
  "/usr/share/gems/gems/foreman_remote_execution-8.3.3/app/views",
  "/usr/share/foreman/app/views",
  "/usr/share/gems/gems/foreman_azure_rm-2.2.7/app/views",
  "/usr/share/gems/gems/foreman_discovery-22.0.2/app/views",
  "/usr/share/gems/gems/foreman_templates-9.3.0/app/views",
  "/usr/share/gems/gems/katello-4.7.0.36/app/views",
  "/usr/local/share/gems/gems/foreman_dummy_interfaces-0.0.1/app/views"
]) view paths!)