How-To Integrate a 3rd Party Tool - Part 4: Admin UI Extension

Overview

If you are not familiar with UI extensions (XUI), please review the product documentation on this topic. This article will teach you how to create an Admin XUI as a means to configure your new integration. We will focus on viewing/editing the associated Connection Info. Most CloudBolt admins will appreciate going to a single location for all of the related features/settings. As we build this Admin XUI, you will see how this integrations starts to feel as thought it was provided as an out of the box (OOTB) feature.

The admin extension is a great place for global settings for the new integration. Additional settings will be covered in a future article of this series.

This will not cover linking to the resource handler for using existing credentials. However, this can be achieved in the Admin XUI.

Considerations

  • Requires an integration that uses a Connection Info.

Create New Admin Extension Procedure

Each extension package can contain multiple types and multiple quantities of each type. This example will start with only an Admin Page. It is recommended to group all of your extension types for an integration into a single extension package.

  1. Goto Admin > Manage UI Extensions

  2. Click “Create a package”

  3. Enter the form details

  4. Expand the extension to see the file path and edit the files

Admin Extension “views.py”

from django.shortcuts import render
from tabs.views import TabGroup
from extensions.views import admin_extension
from utilities.models import ConnectionInfo

template_dir = 'example_extension/templates'

conn, created = ConnectionInfo.objects.get_or_create(
    name='Example Integration',
    defaults={
        "ip": "0.0.0.0",
        "protocol": "https",
        "port": 443,
        "username": "example_svc_acct",
        "password": ""
    }
)

base_url = f'{conn.protocol}://{conn.ip}:{conn.port}/api/v1'


@admin_extension(title="Example Admin Extension", description="Example Admin Extension")
def admin_page(request):
    admin_context = {

        'tabs': TabGroup(
            template_dir=template_dir,
            context={
                "endpoint": conn,
            },
            request=request,
            tabs=[
                # First tab uses template 'groups/tabs/tab-main.html'
                # (_("Configuration"), 'configuration', {}),

                # Tab 2 is conditionally-shown in this slot and
                # uses template 'groups/tabs/tab-related-items.html'
                (("Overview"), 'overview', {}),
                (("Misc"), 'misc', {}),
            ],
        )
    }
    return render(request, f'{template_dir}/admin_page.html', admin_context)

Admin Extension “template/admin_page.html”

{% extends "base.html" %}

{% load helper_tags %}
{% load tab_tags %}
{% block topnav %}Example Integration Admin Page {% endblock %}

{% block title %}  Example Integrtion {% endblock %}

{% block content %}
    <span class="uplink"><a href="{% url 'admin_home' %}">Admin</a></span>
    <h1>Example Integration Admin Page</h1>
    {% draw_tabs tabs %}
{% endblock content %}

Admin Extension “template/tab-overview.html”

{% load i18n %}
{% load tag_tags %}
{% load helper_tags %}

<div class="btn-toolbar">
    <a class="btn btn-default open-dialog"
        href="{% url 'edit_connectioninfo' endpoint.id %}"
        id="edit-button">
        <span class="icon-edit"></span>
        {% trans 'Edit' %}
    </a>
    <a class="btn btn-default open-dialog"
        href="{% url 'delete_connectioninfo' endpoint.id %}">
        <span class="icon-delete"></span>
        {% trans 'Remove' %}&hellip;
    </a>
</div>

{% if endpoint %}
    <div class="panel panel-default">
        <div class="panel-body">
            <div class="row">
                <div class="col-sm-6">
                     <dl class="vertical">
                         {% trans "Name" as name %}
                         <dt>{% text_tooltip name connectioninfo.NAME_HELP_TEXT %}:</dt>
                         <dd>
                             {{ endpoint.name }}
                         </dd>

                         <dt>{% trans 'IP/Hostname:' %}</dt>
                         <dd>
                             {{ endpoint.ip }}
                         </dd>

                         <dt>{% trans 'Port:' %}</dt>
                         <dd>
                             {{ endpoint.port }}
                         </dd>

                         <dt>{% trans 'Protocol:' %}</dt>
                         <dd>
                             {{ endpoint.protocol }}
                     </dl>
                </div>
                <div class="col-sm-6">
                     <dl class="vertical">
                         <dt>URL:</dt>
                         <dd>{{ endpoint.protocol }}://{{ endpoint.ip }}:{{ endpoint.port }}</dd>
                         <dt>{% trans 'Username:' %}</dt>
                         <dd>
                             {{ endpoint.username }}
                         </dd>
....
                         <dt>{% trans 'Password:' %}</dt>
                            <dd>
                             {% if endpoint.password %}
                                    ********
                             {% endif %}
                         </dd>
                         <dt>{% trans 'Labels:' %}</dt>
                         <dd>
                             {% for label in endpoint.labels.all %}
                                 {{ label|tag }}
                             {% endfor %}
                             <a href="{% url 'connectioninfo_edit_labels' endpoint.id %}"
                                 class="open-dialog"><i class="icon-edit"></i>
                             </a>
                         </dd>
                     </dl>
                </div>
            </div>
        </div>
    </div>
{% else %}
    <p><i>No Connection Endpoint configured.</i></p>
{% endif %}

Final Result

Additional information

Include links to outside source articles or reference material if applicable

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.