From d9fee161982be683202721c144c6b64a6d91d290 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 3 Jan 2018 14:13:47 -0500 Subject: [PATCH] Ticket 49512 - Add initial Cockpit UI Plugin Description: Get the inital framwork intothe repo so everyone can work on it https://pagure.io/389-ds-base/issue/49512 Reviewed by: ? --- Makefile.am | 56 +- configure.ac | 18 +- ldap/admin/src/scripts/setup-ds-cockpit | 111 ++++ man/man1/setup-ds-cockpit.1 | 67 ++ src/cockpit/389-console/README.md | 201 ++++++ src/cockpit/389-console/backend.html | 282 ++++++++ src/cockpit/389-console/css/ds.css | 731 +++++++++++++++++++++ src/cockpit/389-console/css/tabs.css | 62 ++ src/cockpit/389-console/index.html | 112 ++++ src/cockpit/389-console/js/backend.js | 214 ++++++ src/cockpit/389-console/js/ds.js | 68 ++ src/cockpit/389-console/js/monitor.js | 43 ++ src/cockpit/389-console/js/plugins.js | 9 + src/cockpit/389-console/js/replication.js | 214 ++++++ src/cockpit/389-console/js/schema.js | 90 +++ src/cockpit/389-console/js/security.js | 61 ++ src/cockpit/389-console/js/servers.js | 211 ++++++ src/cockpit/389-console/js/tabbed.js | 21 + src/cockpit/389-console/manifest.json | 13 + src/cockpit/389-console/monitor.html | 29 + src/cockpit/389-console/plugins.html | 26 + src/cockpit/389-console/replication.html | 437 ++++++++++++ src/cockpit/389-console/schema.html | 132 ++++ src/cockpit/389-console/security.html | 165 +++++ src/cockpit/389-console/servers.html | 715 ++++++++++++++++++++ src/cockpit/389-console/static/32px.png | Bin 0 -> 3121 bytes src/cockpit/389-console/static/40px.png | Bin 0 -> 1880 bytes .../static/images/ui-icons_444444_256x240.png | Bin 0 -> 6992 bytes .../static/images/ui-icons_555555_256x240.png | Bin 0 -> 6988 bytes .../static/images/ui-icons_777620_256x240.png | Bin 0 -> 4549 bytes .../static/images/ui-icons_777777_256x240.png | Bin 0 -> 6999 bytes .../static/images/ui-icons_cc0000_256x240.png | Bin 0 -> 4549 bytes .../static/images/ui-icons_ffffff_256x240.png | Bin 0 -> 6299 bytes .../389-console/static/jquery.dataTables.min.css | 1 + .../389-console/static/jquery.dataTables.min.js | 164 +++++ .../static/jquery.dataTables.select.min.js | 28 + .../389-console/static/jquery.timepicker.min.css | 1 + .../389-console/static/jquery.timepicker.min.js | 7 + src/cockpit/389-console/static/jstree.min.js | 6 + src/cockpit/389-console/static/page.min.css | 1 + src/cockpit/389-console/static/style.min.css | 2 + src/cockpit/389-console/static/throbber.gif | Bin 0 -> 1720 bytes 42 files changed, 4296 insertions(+), 2 deletions(-) create mode 100755 ldap/admin/src/scripts/setup-ds-cockpit create mode 100644 man/man1/setup-ds-cockpit.1 create mode 100644 src/cockpit/389-console/README.md create mode 100644 src/cockpit/389-console/backend.html create mode 100644 src/cockpit/389-console/css/ds.css create mode 100644 src/cockpit/389-console/css/tabs.css create mode 100644 src/cockpit/389-console/index.html create mode 100644 src/cockpit/389-console/js/backend.js create mode 100644 src/cockpit/389-console/js/ds.js create mode 100644 src/cockpit/389-console/js/monitor.js create mode 100644 src/cockpit/389-console/js/plugins.js create mode 100644 src/cockpit/389-console/js/replication.js create mode 100644 src/cockpit/389-console/js/schema.js create mode 100644 src/cockpit/389-console/js/security.js create mode 100644 src/cockpit/389-console/js/servers.js create mode 100644 src/cockpit/389-console/js/tabbed.js create mode 100644 src/cockpit/389-console/manifest.json create mode 100644 src/cockpit/389-console/monitor.html create mode 100644 src/cockpit/389-console/plugins.html create mode 100644 src/cockpit/389-console/replication.html create mode 100644 src/cockpit/389-console/schema.html create mode 100644 src/cockpit/389-console/security.html create mode 100644 src/cockpit/389-console/servers.html create mode 100644 src/cockpit/389-console/static/32px.png create mode 100644 src/cockpit/389-console/static/40px.png create mode 100644 src/cockpit/389-console/static/images/ui-icons_444444_256x240.png create mode 100644 src/cockpit/389-console/static/images/ui-icons_555555_256x240.png create mode 100644 src/cockpit/389-console/static/images/ui-icons_777620_256x240.png create mode 100644 src/cockpit/389-console/static/images/ui-icons_777777_256x240.png create mode 100644 src/cockpit/389-console/static/images/ui-icons_cc0000_256x240.png create mode 100644 src/cockpit/389-console/static/images/ui-icons_ffffff_256x240.png create mode 100644 src/cockpit/389-console/static/jquery.dataTables.min.css create mode 100644 src/cockpit/389-console/static/jquery.dataTables.min.js create mode 100644 src/cockpit/389-console/static/jquery.dataTables.select.min.js create mode 100644 src/cockpit/389-console/static/jquery.timepicker.min.css create mode 100644 src/cockpit/389-console/static/jquery.timepicker.min.js create mode 100644 src/cockpit/389-console/static/jstree.min.js create mode 100644 src/cockpit/389-console/static/page.min.css create mode 100644 src/cockpit/389-console/static/style.min.css create mode 100644 src/cockpit/389-console/static/throbber.gif diff --git a/Makefile.am b/Makefile.am index 3ac5584c8..e4745b817 100644 --- a/Makefile.am +++ b/Makefile.am @@ -287,7 +287,13 @@ updatedir = $(datadir)@updatedir@ pkgconfigdir = $(libdir)/pkgconfig serverincdir = $(includedir)/@serverincdir@ gdbautoloaddir = $(prefixdir)/share/gdb/auto-load$(sbindir) -# THis has to be hardcoded to /lib - $libdir changes between lib/lib64, but +cockpitdir = $(datadir)@cockpitdir@ +cockpitstaticdir = $(datadir)@cockpitstaticdir@ +cockpitimagesdir = $(datadir)@cockpitimagesdir@ +cockpitjsdir = $(datadir)@cockpitjsdir@/ +cockpitcssdir = $(datadir)@cockpitcssdir@ + +# This has to be hardcoded to /lib - $libdir changes between lib/lib64, but # sysctl.d is always in /lib. sysctldir = @prefixdir@/lib/sysctl.d @@ -591,6 +597,7 @@ dist_noinst_DATA = \ $(srcdir)/ldap/admin/src/scripts/*.sh \ $(srcdir)/ldap/admin/src/scripts/ds-replcheck \ $(srcdir)/ldap/admin/src/scripts/migrate-ds.res \ + $(srcdir)/ldap/admin/src/scripts/setup-ds-cockpit \ $(srcdir)/ldap/ldif/*.in \ $(srcdir)/ldap/ldif/*.ldif \ $(srcdir)/ldap/schema/*.ldif \ @@ -610,6 +617,7 @@ dist_noinst_DATA = \ $(srcdir)/wrappers/*.in \ $(srcdir)/wrappers/systemd.template.sysconfig \ $(srcdir)/dirsrvtests \ + $(srcdir)/src/cockpit/* \ $(srcdir)/src/lib389/setup.py \ $(srcdir)/src/lib389 @@ -770,6 +778,7 @@ endif # For scripts that are "as is". dist_bin_SCRIPTS = ldap/admin/src/scripts/ds-replcheck \ + ldap/admin/src/scripts/setup-ds-cockpit \ ldap/admin/src/scripts/ds-logpipe.py dist_bin_SCRIPTS += ldap/admin/src/logconv.pl @@ -870,6 +879,49 @@ inf_DATA = ldap/admin/src/slapd.inf \ mib_DATA = ldap/servers/snmp/redhat-directory.mib +cockpit_DATA = src/cockpit/389-console/manifest.json \ + src/cockpit/389-console/backend.html \ + src/cockpit/389-console/index.html \ + src/cockpit/389-console/monitor.html \ + src/cockpit/389-console/plugins.html \ + src/cockpit/389-console/README.md \ + src/cockpit/389-console/replication.html \ + src/cockpit/389-console/schema.html \ + src/cockpit/389-console/security.html \ + src/cockpit/389-console/servers.html + +cockpitstatic_DATA = src/cockpit/389-console/static/32px.png \ + src/cockpit/389-console/static/40px.png \ + src/cockpit/389-console/static/jquery.dataTables.min.css \ + src/cockpit/389-console/static/jquery.dataTables.min.js \ + src/cockpit/389-console/static/jquery.dataTables.select.min.js \ + src/cockpit/389-console/static/jquery.timepicker.min.css \ + src/cockpit/389-console/static/jquery.timepicker.min.js \ + src/cockpit/389-console/static/jstree.min.js \ + src/cockpit/389-console/static/page.min.css \ + src/cockpit/389-console/static/style.min.css \ + src/cockpit/389-console/static/throbber.gif + +cockpitimages_DATA = src/cockpit/389-console/static/images/ui-icons_444444_256x240.png \ + src/cockpit/389-console/static/images/ui-icons_777620_256x240.png \ + src/cockpit/389-console/static/images/ui-icons_cc0000_256x240.png \ + src/cockpit/389-console/static/images/ui-icons_555555_256x240.png \ + src/cockpit/389-console/static/images/ui-icons_777777_256x240.png \ + src/cockpit/389-console/static/images/ui-icons_ffffff_256x240.png + +cockpitjs_DATA = src/cockpit/389-console/js/backend.js \ + src/cockpit/389-console/js/ds.js \ + src/cockpit/389-console/js/monitor.js \ + src/cockpit/389-console/js/plugins.js \ + src/cockpit/389-console/js/replication.js \ + src/cockpit/389-console/js/schema.js \ + src/cockpit/389-console/js/security.js \ + src/cockpit/389-console/js/servers.js \ + src/cockpit/389-console/js/tabbed.js + +cockpitcss_DATA = src/cockpit/389-console/css/ds.css \ + src/cockpit/389-console/css/tabs.css + pkgconfig_DATA = src/pkgconfig/dirsrv.pc \ src/pkgconfig/libsds.pc \ src/pkgconfig/nunc-stans.pc @@ -892,6 +944,7 @@ dist_man_MANS = man/man1/dbscan.1 \ man/man1/dbgen.pl.1 \ man/man1/ds-logpipe.py.1 \ man/man1/ds-replcheck.1 \ + man/man1/setup-ds-cockpit.1 \ man/man1/infadd.1 \ man/man1/ldap-agent.1 \ man/man1/ldclt.1 \ @@ -2159,6 +2212,7 @@ fixupcmd = sed \ -e 's,@localrundir\@,$(localrundir),g' \ -e 's,@infdir\@,$(infdir),g' \ -e 's,@mibdir\@,$(mibdir),g' \ + -e 's,@cockpitdir\@,$(cockpitdir),g' \ -e 's,@templatedir\@,$(sampledatadir),g' \ -e 's,@systemschemadir\@,$(systemschemadir),g' \ -e 's,@package_name\@,$(PACKAGE_NAME),g' \ diff --git a/configure.ac b/configure.ac index 3b348cd80..8c289eb23 100644 --- a/configure.ac +++ b/configure.ac @@ -372,6 +372,12 @@ if test "$with_fhs_opt" = "yes"; then perldir=/perl # relative to libdir pythondir=/python + # relative to datadir + cockpitdir=/389-console + cockpitstaticdir=/389-console/static + cockpitimagesdir=/389-console/static/images + cockpitjsdir=/389-console/js + cockpitcssdir=/389-console/css else if test "$with_fhs" = "yes"; then ac_default_prefix=/usr @@ -408,6 +414,12 @@ else perldir=/$PACKAGE_NAME/perl # relative to libdir pythondir=/$PACKAGE_NAME/python + # relative to datadir + cockpitdir=/$PACKAGE_NAME/389-console + cockpitstaticdir=/$PACKAGE_NAME/389-console/static + cockpitimagesdir=/$PACKAGE_NAME/389-console/static/images + cockpitjsdir=/$PACKAGE_NAME/389-console/js + cockpitcssdir=/$PACKAGE_NAME/389-console/css fi # if mandir is the default value, override it @@ -495,7 +507,11 @@ AC_SUBST(infdir) AC_SUBST(mibdir) AC_SUBST(mandir) AC_SUBST(updatedir) - +AC_SUBST(cockpitdir) +AC_SUBST(cockpitstaticdir) +AC_SUBST(cockpitimagesdir) +AC_SUBST(cockpitjsdir) +AC_SUBST(cockpitcssdir) AC_SUBST(defaultuser) AC_SUBST(defaultgroup) diff --git a/ldap/admin/src/scripts/setup-ds-cockpit b/ldap/admin/src/scripts/setup-ds-cockpit new file mode 100755 index 000000000..a72208520 --- /dev/null +++ b/ldap/admin/src/scripts/setup-ds-cockpit @@ -0,0 +1,111 @@ +#!/usr/bin/python3 + +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2018 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- + +import argparse +import logging +import sys +import os +import subprocess +import shutil +import socket + +cockpit_plugin = '/usr/share/dirsrv/389-console' + +if __name__ == '__main__': + """Install the 389 Directory Server Cockpit UI Plugin + """ + + # Check if Cockpit is installed + try: + cmd = ["rpm", "-q", "cockpit"] + subprocess.check_call(cmd, stdout=subprocess.PIPE) + except: + print ("You need to install the 'cockpit' package before installing the UI plugin") + sys.exit(1) + + # Check the server's cockpit plugin exists + if not os.path.isdir(cockpit_plugin): + print ("Can not find cockpit UI plugin under '/usr/share/dirsrv'") + sys.exit(1) + + # Setup CLI args + parser = argparse.ArgumentParser() + parser.add_argument('-v', '--verbose', + help="Display verbose operation tracing", + action='store_true', default=False) + parser.add_argument('-i', '--install', + help="Install the cockpit plugin (must be root)", + action='store_true', dest='install', default=False) + parser.add_argument('-t', '--testing', + help="Install the cockpit plugin under users's home directory for testing (~/.local/share/cockpit)", + action='store_true', dest='testing', default=False) + parser.add_argument('-u', '--update', + help="Update existing plugin", + action='store_true', dest='update', default=False) + options = parser.parse_args() + + # Validate options + if options.install and options.testing: + print("You can not specify both '--install' and '--testing'") + parser.print_help() + sys.exit(1) + + if options.install is False and options.testing is False: + print("You must specify either '--install' or '--testing'") + parser.print_help() + sys.exit(1) + + if options.install and os.geteuid() != 0: + print("You must be 'root' to install cockpit plugin") + sys.exit(1) + + # Prepare installation location + if options.testing: + if options.verbose: + print("Preparing to install testing plugin...") + home_dir = os.path.expanduser('~') + cockpit_dir = home_dir + "/.local/share/cockpit" + if not os.path.exists(cockpit_dir): + if options.verbose: + print("Creating 'cockpit' directory: " + cockpit_dir) + os.makedirs(cockpit_dir) + install_location = cockpit_dir + "/389-console" + elif options.install: + if options.verbose: + print("Preparing to install plugin...") + install_location = "/usr/share/cockpit/389-console" + + # Check install location + if os.path.exists(install_location): + # Already exists + if not options.update: + print("The cockpit plugin is already installed at '{}', use '--update' for update it".format(install_location)) + sys.exit(1) + else: + # Force install, remove old dir so we can copy in the new one + print("Updating existing plugin...") + shutil.rmtree(install_location) + + # Now do the install + try: + print("Installing plugin in {}...".format(install_location)) + shutil.copytree(cockpit_plugin, install_location) + if options.verbose: + print ("Installed:\n--------------------") + for ui_file in os.listdir(install_location): + print(" " + ui_file) + print() + except (IOError, os.error) as e: + print("Failed to install cockpit plugin: " + str(e)) + sys.exit(1) + + # Done! + print("Installation is complete!") + print("Open UI with this URL: http://{}:9090/389-console".format(socket.getfqdn())) diff --git a/man/man1/setup-ds-cockpit.1 b/man/man1/setup-ds-cockpit.1 new file mode 100644 index 000000000..781efc250 --- /dev/null +++ b/man/man1/setup-ds-cockpit.1 @@ -0,0 +1,67 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH DS-REPLCHECK 1 "May 2, 2017" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +setup-ds-cockpit - Performs replication synchronization report between two replicas + +.SH SYNOPSIS +setup-ds-cockpit [-h, --help] [-v, --verbose] [-i, --install] [-t, --testing] [-u, --update] + +.SH DESCRIPTION +setup-ds-cockpit installs the Directory Server management Cockpit UI Plugin +into either the default Cockpit plugin location, or the user's home directory +Cockpit location (typically this is used for testing). + +For more information on Cockpit please see: + + http://cockpit-project.org + + https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/getting_started_with_cockpit/ + + +.SH OPTIONS + +A summary of options is included below: + +.TP +.B \fB\-h, \-\-help\fR +.br +Display usage +.TP +.B \fB\-i, \-\-install\fR +Install the Cockpit plugin into the default location +.TP +.B \fB\-t, \-\-testing\fR +Install the Cockpit plugin into the user's default location (~/.local/share/cockpit) +.TP +.B \fB\-u, \-\-update\fR +Update an existing Cockpit plugin installation +.TP +.B \fB\-v, \-\-verbose\fR +Write verbose output to STDOUT + +.SH EXAMPLE +setup-ds-cockpit --testing --verbose + +setup-ds-cockpit -i -u + +.SH AUTHOR +setup-ds-cockpit was written by the 389 Project. +.SH "REPORTING BUGS" +Report bugs to https://pagure.io/389-ds-base/new_issue +.SH COPYRIGHT +Copyright \(co 2018 Red Hat, Inc. diff --git a/src/cockpit/389-console/README.md b/src/cockpit/389-console/README.md new file mode 100644 index 000000000..9a97605f5 --- /dev/null +++ b/src/cockpit/389-console/README.md @@ -0,0 +1,201 @@ +--- +title: "Cockpit UI Design" +--- + +# Layout +-------------------------- + +The main layout consists of as tabbed panel for the following categories: + +- Server Configuration +- Security +- Database +- Replication +- Schema +- Plugins +- Monitoring + + +
+ + +# Panels +------------------------------- + +This briefly describes what each panel covers + +## Server + +This is the welcome page(panel). You select which local instance you want to configure from auto-filled drop down list. This instance is then carried over to the other panels. These are the configuration areas that are covered under this panel: + +- General Configuration: port, hostname, LDAPI, various config settings under cn=config +- SASL: SSL Settings and Mappings +- Password Policy: all things password related +- Logs: access, error, audit/auditfail settings +- Tasks: backups/restore, Create/delete instances, etc +- Tuning and resource limits: size/time limits, max threads per conn, etc + +## Security + +- Enable Security and configureation settings +- Manage Certificate Database +- Manage ciphers + +## Database + +- Mapping tree and backend are "linked". They are seen as a single object in the UI. If you create a new suffix, it creates the mapping tree entry and the backend entry. Delete removes both as well. + +- Global database settings + - General settings + - Chaining +- Suffix settings + - General settings + - Referrals + - Indexes + - Attr encryption +- Suffix Tree Node - right click: + - Import/Export + - Backup/Restore + - Reindex + - Create database link + - Add sub-suffix + - Delete + + +## Replication + +Setup replication configuration, changelog, and agreements. Keep agmt setup wizard simple. Build in some simple monitoring and agreement status info. Save the real replication monitoring for the monitor tab panel. + +- Build in cleanallruv task (and the abort task), and cleanallruv task monitoring! +- "Reinit all agmts" option?? +- "test replication" operation (already exists in lib389) - monitoring page, or agreement dropdown(+1)? + +## Schema + +Manage Standard and Custom Schema and Matching Rules (also has schema-reload task "button") + +## Plugins + +Manage all plugins For common/known plugins like: RI, MEP, MemberOf, DNA, Automember, provide a nice customized configuration form in UI. Eventually do this for IPA plugins too. For generic/unknown plugins provide basic UI form(enable/disable, and dependencies). + + +- Sort server core plugins (with customized config): RI, mep, memeberOf, etc + + + +## Monitoring + +- Replication Monitoring + - Latency monitoring (already exists in lib389) + - repl-monitor.pl equivalent. There are complaints this is too complicated, so we need to find a simpler way to express the replication state. +- cn=monitor/Perf Counters/snmp (all monitors - organize content into database monitoring and server monitoring) +- Log viewing (live tailing - feature of cockpit) +- Logconv stats (either from perl script or new internal stats)? +- Database State: + - index checking/validation (customer request). Task that performs a search(es) that are expected to be indexed or not indexed. + - dbverify + + + +# Documentation Via Mouse Hover +---------------------------------- + +The idea here is provide some built-in documentation that is accessible on the fly when looking at a particular setting or tree node. Hover the mouse pointer over a config setting and it gives a full description of the setting, value range, and the real attribute name. This is good for novices and experts. + +This is really a simple idea, but it could have a huge impact for admins. We can add "titles" to almost anything in HTML, lets use them for everything that could use an explanation. + + +# Working with Cockpit +----------------------------- + +## Install cockpit on all servers in topology + +Cockpit offers some great built-in functionality for things like authentication and managing many systems from a single location. + +- No HTTP admin server to manage +- This allows our UI to be very simple with little overhead. +- Currently there is no need for things like a o=netscaperoot backend (but in the future if the features continue to grow we might still need this). +- UI would be easy to customize + + +## Cockpit and DS interaction + +The cockpit UI runs shell commands on the actual system using lib389's CLI tools. Authentication must use LDAPI. No LDAPI, no cockpit UI. Using the cockpit API we can run CLI tools and retrieve their output. The output should be in a JSON format for easy parsing in the UI/javascript: + + cockpit.spawn('/usr/bin/dsconf', '-z', '-n') + + +# Setup Installation +----------------------------- + +## Prerequisites + +LDAPI Support (no go for Solaris/HPUX) +cockpit + +## Installation + +- Enable LDAPI in local ds instances +- Drop in 389's cockpit plugin bundle under **/usr/share/cockpit/** --> **/usr/share/cockpit/389-console/** +- Done + +## setup-ds-cockpit + +-Install script, see "man setup-ds-cockpit" + + +# Misc +--------------------- + +No RESET buttons? Not yet at least... + + +LIB389 Requirements: + +- Consistent JSON representation of entries +- Retrieve schema: standard and custom (user-defined) +- Retrieve plugins +- retreive indexes +- Retreive config (cn=config and friends) +- SASL mapping/priority +- Retrieve cleanAllRUV(and abort) tasks +- Get all user/subtree password policies +- Get SSL ciphers + + +# To Do +------------------------------------- + +## wizard forms(modals) + +- Edit plugin (generic) +- Edit plugin (RI plugin) +- Edit plugin (Member Of) +- Edit plugin ... +- Add/edit SASL Mapiing +- Export Certification (file location) +- Add/Edit Index +- Add encrypted attr +- Add/edit schema (attrs & objectclasses) +- Add/edit local password policy +- Create instance +- Add cleanAllRUV (and abort) Task + +## Monitoring page + +- Nothing has been done yet +- Some monitoring features need RFE that have yet to be coded + +## Nice to have/fix + +- Get "Cipher" Datatable to sort on checkbox (other wise we need a "yes/no" 'Enabled' column and a button (in its own column) to toggle it. +- Figure out why the ds-flex page changes width between sever configuraton buttons (Server Configuration vs SASL) +- Remove panel tab highlighting after selection + + + + + + + + diff --git a/src/cockpit/389-console/backend.html b/src/cockpit/389-console/backend.html new file mode 100644 index 000000000..3a94ca8ad --- /dev/null +++ b/src/cockpit/389-console/backend.html @@ -0,0 +1,282 @@ +
+
    +
  • Database +
      +
    • dc=example,dc=com +
        +
      • ou=people,dc=example,dc=com
      • +
      +
    • +
    • o=ipaca.com +
    • +
    +
  • +
+
+ +
+ +
+ + +